meta-pdh.mkiv /size: 25 Kb    last modification: 2020-07-01 14:35
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        \ctxlua{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\startMPinitializations
659  mp_shade_version := 2 ;
660\stopMPinitializations
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