123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290(**************************************************************************)(* *)(* Copyright (C) Johannes Kanig, Stephane Lescuyer *)(* Jean-Christophe Filliatre, Romain Bardou and Francois Bobot *)(* *)(* This software is free software; you can redistribute it and/or *)(* modify it under the terms of the GNU Library General Public *)(* License version 2.1, with the special exception on linking *)(* described in file LICENSE. *)(* *)(* This software 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. *)(* *)(**************************************************************************)openPoint_libopenMatrixmoduleP=Picture_libmoduleS=Spline_libopenDviinterpletfprintf=Format.fprintfletconversion=0.3937*.72.letpoint_of_cmcm=conversion*.cmletfloatfmtf=(* PDF does not understand e notation, so we protect the printf which
uses %g in the cases where this would use e notation; we do not need that
much precision anyway*)leta=abs_floatfinifclassify_floatf=FP_nanthen(* should be an error there is a bug somewhere to track *)fprintffmt"0"elseifa<0.0001thenfprintffmt"0"elseifa>=1.e04thenfprintffmt"%.4f"felsefprintffmt"%.4g"fletbpfmtf=Format.fprintffmt"%a bp"floatfletreclistseppfmtl=matchlwith|[]->()|[x]->pfmtx|x::xs->pfmtx;sepfmt;listseppfmtxsletoptionseppfmto=matchowith|None->()|Somex->pfmtx;sepfmtletnothing_=()letspacefmt=fprintffmt"@ "letbracespfmtx=fprintffmt"{%a}"pxmodulePGF=structtypeline_cap=ButtCap|RoundCap|SquareCaplet_=ButtCaplet_=SquareCaptypeline_join=MiterJoin|RoundJoin|BevelJoinlet_=MiterJoinlet_=BevelJoinletpointfmtp=fprintffmt"\\pgfqpoint{%a}{%a}"bpp.xbpp.yletmovetofmtp=fprintffmt"\\pgfpathmoveto{%a}"pointpletlinetofmtp=fprintffmt"\\pgfpathlineto{%a}"pointpletcurvetofmtp1p2p3=fprintffmt"\\pgfpathcurveto{%a}{%a}{%a}"pointp1pointp2pointp3letclose_pathfmt=fprintffmt"\\pgfpathclose"letstrokefmt=fprintffmt"\\pgfusepath{stroke}"letfillfmt=fprintffmt"\\pgfusepath{fill}"letclipfmt=fprintffmt"\\pgfusepath{clip}"letgsavefmt=fprintffmt"\\begin{pgfscope}"letgrestorefmt=fprintffmt"\\end{pgfscope}"letsetlinewidthfmtf=(* handle strange treatment of linewidth of Metapost *)fprintffmt"\\pgfsetlinewidth{%a}"bpfletsetlinecapfmtc=leti=matchcwith|ButtCap->"butt"|RoundCap->"round"|SquareCap->"rect"infprintffmt"\\pgfset%scap"iletsetlinejoinfmtj=leti=matchjwith|MiterJoin->"miter"|RoundJoin->"round"|BevelJoin->"bevel"infprintffmt"\\pgfset%sjoin"ilettransformfmtt=ift=Matrix.identitythen()elsefprintffmt"\\pgflowlevel{\\pgftransformcm{%a}{%a}{%a}{%a}{%a}}"floatt.xxfloatt.yxfloatt.xyfloatt.yypoint{x=t.x0;y=t.y0}letscolor_rgbfmtrgb=fprintffmt"\\color[rgb]{%a,%a,%a}"floatrfloatgfloatbletscolor_cmykfmtcmyk=fprintffmt"\\color[cmyk]{%a,%a,%a,%a}"floatcfloatmfloatyfloatkletscolor_hsbfmthsb=fprintffmt"\\color[hsb]{%a,%a,%a}"floathfloatsfloatbletscolor_grayfmtc=fprintffmt"\\color[gray]{%a}"floatcletscolorfmtc=matchcwith|Concrete_types.RGB(r,g,b)->scolor_rgbfmtrgb|Concrete_types.CMYK(c,m,y,k)->scolor_cmykfmtcmyk|Concrete_types.Grayc->scolor_grayfmtcletcolorfmtc=matchcwith|Concrete_types.OPAQUEc->scolorfmtc|Concrete_types.TRANSPARENT(f,c)->fprintffmt"\\pgfsetfillopacity{%a}\\pgfsetstrokeopacity{%a}%a"floatffloatfscolorcletdvi_colorfmtc=matchcwith|Dviinterp.RGB(r,g,b)->scolor_rgbfmtrgb|Dviinterp.CMYK(c,m,y,k)->scolor_cmykfmtcmyk|Dviinterp.HSB(h,s,b)->scolor_hsbfmthsb|Dviinterp.Grayg->scolor_grayfmtgletdashfmt(offset,pattern)=fprintffmt"\\pgfsetdash{%a}{%a}"(listnothing(bracesbp))patternbpoffsetletchar_constfmtc=fprintffmt"\\char'%03lo"cletglyphfmtpclfont=fprintffmt"\\pgftext[base,left,at={%a}]{{\\font\\mlpostfont=%s at %apt \
{\\mlpostfont %a}}}"pointp(Fonts.tex_namefont)float(Fonts.scalefontconversion)(listnothingchar_const)clletglyphppfmt(cl,font)=glyphfmtpclfontletrectanglefmtpwh=fprintffmt"\\pgfpathrectangle{%a}{%a} %t"pointppoint{x=w;y=h}fillletrectanglepfmt(p,w,h)=rectanglefmtpwhendletin_contextfmtf=fprintffmt"@[<v>%t@, @[<v>%t@]@,%t@]"PGF.gsavefPGF.grestoreletfill_rectfmttransixywh=letx=point_of_cmxandy=point_of_cmyandw=point_of_cmwandh=point_of_cmhinletp={x;y}inin_contextfmt(fun_->fprintffmt"%a@ %a@ %a"PGF.transformtransPGF.dvi_colori.Dviinterp.colorPGF.rectanglep(p,w,h))letdraw_charfmttranstext=(* FIXME why do we need to negate y coordinates? *)letf1,f2=text.tex_posinletf1=point_of_cmf1andf2=point_of_cmf2inletp={x=f1;y=-.f2}inin_contextfmt(fun_->fprintffmt"%a@ %a@ %a"PGF.transformtransPGF.dvi_colortext.Dviinterp.tex_info.Dviinterp.color(PGF.glyphpp)(text.tex_string,text.tex_font))(* FIXME why do we need to negate y coordinates? *)lettex_cmdfmttransc=matchcwith|Dviinterp.Fill_rect(i,x,y,w,h)->fill_rectfmttransix(-.y)wh|Dviinterp.Draw_texttext->draw_charfmttranstext|Dviinterp.Specials_->()|Dviinterp.Draw_text_type1_->assertfalseletdraw_texfmtt=listspace(funfmtx->tex_cmdfmtt.Gentex.transx)fmtt.Gentex.texletcurvetofmts=letsa,sb,sc,sd=Spline.explodesinifsa=sb&&sc=sdthenPGF.linetofmtsdelsePGF.curvetofmtsbscsdletpath=letpathfmt=function|S.Pathp->(matchp.S.plwith|[]->assertfalse|x::_asl->fprintffmt"%a@ %a"PGF.moveto(Spline.left_pointx)(listspacecurveto)l);ifp.S.cyclethenfprintffmt" %t"PGF.close_path|S.Pointp->fprintffmt"%a@ %a"PGF.movetopPGF.linetopinfunfmtp->fprintffmt"%a"pathpletpenfmtt=(* FIXME do something better *)(* for now assume that the pen is simply a scaled circle, so just grab the xx
* value of the matrix and use that as linewidth *)PGF.setlinewidthfmtt.xxletrecpicturefmtp=matchpwith|P.Empty->()|P.OnTopl->listspacepicturefmtl|P.Stroke_path(pa,clr,pe,da)->in_contextfmt(fun_->fprintffmt"%a%a%a@ %a@ %t\n"(optionspacePGF.color)clr(optionspacePGF.dash)dapenpepathpaPGF.stroke)|P.Fill_path(p,clr)->in_contextfmt(fun_->fprintffmt"%a%a@ %t\n"(optionspacePGF.color)clrpathpPGF.fill)|P.Text->draw_texfmtt|P.Clip(com,p)->in_contextfmt(fun_->fprintffmt"%a@ %t@ %a"pathpPGF.clippicturecom)|P.Transform(t,p)->in_contextfmt(fun_->fprintffmt"%a@ %a"PGF.transformtpicturep)|P.ExternalImage(f,_,t)->in_contextfmt(fun_->fprintffmt"%a@ \\pgftext{\\includegraphics{%s}}"PGF.transformtf)letdrawfmtx=letfmt=Format.formatter_of_out_channelfmtinletp1,p2=Picture_lib.bounding_boxxinfprintffmt"%%%%Creator: Mlpost %s@."Mlpost_version.version;fprintffmt"\\begin{tikzpicture}@.";fprintffmt"\\useasboundingbox (%a, %a) rectangle (%a, %a);@."bpp1.xbpp1.ybpp2.xbpp2.y;in_contextfmt(fun_->fprintffmt"%a@ %a@ %a@ %a"PGF.setlinewidth(P.default_line_size/.2.)PGF.setlinecapPGF.RoundCapPGF.setlinejoinPGF.RoundJoinpicture(P.contentx));fprintffmt"@.\\end{tikzpicture}@."letgenerate_onefnfig=File.write_tofn(funfmt->letfig=Compute.commandpicfigin(* Format.printf "picturelib code: \n %a@." P.Print.pic fig; *)drawfmtfig);fnletmpsfigl=List.map(fun(fn,fig)->letfn=File.mkfn"pgf"in(* Format.printf "metapost code:\n %a@."Print.commandpic fig; *)generate_onefnfig)figlletdump()=ignore(mps(Defaults.emited()))letgeneratefigs=ignore(mpsfigs)