1%D \module 2%D [ file=meta-pdf, 3%D version=2006.06.07, 4%D title=\METAPOST\ Graphics, 5%D subtitle=Conversion to \PDF, 6%D author=Hans Hagen \& others (see text), 7%D date=\currentdate, 8%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] 9%C 10%C This module is part of the \CONTEXT\ macro||package and is 11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for 12%C details. 13 14\endinput 15 16%D Formerly known as supp-pdf.tex and supp-mpe.tex and meta-pdf.mkiv. 17%D 18%D Beware: this file is not used but kept for historic purposed! Never 19%D mix this one into mkiv again as it uses other variables. 20 21% \useMPgraphic{1} 22% \testfeatureonce{250}{\setbox0\hbox{\convertMPtoPDF{test-mps-mpgraph.1}{1}{1}}} 23% 24% 8.4 : mkii, direct parsing by tex 25% 11.8 : mkiv, dirty conversion (10.8 with dirty tricks) 26% 14.5 : mkiv, clean conversion 27% 7.4 : mkiv, simulated clean direct lua from mp 28% 0.3 : time taken by tex to handle converted code 29% 30% timings may differ now that we revamped the backend 31 32\registerctxluafile{meta-pdf}{} 33 34%D We will clean up the color mess later. 35 36\writestatus{loading}{MetaPost Graphics / MPS to PDF} 37 38\unprotect 39 40%D First we define a handy constant: 41 42\bgroup \catcode\commentasciicode\othercatcode \xdef\letterpercent{\string%} \egroup 43 44%D \macros 45%D {convertMPtoPDF} 46%D 47%D The next set of macros implements \METAPOST\ to \PDF\ 48%D conversion. The traditional method is in the MkII file. 49%D 50%D The main conversion command is: 51%D 52%D \starttyping 53%D \convertMPtoPDF {filename} {x scale} {y scale} 54%D \stoptyping 55%D 56%D The dimensions are derived from the bounding box. So we 57%D only have to say: 58%D 59%D \starttyping 60%D \convertMPtoPDF{mp-pra-1.eps}{1}{1} 61%D \convertMPtoPDF{mp-pra-1.eps}{.5}{.5} 62%D \stoptyping 63 64%D \macros 65%D {makeMPintoPDFobject,lastPDFMPobject} 66%D 67%D For experts there are a few more options. When attributes 68%D are to be added, the code must be embedded in an object 69%D accompanied with the appropriate directives. One can 70%D influence this process with \type {\makeMPintoPDFobject}. 71%D 72%D This option defaults to~0, because \CONTEXT\ takes care 73%D of objects at another level, which saves some bytes. 74%D 75%D \starttabulate[|l|l|p|] 76%D \NC 0 \NC never \NC don't use an object \NC\NR 77%D \NC 1 \NC always \NC always use an object \NC\NR 78%D \NC 2 \NC optional \NC use object when needed \NC\NR 79%D \stoptabulate 80%D 81%D The last object number used is avaliable in the macro 82%D \type {\lastPDFMPobject}. 83 84\ifx\makeMPintoPDFobject \undefined \newconstant\makeMPintoPDFobject \fi 85\ifx\everyMPtoPDFconversion\undefined \newtoks \everyMPtoPDFconversion \fi 86 87\let\lastPDFMPobject \!!zerocount 88\let\currentPDFresources\empty 89\let\setMPextensions \relax 90 91\def\PDFMPformoffset 92 {\ifx\objectoffset\undefined\zeropoint\else\objectoffset\fi} 93 94\def\resetMPvariables#1#2#3% 95 {\glet\MPwidth \!!zeropoint 96 \glet\MPheight \!!zeropoint 97 \glet\MPllx \!!zerocount 98 \glet\MPlly \!!zerocount 99 \glet\MPurx \!!zerocount 100 \glet\MPury \!!zerocount 101 \xdef\MPxscale {#2}\ifx\MPxscale\empty\let\MPxscale\!!plusone\fi 102 \xdef\MPyscale {#3}\ifx\MPyscale\empty\let\MPyscale\!!plusone\fi 103 \xdef\MPfilename {#1}} 104 105%D The main macro: 106 107\def\convertMPtoPDF#1#2#3% watch the transparency reset 108 {\resetMPvariables{#1}{#2}{#3}% 109 \vpack\bgroup 110 \forgetall 111 \offinterlineskip 112 \setbox\scratchbox\vpack\bgroup 113 \setnormalcatcodes % we can be in verbatim or so 114 \message{[MP to PDF]}% 115 \startMPresources 116 \pdfliteral{\letterpercent\space mps begin}% 117 \pdfliteral{q 1 0 0 1 0 0 cm}% 118 metapost.mptopdf.convertmpstopdf("\MPfilename")\removeunwantedspaces 119 \pdfliteral{Q}% 120 \pdfliteral{\letterpercent\space mps end}% 121 \stopMPresources 122 \egroup 123 \setbox\scratchbox\hpack\bgroup 124 \hskip-\MPllx\onebasepoint 125 \raise-\MPlly\onebasepoint 126 \box\scratchbox 127 \egroup 128 \setbox\scratchbox\vpack to \MPheight\bgroup 129 \vfill 130 \hsize\MPwidth 131 \smashbox\scratchbox 132 \box\scratchbox 133 \egroup 134 \wd\scratchbox\MPwidth 135 \ht\scratchbox\MPheight 136 \dopackageMPgraphic\scratchbox 137 \egroup} 138 139\let\processMPtoPDFfile\convertMPtoPDF 140 141%D A common hook. 142 143\let\MPfshowcommand\empty 144 145%D Objects. 146 147\def\dopackageMPgraphic#1% #1 = boxregister 148 {\ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else 149 % an existing value of 2 signals object support (set elsewhere) 150 \makeMPintoPDFobject\plusone 151 \fi\fi 152 \ifcase\makeMPintoPDFobject 153 \box#1% 154 \or 155 \scratchdimen\PDFMPformoffset\relax 156 \ifdim\scratchdimen>\zeropoint % compensate for error 157 \setbox#1\vpack spread 2\scratchdimen 158 {\forgetall\vss\hpack spread 2\scratchdimen{\hss\box#1\hss}\vss}% 159 \fi 160 \setMPPDFobject{\currentPDFresources}{#1}% 161 \ifdim\scratchdimen>\zeropoint % compensate for error 162 \vpack to \MPheight 163 {\forgetall\vss\hpack to \MPwidth{\hss\getMPPDFobject\hss}\vss}% 164 \else 165 \getMPPDFobject 166 \fi 167 \glet\currentPDFresources\empty 168 \else 169 \box#1% 170 \fi} 171 172\def\setMPPDFobject#1#2% resources boxnumber 173 {\ifx\everyPDFxform\undefined\else\the\everyPDFxform\fi 174 \immediate\saveboxresource resources{#1}#2% 175 \edef\getMPPDFobject{\noexpand\useboxresource\the\lastsavedboxresourceindex}} 176 177\let\getMPPDFobject\relax 178 179%D \macros 180%D {deleteMPgraphic, 181%D startMPresources, 182%D stopMPresources} 183 184\ifx\deleteMPgraphic\undefined 185 \def\deleteMPgraphic#1{} 186\fi 187 188\ifx\startMPresources\undefined 189 \let\startMPresources\relax 190 \let\stopMPresources\relax 191\fi 192 193%D We implement extensions by using the \METAPOST\ special 194%D mechanism. Opposite to \TEX's specials, the \METAPOST\ ones 195%D are flushed before or after the graphic data, but thereby 196%D are no longer connected to a position. 197%D 198%D We implement specials by overloading the \type {fill} 199%D operator. By counting the fills, we can let the converter 200%D treat the appropriate fill in a special way. The 201%D specification of the speciality can have two forms, 202%D determined by the setting of a boolean variable: 203%D 204%D \starttyping 205%D _inline_specials_ := false ; % comment like code (default) 206%D _inline_specials_ := true ; % command like code 207%D \stoptyping 208%D 209%D When the specification is embedded as comment, it looks 210%D like: 211%D 212%D \starttyping 213%D %%MetaPostSpecial <size> <data> <number> <identifier> 214%D \stoptyping 215%D 216%D The in||line alternative is more tuned for \POSTSCRIPT, 217%D since it permits us to define a macro \type {special}. 218%D 219%D \starttyping 220%D inline : <data> <number> <identifier> <size> special 221%D \stoptyping 222%D 223%D The \type {identifier} determines what to do, and the data 224%D can be used to accomplish this. A type~2 shading function 225%D has identifier~2. Alltogether, the number of parameters is 226%D specified in \type {size}. The \type {number} is the number 227%D of the fill that needs the special treatment. For a type~2 228%D and~3 shaded fill, the datablock contains the following 229 230%D data: 231%D 232%D \starttyping 233%D from to n inner_r g b x y outer_r g b x y 234%D from to n inner_r g b x y radius outer_r g b x y radius 235%D \stoptyping 236 237\newconditional\manyMPspecials \settrue\manyMPspecials 238 239%D In case of \PDF, we need to prepare resourcs. 240 241\newtoks\MPstartresources 242\newtoks\MPstopresources 243 244\def\startMPresources 245 {\the\MPstartresources} 246 247\def\stopMPresources 248 {\the\MPstopresources} 249 250%D Some day we may consider collecting local resources. 251 252\appendtoks 253 \glet\currentPDFresources\empty % kind of redundant 254\to \MPstartresources 255 256% \appendtoks 257% \collectPDFresources 258% \glet\currentPDFresources\collectedPDFresources 259% \to \MPstopresources 260 261\appendtoksonce 262 \the\everyPDFxform 263\to \MPstopresources 264 265%D Since colors are not subjected to transformations, we can 266%D only use colors as signal. In our case, we use a dummy colored 267%D path with a red color component of \type {0.n}, so \type 268%D {0.001} is the first path and \type {0.010} the tenth. Since 269%D \METAPOST strips trailing zeros, we have to padd the string. 270 271% \newif\ifMPcmykcolors 272% \newif\ifMPspotcolors 273 274%D Specials: 275 276% \settrue \manyMPspecials \newcount\nofMParguments \let\extraMPpathcode\empty 277% 278% \def\@@MP {@@MP} 279% \def\@@MPSK{@MPSK@} 280% 281% \def\MPspecial{\@@MPSK\@@MPSK\gMPs\nofMParguments} 282% 283% \unexpanded\def\defineMPspecial#1#2% 284% {\setvalue{\@@MPSK\@@MPSK#1}{#2}} 285 286%D Special number~1 is dedicated to \CMYK\ support. If you 287%D want to know why: look at this: 288%D 289%D \startbuffer[mp] 290%D fill fullcircle xyscaled (3cm,1cm) withcolor \MPcolor{test} ; 291%D \stopbuffer 292%D 293%D \startbuffer[cmyk] 294%D \startcombination[4*1] 295%D {\definecolor[test][c=1,y=.3,k=.3] \processMPbuffer[mp]} {c=1 y=.3 k=.3} 296%D {\definecolor[test][c=.9,y=.15] \processMPbuffer[mp]} {c=.9 y=.15} 297%D {\definecolor[test][c=.25,y=.8] \processMPbuffer[mp]} {c=.25 y=.8} 298%D {\definecolor[test][c=.45,y=.1] \processMPbuffer[mp]} {c=.45 y=.1} 299%D \stopcombination 300%D \stopbuffer 301%D 302%D \placefigure 303%D {\CMYK\ support disabled, 304%D conversion to \RGB.} 305%D {\setupcolors[cmyk=nee,state=start]\getbuffer[cmyk]} 306%D 307%D \placefigure 308%D {\CMYK\ support enabled, 309%D no support in \METAPOST.} 310%D {\setupcolors[cmyk=ja,mpcmyk=nee,state=start]\getbuffer[cmyk]} 311%D 312%D \placefigure 313%D {\CMYK\ support enabled, 314%D no conversion to \RGB, 315%D support in \METAPOST} 316%D {\setupcolors[cmyk=ja,state=start]\getbuffer[cmyk]} 317 318% \let\revokeMPtransparencyspecial\relax 319 320%D Transparency support used specials 60 (rgb) and 61 321%D (cmyk). 322%D 323%D \startbuffer 324%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0); 325%D 326%D fill p rotated 90 withcolor transparent(1,.5,yellow) ; 327%D fill p rotated 210 withcolor transparent(1,.5,green) ; 328%D fill p rotated 330 withcolor transparent(1,.5,blue) ; 329%D \stopbuffer 330%D 331%D \typebuffer 332%D 333%D \startlinecorrection \processMPbuffer \stoplinecorrection 334%D 335%D One can also communicate colors between \CONTEXT\ and 336%D \METAPOST: 337%D 338%D \startbuffer 339%D \definecolor[tcyan] [c=1,k=.2,t=.5] 340%D \definecolor[tmagenta][m=1,k=.2,t=.5] 341%D \definecolor[tyellow] [y=1,k=.2,t=.5] 342%D \stopbuffer 343%D 344%D \typebuffer \getbuffer 345%D 346%D \startbuffer 347%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0); 348%D 349%D fill p rotated 90 withcolor \MPcolor{tcyan} ; 350%D fill p rotated 210 withcolor \MPcolor{tmagenta} ; 351%D fill p rotated 330 withcolor \MPcolor{tyellow} ; 352%D \stopbuffer 353%D 354%D \startlinecorrection \processMPbuffer \stoplinecorrection 355 356%D Shading is an example of a more advanced graphic feature, 357%D but users will seldom encounter those complications. Here 358%D we only show a few simple examples, but many other 359%D alternatives are possible by setting up the functions built 360%D in \PDF\ in the appropriate way. 361%D 362%D Shading has to do with interpolation between two or more 363%D points or user supplied ranges. In \PDF, the specifications 364%D of a shade has to be encapsulated in objects and passed on 365%D as resources. This is a \PDF\ level 1.3. feature. One can 366%D simulate three dimensional shades as well and define simple 367%D functions using a limited set of \POSTSCRIPT\ primitives. 368%D Given the power of \METAPOST\ and these \PDF\ features, we 369%D can achieve superb graphic effects. 370%D 371%D Since everything is hidden in \TEX\ and \METAPOST\ graphics, 372%D we can stick to high level \CONTEXT\ command, as shown in 373%D the following exmples. 374%D 375%D \startbuffer 376%D \startuniqueMPgraphic{CircularShade} 377%D path p ; p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ; 378%D circular_shade(p,0,.2red,.9red) ; 379%D \stopuniqueMPgraphic 380%D 381%D \startuniqueMPgraphic{LinearShade} 382%D path p ; p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ; 383%D linear_shade(p,0,.2blue,.9blue) ; 384%D \stopuniqueMPgraphic 385%D 386%D \startuniqueMPgraphic{DuotoneShade} 387%D path p ; p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ; 388%D linear_shade(p,2,.5green,.5red) ; 389%D \stopuniqueMPgraphic 390%D \stopbuffer 391%D 392%D \typebuffer 393%D 394%D \getbuffer 395%D 396%D These graphics can be hooked into the overlay mechanism, 397%D which is available in many commands. 398%D 399%D \startbuffer 400%D \defineoverlay[demo 1][\uniqueMPgraphic{CircularShade}] 401%D \defineoverlay[demo 2][\uniqueMPgraphic {LinearShade}] 402%D \defineoverlay[demo 3][\uniqueMPgraphic {DuotoneShade}] 403%D \stopbuffer 404%D 405%D \typebuffer 406%D 407%D \getbuffer 408%D 409%D These backgrounds can for instance be applied to \type 410%D {\framed}: 411%D 412%D \startbuffer 413%D \setupframed[width=3cm,height=2cm,frame=off] 414%D \startcombination[3*1] 415%D {\framed[backgroundachtergrond=demo 1]{\bfd \white Demo 1}} {} 416%D {\framed[backgroundachtergrond=demo 2]{\bfd \white Demo 2}} {} 417%D {\framed[backgroundachtergrond=demo 3]{\bfd \white Demo 3}} {} 418%D \stopcombination 419%D \stopbuffer 420%D 421%D \typebuffer 422%D 423%D \startlinecorrection 424%D \getbuffer 425%D \stoplinecorrection 426%D 427%D There are a few more alternatives, determined by the second 428%D parameter passed to \type {circular_shade} and alike. 429%D 430%D \def\SomeShade#1#2#3#4#5% 431%D {\startuniqueMPgraphic{Shade-#1} 432%D width := OverlayWidth ; 433%D height := OverlayHeight ; 434%D path p ; p := unitsquare xscaled width yscaled height ; 435%D #2_shade(p,#3,#4,#5) ; 436%D \stopuniqueMPgraphic 437%D \defineoverlay[Shade-#1][\uniqueMPgraphic{Shade-#1}]% 438%D \framed[backgroundachtergrond=Shade-#1,width=2cm,height=2cm,frame=off]{}} 439%D 440%D \startlinecorrection 441%D \startcombination[5*1] 442%D {\SomeShade{10}{circular}{0}{.3blue}{.9blue}} {circular 0} 443%D {\SomeShade{11}{circular}{1}{.3blue}{.9blue}} {circular 1} 444%D {\SomeShade{12}{circular}{2}{.3blue}{.9blue}} {circular 2} 445%D {\SomeShade{13}{circular}{3}{.3blue}{.9blue}} {circular 3} 446%D {\SomeShade{14}{circular}{4}{.3blue}{.9blue}} {circular 4} 447%D \stopcombination 448%D \stoplinecorrection 449%D 450%D \blank 451%D 452%D \startlinecorrection 453%D \startcombination[5*1] 454%D {\SomeShade{20}{circular}{0}{.9green}{.3green}} {circular 0} 455%D {\SomeShade{21}{circular}{1}{.9green}{.3green}} {circular 1} 456%D {\SomeShade{22}{circular}{2}{.9green}{.3green}} {circular 2} 457%D {\SomeShade{23}{circular}{3}{.9green}{.3green}} {circular 3} 458%D {\SomeShade{24}{circular}{4}{.9green}{.3green}} {circular 4} 459%D \stopcombination 460%D \stoplinecorrection 461%D 462%D \blank 463%D 464%D \startlinecorrection 465%D \startcombination[4*1] 466%D {\SomeShade{30}{linear}{0}{.3red}{.9red}} {linear 0} 467%D {\SomeShade{31}{linear}{1}{.3red}{.9red}} {linear 1} 468%D {\SomeShade{32}{linear}{2}{.3red}{.9red}} {linear 2} 469%D {\SomeShade{33}{linear}{3}{.3red}{.9red}} {linear 3} 470%D \stopcombination 471%D \stoplinecorrection 472%D 473%D These macros closely cooperate with the \METAPOST\ module 474%D \type {mp-spec.mp}, which is part of the \CONTEXT\ 475%D distribution. 476%D 477%D The low level (\PDF) implementation is based on the \TEX\ 478%D based \METAPOST\ to \PDF\ converter. Shading is supported 479%D by overloading the \type {fill} operator as implemented 480%D earlier. In \PDF\ type~2 and~3 shading functions are 481%D specified in terms of: 482%D 483%D \starttabulate[|Tl|l|] 484%D \NC /Domain \NC sort of meeting range \NC \NR 485%D \NC /C0 \NC inner shade \NC \NR 486%D \NC /C1 \NC outer shade \NC \NR 487%D \NC /N \NC smaller values, bigger inner circles \NC \NR 488%D \stoptabulate 489 490% \newcount\currentPDFshade % 0 % global (document wide) counter 491% 492% \def\dosetMPsomePDFshade#1#2% 493% {\immediate\pdfobj 494% {<</FunctionType 2 495% /Domain [\gMPs1 \gMPs2] 496% /C0 [\MPshadeA] 497% /C1 [\MPshadeB] 498% /N \gMPs3>>}% 499% \immediate\pdfobj 500% {<</ShadingType #1 501% /ColorSpace /\MPresolvedspace 502% /Function \the\pdflastobj\space 0 R 503% /Coords [\MPshadeC] 504% /Extend [true true]>>}% 505% \global\advance\currentPDFshade \plusone 506% \ctxlua{lpdf.adddocumentshade("Sh\the\currentPDFshade",lpdf.reference(\the\pdflastobj))}% 507% \setxvalue{\@@MPSK#2}{\noexpand\dohandleMPshade{\the\currentPDFshade}}} 508% 509% \def\dosetMPlinearshade {\dosetMPsomePDFshade2}% #1 510% \def\dosetMPcircularshade{\dosetMPsomePDFshade3}% #1 511% 512% \defineMPspecial{30} 513% {\normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA 514% \normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs{9}}{\gMPs{10}}{\gMPs{11}}}\to\MPshadeB 515% \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs{12} \gMPs{13}}% 516% \dosetMPlinearshade{\gMPs{14}}} 517% 518% \defineMPspecial{31} 519% {\normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA 520% \normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}}\to\MPshadeB 521% \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs9 \gMPs{13} \gMPs{14} \gMPs{15}}% 522% \dosetMPcircularshade{\gMPs{16}}} 523% 524% \defineMPspecial{32} 525% {\normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA 526% \normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB 527% \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}% 528% \dosetMPlinearshade{\gMPs{16}}} 529% 530% \defineMPspecial{33} 531% {\normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA 532% \normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB 533% \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}% 534% \dosetMPcircularshade{\gMPs{18}}} 535% 536% \defineMPspecial{34} 537% {\normalexpanded{\noexpand\resolveMPspotcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA 538% \normalexpanded{\noexpand\resolveMPspotcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB 539% \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}% 540% \dosetMPlinearshade{\gMPs{16}}} 541% 542% \defineMPspecial{35} 543% {\normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA 544% \normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB 545% \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}% 546% \dosetMPcircularshade{\gMPs{18}}} 547% 548% \newconditional\ignoreMPpath 549% 550% \def\dohandleMPshade#1% 551% {\revokeMPtransparencyspecial 552% \settrue\ignoreMPpath 553% \def\extraMPpathcode{/Sh#1 sh Q}% 554% \pdfliteral{q /Pattern cs}} 555% 556% \defineMPspecial{10} 557% {\setxvalue{\@@MPSK\gMPs8}% 558% {\noexpand\handleMPfigurespecial{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}{\gMPs8}}} 559% 560% \def\handleMPfigurespecial#1#2#3#4#5#6#7#8% todo : combine with ext fig 561% {\letgvalueempty{\@@MPSK#8}% 562% \vbox to \zeropoint 563% {\vss 564% \hbox to \zeropoint 565% {\ifcase\pdfoutput\or % will be hooked into the special driver 566% \doiffileelse{#7} 567% {\doifundefinedelse{mps:x:#7} 568% {\immediate\pdfximage\s!width\onebasepoint\s!height\onebasepoint{#7}% 569% \setxvalue{mps:x:#7}{\pdfrefximage\the\pdflastximage}}% 570% {\message{[reusing figure #7]}}% 571% \pdfliteral{q #1 #2 #3 #4 #5 #6 cm}% 572% \rlap{\getvalue{mps:x:#7}}% 573% \pdfliteral{Q}} 574% {\message{[unknown figure #7]}}% 575% \fi 576% \hss}}} 577 578%D An example of using both special features is the 579%D following. 580%D 581%D \starttyping 582%D \startMPpage 583%D externalfigure "hakker1b.png" scaled 22cm rotated 10 shifted (-2cm,0cm); 584%D externalfigure "hakker1b.png" scaled 10cm rotated -10 ; 585%D externalfigure "hakker1b.png" scaled 7cm rotated 45 shifted (8cm,12cm) ; 586%D path p ; p := unitcircle xscaled 15cm yscaled 20cm; 587%D path q ; q := p rotatedaround(center p,90) ; 588%D path r ; r := buildcycle(p,q) ; clip currentpicture to r ; 589%D path s ; s := boundingbox currentpicture enlarged 5mm ; 590%D picture c ; c := currentpicture ; currentpicture := nullpicture ; 591%D circular_shade(s,0,.2red,.9red) ; 592%D addto currentpicture also c ; 593%D \stopMPpage 594%D \stoptyping 595 596% \defineMPspecial{20} 597% {\setxvalue{\@@MPSK\gMPs6}% 598% {\noexpand\handleMPhyperlink{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}}} 599% 600% \def\handleMPhyperlink#1#2#3#4#5#6% 601% {\letgvalueempty{\@@MPSK#6}% 602% \setbox\scratchbox\hbox 603% {\setbox\scratchbox\emptyhbox 604% \wd\scratchbox\dimexpr-#1\onebasepoint+#3\onebasepoint\relax 605% \ht\scratchbox\dimexpr-#2\onebasepoint+#4\onebasepoint\relax 606% \gotobox{\box\scratchbox}[#5]}% 607% \setbox\scratchbox\hbox 608% {\hskip\dimexpr\MPxoffset\onebasepoint+#1\onebasepoint\relax 609% \raise\dimexpr\MPyoffset\onebasepoint+#2\onebasepoint\relax 610% \box\scratchbox}% 611% \smashbox\scratchbox 612% \box\scratchbox} 613 614%D This special (number 50) passes positions to a tex file. 615%D This method uses a two||pass approach an (mis|)|used the 616%D context positioning macros. In \type {core-pos} we will 617%D implement the low level submacro needed. 618%D 619%D \startbuffer 620%D \definelayer[test] 621%D 622%D \setlayer 623%D [test] 624%D [x=\MPx{somepos-1},y=\MPy{somepos-1}] 625%D {Whatever we want here!} 626%D 627%D \setlayer 628%D [test] 629%D [x=\MPx{somepos-2},y=\MPy{somepos-2}] 630%D {Whatever we need there!} 631%D 632%D \startuseMPgraphic{oeps} 633%D draw fullcircle scaled 6cm withcolor red ; 634%D register ("somepos-1",1cm,2cm,center currentpicture) ; 635%D register ("somepos-2",4cm,3cm,(-1cm,-2cm)) ; 636%D \stopuseMPgraphic 637%D 638%D \framed[background=test,offset=overlay]{\useMPgraphic{oeps}} 639%D \stopbuffer 640%D 641%D \typebuffer 642%D 643%D Here the width and height are not realy used, but one can 644%D imagine situations where tex has to work with values 645%D calculated by \METAPOST. 646%D 647%D \startlinecorrection 648%D \getbuffer 649%D \stoplinecorrection 650%D 651%D Later we will implement a more convenient macro: 652%D 653%D \starttyping 654%D \setMPlayer [test] [somepos-1] {Whatever we want here!} 655%D \setMPlayer [test] [somepos-2] {Whatever we need there!} 656%D \stoptyping 657 658 659 mp_shade_version := 2 ; 660 661 662%D This is done much cleaner in \MPLIB. 663 664\def\MPStextext#1#2#3#4#5% if we clean up this plugin model, we can 665 {\def\MPtextdata{#3}% % delegate the splitter to lua + redesign 666 \def\MPtextsize{#2}% 667 \def\lastMPmoveX{#4}% 668 \def\lastMPmoveY{#5}% 669 \defconvertedcommand\MPtextdata\MPtextdata % no edef 670 \splitstring\MPtextdata\at::::\to\MPtexttag\and\MPtextnumber 671 \executeifdefined{handleMPtext\MPtexttag} 672 {\setbox\scratchbox\hbox % text 673 {\font\temp=#1\space at #2\onebasepoint 674 \let\c\char 675 \temp 676 \MPfshowcommand{#3}}% 677 \setbox\scratchbox\hpack 678 {\hskip#4\onebasepoint 679 \raise#5\onebasepoint 680 \box\scratchbox}% 681 \smashbox\scratchbox 682 \box\scratchbox}} 683 684%D We save the special variables on a stack. It's not that 685%D fast, but it make implementing the special more convenient. 686 687% \def\MPSbegin 688% {\nofMParguments\zerocount} 689% 690% \def\MPSend 691% {\csname\MPspecial\endcsname} 692% 693% \def\MPSset 694% {\advance\nofMParguments\plusone 695% \expandafter\def\csname\@@MP\number\nofMParguments\endcsname} 696% 697% \def\gMPs#1{\csname\@@MP\number#1\endcsname} 698 699%D The boundingbox. 700 701\def\MPSboundingbox#1#2#3#4% 702 {\xdef\MPllx{#1}\xdef\MPlly{#2}\xdef\MPurx{#3}\xdef\MPury{#4}% 703 \xdef\MPwidth {\the\dimexpr#3\onebasepoint-#1\onebasepoint\relax}% 704 \xdef\MPheight{\the\dimexpr#4\onebasepoint-#2\onebasepoint\relax}} 705 706\MPSboundingbox0000 707 708% \def\MPSspecial#1#2% 709% {\csname\@@MPSK#2\endcsname} 710 711%D A path is (in most cases) just a sequence of \PDF\ commands. 712 713% \newconditional\ignoreMPpath 714 715% \def\MPSpath 716% {\pdfliteral} 717 718% \def\MPScode % hack, will be improved 719% {\ifconditional\ignoreMPpath 720% \pdfliteral{h W n}% 721% \ifx\extraMPpathcode\empty\else 722% \pdfliteral{\extraMPpathcode}% 723% \let\extraMPpathcode\empty 724% \fi 725% \setfalse\ignoreMPpath 726% \expandafter\gobbleoneargument 727% \else 728% \expandafter\pdfliteral 729% \fi} 730 731%D Test code: 732 733% \startMPcode 734% fill fullcircle scaled 3cm withcolor red ; 735% fill fullcircle scaled 2cm withcolor green ; 736% fill fullcircle scaled 1cm withcolor blue ; 737% currentpicture := currentpicture shifted (-4cm,0) ; 738% fill fullcircle scaled 3cm withcolor cmyk(0,0,1,0) ; 739% fill fullcircle scaled 2cm withcolor cmyk(0,1,0,0) ; 740% fill fullcircle scaled 1cm withcolor cmyk(0,0,1,0) ; 741% currentpicture := currentpicture shifted (-4cm,0) ; 742% draw fullcircle scaled 3cm dashed evenly ; 743% draw fullcircle scaled 2cm dashed withdots ; 744% draw origin withpen pencircle scaled 3mm; 745% currentpicture := currentpicture shifted (-4cm,0) ; 746% fill fullcircle scaled 2cm shifted (-.5cm,+.5cm) withcolor transparent(1,.5,red); 747% fill fullcircle scaled 2cm shifted (-.5cm,-.5cm) withcolor transparent(1,.5,red); 748% fill fullcircle scaled 2cm shifted (+.5cm,+.5cm) withcolor transparent(1,.5,green); 749% fill fullcircle scaled 2cm shifted (+.5cm,-.5cm) withcolor transparent(1,.5,cmyk(1,0,1,.5)); 750% currentpicture := currentpicture shifted (12cm,-4cm) ; 751% draw "o e p s" infont defaultfont scaled 2 shifted (-1cm,0) ; 752% currentpicture := currentpicture shifted (-4cm,0) ; 753% % bug: shift 754% draw fullcircle scaled 3cm withpen pencircle yscaled 3mm xscaled 2mm rotated 30 ; 755% draw fullcircle scaled 2cm withpen pencircle yscaled 3mm xscaled 2mm rotated 20 withcolor red ; 756% filldraw fullcircle scaled 1cm withpen pencircle yscaled 3mm xscaled 2mm rotated 10 withcolor green ; 757% currentpicture := currentpicture shifted (-4cm,0) ; 758% % shade cannot handle shift 759% circular_shade(fullcircle scaled 3cm,0,.2red,.9green) ; 760% circular_shade(fullcircle scaled 3cm shifted(+4cm,0),0,cmyk(1,0,0,0),cmyk(0,1,0,0)) ; 761% filldraw boundingbox currentpicture enlarged -3cm withpen pencircle scaled 1pt withcolor .5white ; 762% \stopMPcode 763 764% We cannot use attributes for switching colors in mp literals because 765% grouping (qQ) interferes. 766 767% \def\dohandleMPshade#1% 768% {\revokeMPtransparencyspecial 769% \settrue\ignoreMPpath 770% \def\extraMPpathcode{/#1 sh Q}% 771% \pdfliteral{q /Pattern cs}} 772 773\protect \endinput 774 |