123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050(* File: cairo.ml
Copyright (C) 2009
Christophe Troestler <Christophe.Troestler@umons.ac.be>
WWW: http://math.umh.ac.be/an/software/
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3 or
later as published by the Free Software Foundation, with the special
exception on linking described in the file LICENSE.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
LICENSE for more details. *)(* Keep in sync with the C function caml_cairo_raise_Error *)typestatus=(* Programmer error *)|INVALID_RESTORE|INVALID_POP_GROUP|NO_CURRENT_POINT|INVALID_MATRIX|INVALID_STATUS(* Language binding implementation *)|NULL_POINTER|INVALID_STRING|INVALID_PATH_DATA(* Other *)|READ_ERROR|WRITE_ERROR|SURFACE_FINISHED|SURFACE_TYPE_MISMATCH|PATTERN_TYPE_MISMATCH|INVALID_CONTENT|INVALID_FORMAT|INVALID_VISUAL|FILE_NOT_FOUND|INVALID_DASH|INVALID_DSC_COMMENT|INVALID_INDEX|CLIP_NOT_REPRESENTABLE|TEMP_FILE_ERROR|INVALID_STRIDE|FONT_TYPE_MISMATCH|USER_FONT_IMMUTABLE|USER_FONT_ERROR|NEGATIVE_COUNT|INVALID_CLUSTERS|INVALID_SLANT|INVALID_WEIGHT|INVALID_SIZE|USER_FONT_NOT_IMPLEMENTED|DEVICE_TYPE_MISMATCH|DEVICE_ERROR|INVALID_MESH_CONSTRUCTION|DEVICE_FINISHED|JBIG2_GLOBAL_MISSINGexceptionErrorofstatuslet()=Callback.register_exception"Cairo.Error"(ErrorINVALID_RESTORE)leterror_of_status=function|INVALID_RESTORE->"Cairo.Error(INVALID_RESTORE)"|INVALID_POP_GROUP->"Cairo.Error(INVALID_POP_GROUP)"|NO_CURRENT_POINT->"Cairo.Error(NO_CURRENT_POINT)"|INVALID_MATRIX->"Cairo.Error(INVALID_MATRIX)"|INVALID_STATUS->"Cairo.Error(INVALID_STATUS)"|NULL_POINTER->"Cairo.Error(NULL_POINTER)"|INVALID_STRING->"Cairo.Error(INVALID_STRING)"|INVALID_PATH_DATA->"Cairo.Error(INVALID_PATH_DATA)"|READ_ERROR->"Cairo.Error(READ_ERROR)"|WRITE_ERROR->"Cairo.Error(WRITE_ERROR)"|SURFACE_FINISHED->"Cairo.Error(SURFACE_FINISHED)"|SURFACE_TYPE_MISMATCH->"Cairo.Error(SURFACE_TYPE_MISMATCH)"|PATTERN_TYPE_MISMATCH->"Cairo.Error(PATTERN_TYPE_MISMATCH)"|INVALID_CONTENT->"Cairo.Error(INVALID_CONTENT)"|INVALID_FORMAT->"Cairo.Error(INVALID_FORMAT)"|INVALID_VISUAL->"Cairo.Error(INVALID_VISUAL)"|FILE_NOT_FOUND->"Cairo.Error(FILE_NOT_FOUND)"|INVALID_DASH->"Cairo.Error(INVALID_DASH)"|INVALID_DSC_COMMENT->"Cairo.Error(INVALID_DSC_COMMENT)"|INVALID_INDEX->"Cairo.Error(INVALID_INDEX)"|CLIP_NOT_REPRESENTABLE->"Cairo.Error(CLIP_NOT_REPRESENTABLE)"|TEMP_FILE_ERROR->"Cairo.Error(TEMP_FILE_ERROR)"|INVALID_STRIDE->"Cairo.Error(INVALID_STRIDE)"|FONT_TYPE_MISMATCH->"Cairo.Error(FONT_TYPE_MISMATCH)"|USER_FONT_IMMUTABLE->"Cairo.Error(USER_FONT_IMMUTABLE)"|USER_FONT_ERROR->"Cairo.Error(USER_FONT_ERROR)"|NEGATIVE_COUNT->"Cairo.Error(NEGATIVE_COUNT)"|INVALID_CLUSTERS->"Cairo.Error(INVALID_CLUSTERS)"|INVALID_SLANT->"Cairo.Error(INVALID_SLANT)"|INVALID_WEIGHT->"Cairo.Error(INVALID_WEIGHT)"|INVALID_SIZE->"Cairo.Error(INVALID_SIZE)"|USER_FONT_NOT_IMPLEMENTED->"Cairo.Error(USER_FONT_NOT_IMPLEMENTED)"|DEVICE_TYPE_MISMATCH->"Cairo.Error(DEVICE_TYPE_MISMATCH)"|DEVICE_ERROR->"Cairo.Error(DEVICE_ERROR)"|INVALID_MESH_CONSTRUCTION->"Cairo.Error(INVALID_MESH_CONSTRUCTION)"|DEVICE_FINISHED->"Cairo.Error(DEVICE_FINISHED)"|JBIG2_GLOBAL_MISSING->"Cairo.Error(JBIG2_GLOBAL_MISSING)"let()=Printexc.register_printer(function|Errors->Some(error_of_statuss)|_->None)externalstatus_to_string:status->string="caml_cairo_status_to_string"exceptionUnavailablelet()=Callback.register_exception"Cairo.Unavailable"Unavailabletypecontexttypesurfacetypecontent=COLOR|ALPHA|COLOR_ALPHAtype'apatternconstraint'a=[<`Solid|`Surface|`Gradient|`Linear|`Radial]typeany_pattern=[`Solid|`Surface|`Gradient|`Linear|`Radial]patterntypeglyph={index:int;x:float;y:float}externalcreate:surface->context="caml_cairo_create"externalsave:context->unit="caml_cairo_save"externalrestore:context->unit="caml_cairo_restore"externalget_target:context->surface="caml_cairo_get_target"moduleGroup=structexternalpush_group:context->unit="caml_cairo_push_group"externalpush_group_with_content:context->content->unit="caml_cairo_push_group_with_content"letpush?contentcr=matchcontentwith|None->push_groupcr|Somec->push_group_with_contentcrcexternalpop:context->any_pattern="caml_cairo_pop_group"externalpop_to_source:context->unit="caml_cairo_pop_group_to_source"externalget_target:context->surface="caml_cairo_get_group_target"endexternalset_source_rgb:context->float->float->float->unit="caml_cairo_set_source_rgb"externalset_source_rgba:context->float->float->float->float->unit="caml_cairo_set_source_rgba"externalset_source:context->'apattern->unit="caml_cairo_set_source"externalset_source_surface:context->surface->x:float->y:float->unit="caml_cairo_set_source_surface"externalget_source:context->any_pattern="caml_cairo_get_source"typeantialias=|ANTIALIAS_DEFAULT|ANTIALIAS_NONE|ANTIALIAS_GRAY|ANTIALIAS_SUBPIXELexternalset_antialias:context->antialias->unit="caml_cairo_set_antialias"externalget_antialias:context->antialias="caml_cairo_get_antialias"externalset_dash_stub:context->floatarray->ofs:float->unit="caml_cairo_set_dash"letset_dashcr?(ofs=0.0)dashes=set_dash_stubcrdashes~ofsexternalget_dash:context->floatarray*float="caml_cairo_get_dash"typefill_rule=|WINDING|EVEN_ODDexternalset_fill_rule:context->fill_rule->unit="caml_cairo_set_fill_rule"externalget_fill_rule:context->fill_rule="caml_cairo_get_fill_rule"typeline_cap=|BUTT|ROUND|SQUAREexternalset_line_cap:context->line_cap->unit="caml_cairo_set_line_cap"externalget_line_cap:context->line_cap="caml_cairo_get_line_cap"typeline_join=|JOIN_MITER|JOIN_ROUND|JOIN_BEVELexternalset_line_join:context->line_join->unit="caml_cairo_set_line_join"externalget_line_join:context->line_join="caml_cairo_get_line_join"externalset_line_width:context->float->unit="caml_cairo_set_line_width"externalget_line_width:context->float="caml_cairo_get_line_width"externalset_miter_limit:context->float->unit="caml_cairo_set_miter_limit"externalget_miter_limit:context->float="caml_cairo_get_miter_limit"typeoperator=|CLEAR|SOURCE|OVER|IN|OUT|ATOP|DEST|DEST_OVER|DEST_IN|DEST_OUT|DEST_ATOP|XOR|ADD|SATURATEexternalset_operator:context->operator->unit="caml_cairo_set_operator"externalget_operator:context->operator="caml_cairo_get_operator"externalset_tolerance:context->float->unit="caml_cairo_set_tolerance"externalget_tolerance:context->float="caml_cairo_get_tolerance"externalclip:context->unit="caml_cairo_clip"externalclip_preserve:context->unit="caml_cairo_clip_preserve"typerectangle={x:float;y:float;w:float;h:float}externalclip_extents:context->rectangle="caml_cairo_clip_extents"externalclip_reset:context->unit="caml_cairo_reset_clip"externalclip_rectangle_list:context->rectanglelist="caml_cairo_copy_clip_rectangle_list"externalfill:context->unit="caml_cairo_fill"externalfill_preserve:context->unit="caml_cairo_fill_preserve"externalfill_extents:context->rectangle="caml_cairo_fill_extents"externalin_fill:context->float->float->bool="caml_cairo_in_fill"externalmask:context->'apattern->unit="caml_cairo_mask"externalmask_surface:context->surface->x:float->y:float->unit="caml_cairo_mask_surface"externalpaint_stub:context->unit="caml_cairo_paint"externalpaint_with_alpha:context->float->unit="caml_cairo_paint_with_alpha"letpaint?alphacr=matchalphawith|None->paint_stubcr|Somea->paint_with_alphacraexternalstroke:context->unit="caml_cairo_stroke"externalstroke_preserve:context->unit="caml_cairo_stroke_preserve"externalstroke_extents:context->rectangle="caml_cairo_stroke_extents"externalin_stroke:context->float->float->bool="caml_cairo_in_stroke"externalcopy_page:context->unit="caml_cairo_copy_page"externalshow_page:context->unit="caml_cairo_show_page"(* ---------------------------------------------------------------------- *)typepath_data=|MOVE_TOoffloat*float|LINE_TOoffloat*float|CURVE_TOoffloat*float*float*float*float*float|CLOSE_PATHmodulePath=structtypetexternalcopy:context->t="caml_cairo_copy_path"externalcopy_flat:context->t="caml_cairo_copy_path_flat"externalappend:context->t->unit="caml_cairo_append_path"externalget_current_point:context->float*float="caml_cairo_get_current_point"externalclear:context->unit="caml_cairo_new_path"externalsub:context->unit="caml_cairo_new_sub_path"externalclose:context->unit="caml_cairo_close_path"externalglyph:context->glypharray->unit="caml_cairo_glyph_path"externaltext:context->string->unit="caml_cairo_text_path"externalextents:context->rectangle="caml_cairo_path_extents"externalfold:t->('a->path_data->'a)->'a->'a="caml_cairo_path_fold"externalto_array:t->path_dataarray="caml_cairo_path_to_array"externalof_array:path_dataarray->t="caml_cairo_path_of_array"endexternalarc:context->float->float->r:float->a1:float->a2:float->unit="caml_cairo_arc_bc""caml_cairo_arc"externalarc_negative:context->float->float->r:float->a1:float->a2:float->unit="caml_cairo_arc_negative_bc""caml_cairo_arc_negative"externalcurve_to:context->float->float->float->float->float->float->unit="caml_cairo_curve_to_bc""caml_cairo_curve_to"externalline_to:context->float->float->unit="caml_cairo_line_to"externalmove_to:context->float->float->unit="caml_cairo_move_to"externalrectangle:context->float->float->w:float->h:float->unit="caml_cairo_rectangle"externalrel_curve_to:context->float->float->float->float->float->float->unit="caml_cairo_rel_curve_to_bc""caml_cairo_rel_curve_to"externalrel_line_to:context->float->float->unit="caml_cairo_rel_line_to"externalrel_move_to:context->float->float->unit="caml_cairo_rel_move_to"(* ---------------------------------------------------------------------- *)typematrix={mutablexx:float;mutableyx:float;mutablexy:float;mutableyy:float;mutablex0:float;mutabley0:float}moduleMatrix=structtypet=matrix(* x_new = xx *. x +. xy *. y +. x0;
y_new = yx *. x +. yy *. y +. y0; *)letinit_identity()={xx=1.;yx=0.;xy=0.;yy=1.;x0=0.;y0=0.}letinit_translatexy={xx=1.;yx=0.;xy=0.;yy=1.;x0=x;y0=y}letinit_scalexy={xx=x;yx=0.;xy=0.;yy=y;x0=0.;y0=0.}letinit_rotateangle={xx=cos(angle);yx=sin(angle);xy=-.sin(angle);yy=cos(angle);x0=0.;y0=0.}lettranslatemxy=m.x0<-m.x0+.m.xx*.x+.m.xy*.y;m.y0<-m.y0+.m.yx*.x+.m.yy*.yletscalemxy=m.xx<-m.xx*.x;m.yx<-m.yx*.x;m.xy<-m.xy*.y;m.yy<-m.yy*.yletrotatemangle=letcosa=cosangleandsina=sinangleinletxx=m.xxinm.xx<-xx*.cosa+.m.xy*.sina;m.xy<-m.xy*.cosa-.xx*.sina;letyx=m.yxinm.yx<-yx*.cosa+.m.yy*.sina;m.yy<-m.yy*.cosa-.yx*.sinaletinvertm=(* Optimize for scaling|translation matrices just like cairo... *)ifm.xy=0.&&m.yx=0.then(m.x0<--.m.x0;m.y0<--.m.y0;ifm.xx<>1.then(ifm.xx=0.thenraise(ErrorINVALID_MATRIX);m.xx<-1./.m.xx;m.x0<-m.x0*.m.xx;);ifm.yy<>1.then(ifm.yy=0.thenraise(ErrorINVALID_MATRIX);m.yy<-1./.m.yy;m.y0<-m.y0*.m.yy;);)elseletdet=m.xx*.m.yy-.m.yx*.m.xyinifdet=0.||1./.det=0.(* infinite det *)thenraise(ErrorINVALID_MATRIX);letyy=m.xx/.detinm.xx<-m.yy/.det;m.xy<--.m.xy/.det;m.yx<--.m.yx/.det;m.yy<-yy;lety0=-.m.yx*.m.x0-.yy*.m.y0inm.x0<--.m.xx*.m.x0-.m.xy*.m.y0;m.y0<-y0letmultiplyab={xx=b.xx*.a.xx+.b.xy*.a.yx;xy=b.xx*.a.xy+.b.xy*.a.yy;yx=b.yx*.a.xx+.b.yy*.a.yx;yy=b.yx*.a.xy+.b.yy*.a.yy;x0=b.xx*.a.x0+.b.xy*.a.y0+.b.x0;y0=b.yx*.a.x0+.b.yy*.a.y0+.b.y0;}lettransform_distancem~dx~dy=(m.xx*.dx+.m.xy*.dy,m.yx*.dx+.m.yy*.dy)lettransform_pointmxy=(m.xx*.x+.m.xy*.y+.m.x0,m.yx*.x+.m.yy*.y+.m.y0)end(* ---------------------------------------------------------------------- *)(* Rendering text and glyphs *)typetext_extents={x_bearing:float;y_bearing:float;width:float;height:float;x_advance:float;y_advance:float;}typesubpixel_order=|SUBPIXEL_ORDER_DEFAULT|SUBPIXEL_ORDER_RGB|SUBPIXEL_ORDER_BGR|SUBPIXEL_ORDER_VRGB|SUBPIXEL_ORDER_VBGRtypehint_style=|HINT_STYLE_DEFAULT|HINT_STYLE_NONE|HINT_STYLE_SLIGHT|HINT_STYLE_MEDIUM|HINT_STYLE_FULLtypehint_metrics=|HINT_METRICS_DEFAULT|HINT_METRICS_OFF|HINT_METRICS_ONmoduleFont_options=structtypetexternalset:context->t->unit="caml_cairo_set_font_options"externalget:context->t="caml_cairo_get_font_options"externalcreate:unit->t="caml_cairo_font_options_create"externalcopy:t->t="caml_cairo_font_options_copy"externalmerge:t->t->unit="caml_cairo_font_options_merge"externalset_antialias:t->antialias->unit="caml_cairo_font_options_set_antialias"externalget_antialias:t->antialias="caml_cairo_font_options_get_antialias"externalset_subpixel_order:t->subpixel_order->unit="caml_cairo_font_options_set_subpixel_order"externalget_subpixel_order:t->subpixel_order="caml_cairo_font_options_get_subpixel_order"externalset_hint_style:t->hint_style->unit="caml_cairo_font_options_set_hint_style"externalget_hint_style:t->hint_style="caml_cairo_font_options_get_hint_style"externalset_hint_metrics:t->hint_metrics->unit="caml_cairo_font_options_set_hint_metrics"externalget_hint_metrics:t->hint_metrics="caml_cairo_font_options_get_hint_metrics"letmake?(antialias=ANTIALIAS_DEFAULT)?(subpixel_order=SUBPIXEL_ORDER_DEFAULT)?(hint_style=HINT_STYLE_DEFAULT)?(hint_metrics=HINT_METRICS_DEFAULT)()=letfo=create()inset_antialiasfoantialias;set_subpixel_orderfosubpixel_order;set_hint_stylefohint_style;set_hint_metricsfohint_metrics;foendtypeslant=Upright|Italic|Obliquetypeweight=Normal|Boldtypefont_type=[`Toy|`Ft|`Win32|`Quartz|`User]externalfont_type_init:unit->unit="caml_cairo_font_type_init"[@@noalloc]let()=font_type_init()moduleFont_face=structtype'atexternalset:context->_t->unit="caml_cairo_set_font_face"externalget:context->font_typet="caml_cairo_get_font_face"externalget_type:'at->font_type="caml_cairo_font_face_get_type"externalcreate_stub:family:string->slant->weight->[`Toy]t="caml_cairo_toy_font_face_create"letcreate?(family="")slantweight=create_stub~familyslantweightexternalget_family:[`Toy]t->string="caml_cairo_toy_font_face_get_family"externalget_slant:[`Toy]t->slant="caml_cairo_toy_font_face_get_slant"externalget_weight:[`Toy]t->weight="caml_cairo_toy_font_face_get_weight"endmoduleGlyph=struct(* type array (\* FIXME: abstract type for cairo_glyph_t* ? *\) *)typet=glyph={index:int;x:float;y:float}typecluster={num_bytes:int;num_glyphs:int;}typecluster_flags=|BACKWARDexternalextents:context->tarray->text_extents="caml_cairo_glyph_extents"externalshow:context->tarray->unit="caml_cairo_show_glyphs"externalshow_text:context->string->tarray->clusterarray->cluster_flags->unit="caml_cairo_show_text_glyphs"endtypefont_extents={ascent:float;descent:float;baseline:float;max_x_advance:float;max_y_advance:float;}moduleScaled_font=structtype'atexternalset:context->_t->unit="caml_cairo_set_scaled_font"externalget:context->_t="caml_cairo_get_scaled_font"externalcreate:'aFont_face.t->Matrix.t->Matrix.t->Font_options.t->'at="caml_cairo_scaled_font_create"externalextents:_t->font_extents="caml_cairo_scaled_font_extents"externaltext_extents:_t->string->text_extents="caml_cairo_scaled_font_text_extents"externalglyph_extents:_t->Glyph.tarray->text_extents="caml_cairo_scaled_font_glyph_extents"externaltext_to_glyphs:_t->x:float->y:float->string->Glyph.tarray*Glyph.clusterarray*Glyph.cluster_flags="caml_cairo_scaled_font_text_to_glyphs"externalget_font_face:'at->'aFont_face.t="caml_cairo_scaled_font_get_font_face"externalget_font_options:_t->Font_options.t="caml_cairo_scaled_font_get_font_options"externalget_font_matrix:_t->Matrix.t="caml_cairo_scaled_font_get_font_matrix"externalget_ctm:_t->Matrix.t="caml_cairo_scaled_font_get_ctm"externalget_scale_matrix:_t->Matrix.t="caml_cairo_scaled_font_get_scale_matrix"externalget_type:_t->font_type="caml_cairo_scaled_font_get_type"endmoduleFt=structtypefacetypelibraryletft_library=refNone(* FIXME: is it important to have to possibility to create more than
one library resource? *)externalinit_freetype:unit->library="caml_cairo_Ft_init_FreeType"letget_ft_library()=match!ft_librarywith|None->letft=init_freetype()inft_library:=Someft;ft|Someft->ftexternalnew_face:library->string->int->face="caml_cairo_Ft_new_face"letface?library?(index=0)pathname=letft=matchlibrarywith|Somel->l|None->get_ft_library()innew_faceftpathnameindexexternalcreate_for_ft_face_:face->vertical:bool->autohint:bool->[`Ft]Font_face.t="caml_cairo_ft_create_for_ft_face"typeflag=[`Vertical_layout|`Force_autohint]letcreate_for_ft_face?(flags=[])face=letvertical=reffalseinletautohint=reffalseinList.iter(function`Vertical_layout->vertical:=true|`Force_autohint->autohint:=true)flags;create_for_ft_face_face~vertical:!vertical~autohint:!autohintexternalcreate_for_pattern:?options:Font_options.t->string->[`Ft]Font_face.t="caml_cairo_ft_create_for_pattern"externalscaled_font_lock_face:[`Ft]Scaled_font.t->face="caml_cairo_ft_scaled_font_lock_face"externalscaled_font_unlock_face:[`Ft]Scaled_font.t->unit="caml_cairo_ft_scaled_font_unlock_face"moduleSynthesize=structtypet={bold:bool;oblique:bool}externalget:[`Ft]Font_face.t->t="caml_cairo_ft_synthesize_get"externalset_:[`Ft]Font_face.t->bold:bool->oblique:bool->unit="caml_cairo_ft_synthesize_set"externalunset_:[`Ft]Font_face.t->bold:bool->oblique:bool->unit="caml_cairo_ft_synthesize_unset"letset?(bold=false)?(oblique=false)ff=set_ff~bold~obliqueletunset?(bold=false)?(oblique=false)ff=unset_ff~bold~obliqueendendexternalselect_font_face:context->slant->weight->string->unit="caml_cairo_select_font_face"letselect_font_facecr?(slant=Upright)?(weight=Normal)family=select_font_facecrslantweightfamilyexternalset_font_size:context->float->unit="caml_cairo_set_font_size"externalset_font_matrix:context->Matrix.t->unit="caml_cairo_set_font_matrix"externalget_font_matrix:context->Matrix.t="caml_cairo_get_font_matrix"externalshow_text:context->string->unit="caml_cairo_show_text"externalfont_extents:context->font_extents="caml_cairo_font_extents"externaltext_extents:context->string->text_extents="caml_cairo_text_extents"(* ---------------------------------------------------------------------- *)moduleSurface=structtypet=surfaceexternalcreate_similar:t->content->w:int->h:int->t="caml_cairo_surface_create_similar"externalfinish:t->unit="caml_cairo_surface_finish"externalflush:t->unit="caml_cairo_surface_flush"externalget_font_options:t->Font_options.t="caml_cairo_surface_get_font_options"externalget_content:t->content="caml_cairo_surface_get_content"externalmark_dirty:t->unit="caml_cairo_surface_mark_dirty"externalmark_dirty_rectangle:t->int->int->w:int->h:int->unit="caml_cairo_surface_mark_dirty_rectangle"externalset_device_offset:t->float->float->unit="caml_cairo_surface_set_device_offset"externalget_device_offset:t->float*float="caml_cairo_surface_get_device_offset"externalset_fallback_resolution:t->x:float->y:float->unit="caml_cairo_surface_set_fallback_resolution"externalget_fallback_resolution:t->float*float="caml_cairo_surface_get_fallback_resolution"typekind=[`Image|`PDF|`PS|`XLib|`XCB|`GLITZ|`Quartz|`Win32|`BEOS|`DirectFB|`SVG|`OS2|`Win32_printing|`Quartz_image|`Recording]externalinit:unit->unit="caml_cairo_surface_kind_init"let()=init()externalget_type:t->kind="caml_cairo_surface_get_type"externalcopy_page:t->unit="caml_cairo_surface_copy_page"externalshow_page:t->unit="caml_cairo_surface_show_page"externalhas_show_text_glyphs:t->bool="caml_cairo_surface_has_show_text_glyphs"endmoduleImage=structtypeformat=|ARGB32|RGB24|A8|A1externalcreate:format->w:int->h:int->Surface.t="caml_cairo_image_surface_create"externalget_format:Surface.t->format="caml_cairo_image_surface_get_format"externalget_width:Surface.t->int="caml_cairo_image_surface_get_width"externalget_height:Surface.t->int="caml_cairo_image_surface_get_height"externalget_stride:Surface.t->int="caml_cairo_image_surface_get_stride"externalstride_for_width:format->int->int="caml_cairo_format_stride_for_width"[@@noalloc]openBigarraytypedata8=(int,Bigarray.int8_unsigned_elt,Bigarray.c_layout)Bigarray.Array1.ttypedata32=(int32,Bigarray.int32_elt,Bigarray.c_layout)Bigarray.Array2.t(* These direct bindings assume that the bigarray is large enough *)externalcreate_for_data8_unsafe:data8->format->w:int->h:int->stride:int->Surface.t="caml_cairo_image_surface_create_for_data8"externalcreate_for_data32_unsafe:data32->format->w:int->h:int->stride:int->Surface.t="caml_cairo_image_surface_create_for_data32"letcreate_for_data8data?strideformat~w~h=ifw<=0theninvalid_arg"Cairo.Image.create_for_data8: width <= 0";ifh<=0theninvalid_arg"Cairo.Image.create_for_data8: height <= 0";letstride=matchstridewith|None->stride_for_widthformatw|Somes->ifs<w(* thus if s <= 0 *)thenraise(ErrorINVALID_STRIDE);sinifstride*h>Array1.dimdatatheninvalid_arg(Printf.sprintf"Cairo.Image.create_for_data8: bigarray too \
small for the required stride=%i and height=%i"strideh);create_for_data8_unsafedataformat~w~h~strideletcreate_for_data32?w?h?(alpha=true)data=letwidth=matchwwith|None->Array2.dim2data|Somew->ifw<0theninvalid_arg"Cairo.Image.create_for_data32: width < 0";ifw>Array2.dim2datatheninvalid_arg"Cairo.Image.create_for_data32: given width too large";winletheight=matchhwith|None->Array2.dim1data|Someh->ifh<0theninvalid_arg"Cairo.Image.create_for_data32: height < 0";ifh>Array2.dim1datatheninvalid_arg"Cairo.Image.create_for_data32: given height too large";hinletformat=ifalphathenARGB32elseRGB24in(* Both format use 32 bits = 4 bytes *)create_for_data32_unsafedataformat~w:width~h:height~stride:(4*Array2.dim2data)externalget_data8:Surface.t->(int,int8_unsigned_elt,c_layout)Array1.t="caml_cairo_image_surface_get_UINT8"externalget_data32:Surface.t->(int32,int32_elt,c_layout)Array2.t="caml_cairo_image_surface_get_INT32"letget_data32surface=letformat=get_formatsurfaceinifformat<>ARGB32&&format<>RGB24theninvalid_arg"Cairo.Image.get_data32: image format must be \
ARGB32 or RGB24";get_data32surfaceletoutput_ppmfh?w?h(data:data32)=letwidth=matchwwith|None->Array2.dim1data|Somew->ifw>Array2.dim1datatheninvalid_arg"Cairo.Image.output_ppm: width > Array2.dim1 data";ifw<=0theninvalid_arg"Cairo.Image.output_ppm: width <= 0";winletheight=matchhwith|None->Array2.dim2data|Someh->ifh>Array2.dim2datatheninvalid_arg"Cairo.Image.output_ppm: height > Array2.dim2 data";ifh<=0theninvalid_arg"Cairo.Image.output_ppm: height <= 0";hinPrintf.fprintffh"P6 %d %d 255\n"widthheight;fori=0towidth-1doforj=0toheight-1do(* Output pixel RGB *)letp=Int32.to_intdata.{i,j}inoutput_bytefh((plsr16)land0xFF);output_bytefh((plsr8)land0xFF);output_bytefh(pland0xFF)donedone(* flush fh ?? *)endmodulePDF=structexternalcreate_for_stream:(string->unit)->w:float->h:float->Surface.t="caml_cairo_pdf_surface_create_for_stream"externalcreate:string->w:float->h:float->Surface.t="caml_cairo_pdf_surface_create"(* Do we want to implement it in terms of [create_for_stream]?
The "problem" is the absence of close function... *)externalset_size:Surface.t->w:float->h:float->unit="caml_cairo_pdf_surface_set_size"[@@noalloc]endmodulePNG=structexternalcreate:string->Surface.t="caml_cairo_image_surface_create_from_png"externalcreate_from_stream:input:(string->int->unit)->Surface.t="caml_cairo_image_surface_create_from_png_stream"(* FIXME: must hold the input function to avoid it is being
reclaimed before the surface? *)externalwrite:Surface.t->string->unit="caml_cairo_surface_write_to_png"externalwrite_to_stream:Surface.t->(string->unit)->unit="caml_cairo_surface_write_to_png_stream"endmodulePS=structexternalcreate_for_stream:(string->unit)->w:float->h:float->Surface.t="caml_cairo_ps_surface_create_for_stream"externalcreate:string->w:float->h:float->Surface.t="caml_cairo_ps_surface_create"typelevel=LEVEL_2|LEVEL_3externalrestrict_to_level:Surface.t->level->unit="caml_cairo_ps_surface_restrict_to_level"externalget_levels:unit->levellist="caml_cairo_ps_get_levels"externallevel_to_string:level->string="caml_cairo_ps_level_to_string"externalset_eps:Surface.t->eps:bool->unit="caml_cairo_ps_surface_set_eps"externalget_eps:Surface.t->bool="caml_cairo_ps_surface_get_eps"externalset_size:Surface.t->w:float->h:float->unit="caml_cairo_ps_surface_set_size"moduleDsc=structexternalbegin_setup:Surface.t->unit="caml_cairo_ps_surface_dsc_begin_setup"externalbegin_page_setup:Surface.t->unit="caml_cairo_ps_surface_dsc_begin_page_setup"externalcomment:Surface.t->string->unit="caml_cairo_ps_surface_dsc_comment"endendmoduleSVG=structexternalcreate:string->w:float->h:float->Surface.t="caml_cairo_svg_surface_create"externalcreate_for_stream:(string->unit)->w:float->h:float->Surface.t="caml_cairo_svg_surface_create_for_stream"typeversion=VERSION_1_1|VERSION_1_2externalrestrict_to_version:Surface.t->version->unit="caml_cairo_svg_surface_restrict_to_version"externalget_versions:unit->versionlist="caml_cairo_svg_get_versions"externalversion_to_string:version->string="caml_cairo_svg_version_to_string"endmoduleRecording=structexternalcreate:?extents:rectangle->content->Surface.t="caml_cairo_recording_surface_create"externalink_extents:Surface.t->rectangle="caml_cairo_recording_surface_ink_extents"end(* ---------------------------------------------------------------------- *)modulePattern=structtype'at='apatterntypeany=any_patternexternaladd_color_stop_rgb_stub:[>`Gradient]t->ofs:float->float->float->float->unit="caml_cairo_pattern_add_color_stop_rgb"[@@noalloc]letadd_color_stop_rgbcr?(ofs=0.0)rgb=add_color_stop_rgb_stubcr~ofsrgbexternaladd_color_stop_rgba_stub:[>`Gradient]t->ofs:float->float->float->float->float->unit="caml_cairo_pattern_add_color_stop_rgba_bc""caml_cairo_pattern_add_color_stop_rgba"[@@noalloc]letadd_color_stop_rgbacr?(ofs=0.0)rgba=add_color_stop_rgba_stubcr~ofsrgbaexternalget_color_stop_count:[>`Gradient]t->int="caml_cairo_pattern_get_color_stop_count"externalget_color_stop_rgba:[>`Gradient]t->idx:int->float*float*float*float*float="caml_cairo_pattern_get_color_stop_rgba"(* FIXME: do we want to iterate over the colors instead ?? *)externalcreate_rgb:float->float->float->[`Solid]t="caml_cairo_pattern_create_rgb"externalcreate_rgba:float->float->float->float->[`Solid]t="caml_cairo_pattern_create_rgba"externalget_rgba:[>`Solid]t->float*float*float*float="caml_cairo_pattern_get_rgba"externalcreate_for_surface:Surface.t->[`Surface]t="caml_cairo_pattern_create_for_surface"externalget_surface:[`Surface]t->Surface.t="caml_cairo_pattern_get_surface"externalcreate_linear:x0:float->y0:float->x1:float->y1:float->[`Linear|`Gradient]t="caml_cairo_pattern_create_linear"externalget_linear_points:[>`Linear|`Gradient]t->float*float*float*float="caml_cairo_pattern_get_linear_points"externalcreate_radial:x0:float->y0:float->r0:float->x1:float->y1:float->r1:float->[`Radial|`Gradient]t="caml_cairo_pattern_create_radial_bc""caml_cairo_pattern_create_radial"externalget_radial_circles:[>`Radial|`Gradient]t->float*float*float*float*float*float="caml_cairo_pattern_get_radial_circles"typeextend=|NONE|REPEAT|REFLECT|PADexternalset_extend:'at->extend->unit="caml_cairo_pattern_set_extend"[@@noalloc]externalget_extend:'at->extend="caml_cairo_pattern_get_extend"typefilter=|FAST|GOOD|BEST|NEAREST|BILINEAR(* | GAUSSIAN *)externalset_filter:'at->filter->unit="caml_cairo_pattern_set_filter"[@@noalloc]externalget_filter:'at->filter="caml_cairo_pattern_get_filter"externalset_matrix:'at->Matrix.t->unit="caml_cairo_pattern_set_matrix"[@@noalloc]externalget_matrix:'at->Matrix.t="caml_cairo_pattern_get_matrix"end(* ---------------------------------------------------------------------- *)(* Transformations - Manipulating the current transformation matrix *)externaltranslate:context->float->float->unit="caml_cairo_translate"externalscale:context->float->float->unit="caml_cairo_scale"externalrotate:context->float->unit="caml_cairo_rotate"externaltransform:context->Matrix.t->unit="caml_cairo_transform"[@@noalloc]externalset_matrix:context->Matrix.t->unit="caml_cairo_set_matrix"[@@noalloc]externalget_matrix:context->Matrix.t="caml_cairo_get_matrix"externalidentity_matrix:context->unit="caml_cairo_identity_matrix"externaluser_to_device:context->float->float->float*float="caml_cairo_user_to_device"externaluser_to_device_distance:context->float->float->float*float="caml_cairo_user_to_device_distance"externaldevice_to_user:context->float->float->float*float="caml_cairo_device_to_user"externaldevice_to_user_distance:context->float->float->float*float="caml_cairo_device_to_user_distance"