meta-pdh.mkxl /size: 23 Kb    last modification: 2023-12-21 09:44
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\ifdefined\makeMPintoPDFobject    \else \newconstant\makeMPintoPDFobject    \fi
85\ifdefined\everyMPtoPDFconversion \else \newtoks    \everyMPtoPDFconversion \fi
86
87\let\lastPDFMPobject\!!zerocount
88\let\setMPextensions\relax
89
90\lettonothing\currentPDFresources
91
92\def\PDFMPformoffset{\ifdefined\objectoffset\objectoffset\else\zeropoint\fi} % no longer used
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}\ifempty\MPxscale\let\MPxscale\!!plusone\fi
102   \xdef\MPyscale   {#3}\ifempty\MPyscale\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\lettonothing\MPfshowcommand
144
145%D Objects.
146
147\def\dopackageMPgraphic#1% #1 = boxregister
148  {\ifcase\makeMPintoPDFobject\or\or\ifempty\currentPDFresources\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  {\ifdefined\everyPDFxform\expand\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\ifdefined\deleteMPgraphic \else
185  \def\deleteMPgraphic#1{}
186\fi
187
188\ifdefined\startMPresources \else
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 \manyMPspecials\conditionaltrue
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   \expand\everyPDFxform
258\to \MPstopresources
259
260%D Special number~1 is dedicated to \CMYK\ support. If you
261%D want to know why: look at this:
262%D
263%D \startbuffer[mp]
264%D   fill fullcircle xyscaled (3cm,1cm) withcolor \MPcolor{test} ;
265%D \stopbuffer
266%D
267%D \startbuffer[cmyk]
268%D \startcombination[4*1]
269%D   {\definecolor[test][c=1,y=.3,k=.3] \processMPbuffer[mp]} {c=1 y=.3 k=.3}
270%D   {\definecolor[test][c=.9,y=.15]    \processMPbuffer[mp]} {c=.9 y=.15}
271%D   {\definecolor[test][c=.25,y=.8]    \processMPbuffer[mp]} {c=.25 y=.8}
272%D   {\definecolor[test][c=.45,y=.1]    \processMPbuffer[mp]} {c=.45 y=.1}
273%D \stopcombination
274%D \stopbuffer
275%D
276%D \placefigure
277%D   {\CMYK\ support disabled,
278%D    conversion to \RGB.}
279%D   {\setupcolors[cmyk=nee,state=start]\getbuffer[cmyk]}
280%D
281%D \placefigure
282%D   {\CMYK\ support enabled,
283%D    no support in \METAPOST.}
284%D   {\setupcolors[cmyk=ja,mpcmyk=nee,state=start]\getbuffer[cmyk]}
285%D
286%D \placefigure
287%D   {\CMYK\ support enabled,
288%D    no conversion to \RGB,
289%D    support in \METAPOST}
290%D   {\setupcolors[cmyk=ja,state=start]\getbuffer[cmyk]}
291
292% \let\revokeMPtransparencyspecial\relax
293
294%D Transparency support used specials 60 (rgb) and 61
295%D (cmyk).
296%D
297%D \startbuffer
298%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
299%D
300%D fill p rotated  90 withcolor transparent(1,.5,yellow) ;
301%D fill p rotated 210 withcolor transparent(1,.5,green) ;
302%D fill p rotated 330 withcolor transparent(1,.5,blue) ;
303%D \stopbuffer
304%D
305%D \typebuffer
306%D
307%D \startlinecorrection \processMPbuffer \stoplinecorrection
308%D
309%D One can also communicate colors between \CONTEXT\ and
310%D \METAPOST:
311%D
312%D \startbuffer
313%D \definecolor[tcyan]   [c=1,k=.2,t=.5]
314%D \definecolor[tmagenta][m=1,k=.2,t=.5]
315%D \definecolor[tyellow] [y=1,k=.2,t=.5]
316%D \stopbuffer
317%D
318%D \typebuffer \getbuffer
319%D
320%D \startbuffer
321%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
322%D
323%D fill p rotated  90 withcolor \MPcolor{tcyan} ;
324%D fill p rotated 210 withcolor \MPcolor{tmagenta} ;
325%D fill p rotated 330 withcolor \MPcolor{tyellow} ;
326%D \stopbuffer
327%D
328%D \startlinecorrection \processMPbuffer \stoplinecorrection
329
330%D Shading is an example of a more advanced graphic feature,
331%D but users will seldom encounter those complications. Here
332%D we only show a few simple examples, but many other
333%D alternatives are possible by setting up the functions built
334%D in \PDF\ in the appropriate way.
335%D
336%D Shading has to do with interpolation between two or more
337%D points or user supplied ranges. In \PDF, the specifications
338%D of a shade has to be encapsulated in objects and passed on
339%D as resources. This is a \PDF\ level 1.3. feature. One can
340%D simulate three dimensional shades as well and define simple
341%D functions using a limited set of \POSTSCRIPT\ primitives.
342%D Given the power of \METAPOST\ and these \PDF\ features, we
343%D can achieve superb graphic effects.
344%D
345%D Since everything is hidden in \TEX\ and \METAPOST\ graphics,
346%D we can stick to high level \CONTEXT\ command, as shown in
347%D the following exmples.
348%D
349%D \startbuffer
350%D \startuniqueMPgraphic{CircularShade}
351%D   path  p ; p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ;
352%D   circular_shade(p,0,.2red,.9red) ;
353%D \stopuniqueMPgraphic
354%D
355%D \startuniqueMPgraphic{LinearShade}
356%D   path  p ; p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ;
357%D   linear_shade(p,0,.2blue,.9blue) ;
358%D \stopuniqueMPgraphic
359%D
360%D \startuniqueMPgraphic{DuotoneShade}
361%D   path  p ; p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ;
362%D   linear_shade(p,2,.5green,.5red) ;
363%D \stopuniqueMPgraphic
364%D \stopbuffer
365%D
366%D \typebuffer
367%D
368%D \getbuffer
369%D
370%D These graphics can be hooked into the overlay mechanism,
371%D which is available in many commands.
372%D
373%D \startbuffer
374%D \defineoverlay[demo 1][\uniqueMPgraphic{CircularShade}]
375%D \defineoverlay[demo 2][\uniqueMPgraphic  {LinearShade}]
376%D \defineoverlay[demo 3][\uniqueMPgraphic {DuotoneShade}]
377%D \stopbuffer
378%D
379%D \typebuffer
380%D
381%D \getbuffer
382%D
383%D These backgrounds can for instance be applied to \type
384%D {\framed}:
385%D
386%D \startbuffer
387%D \setupframed[width=3cm,height=2cm,frame=off]
388%D \startcombination[3*1]
389%D   {\framed[backgroundachtergrond=demo 1]{\bfd \white Demo 1}} {}
390%D   {\framed[backgroundachtergrond=demo 2]{\bfd \white Demo 2}} {}
391%D   {\framed[backgroundachtergrond=demo 3]{\bfd \white Demo 3}} {}
392%D \stopcombination
393%D \stopbuffer
394%D
395%D \typebuffer
396%D
397%D \startlinecorrection
398%D \getbuffer
399%D \stoplinecorrection
400%D
401%D There are a few more alternatives, determined by the second
402%D parameter passed to \type {circular_shade} and alike.
403%D
404%D \def\SomeShade#1#2#3#4#5%
405%D   {\startuniqueMPgraphic{Shade-#1}
406%D      width := OverlayWidth ;
407%D      height := OverlayHeight ;
408%D      path p ; p := unitsquare xscaled width yscaled height ;
409%D      #2_shade(p,#3,#4,#5) ;
410%D    \stopuniqueMPgraphic
411%D    \defineoverlay[Shade-#1][\uniqueMPgraphic{Shade-#1}]%
412%D    \framed[backgroundachtergrond=Shade-#1,width=2cm,height=2cm,frame=off]{}}
413%D
414%D \startlinecorrection
415%D \startcombination[5*1]
416%D   {\SomeShade{10}{circular}{0}{.3blue}{.9blue}} {circular 0}
417%D   {\SomeShade{11}{circular}{1}{.3blue}{.9blue}} {circular 1}
418%D   {\SomeShade{12}{circular}{2}{.3blue}{.9blue}} {circular 2}
419%D   {\SomeShade{13}{circular}{3}{.3blue}{.9blue}} {circular 3}
420%D   {\SomeShade{14}{circular}{4}{.3blue}{.9blue}} {circular 4}
421%D \stopcombination
422%D \stoplinecorrection
423%D
424%D \blank
425%D
426%D \startlinecorrection
427%D \startcombination[5*1]
428%D   {\SomeShade{20}{circular}{0}{.9green}{.3green}} {circular 0}
429%D   {\SomeShade{21}{circular}{1}{.9green}{.3green}} {circular 1}
430%D   {\SomeShade{22}{circular}{2}{.9green}{.3green}} {circular 2}
431%D   {\SomeShade{23}{circular}{3}{.9green}{.3green}} {circular 3}
432%D   {\SomeShade{24}{circular}{4}{.9green}{.3green}} {circular 4}
433%D \stopcombination
434%D \stoplinecorrection
435%D
436%D \blank
437%D
438%D \startlinecorrection
439%D \startcombination[4*1]
440%D   {\SomeShade{30}{linear}{0}{.3red}{.9red}} {linear 0}
441%D   {\SomeShade{31}{linear}{1}{.3red}{.9red}} {linear 1}
442%D   {\SomeShade{32}{linear}{2}{.3red}{.9red}} {linear 2}
443%D   {\SomeShade{33}{linear}{3}{.3red}{.9red}} {linear 3}
444%D \stopcombination
445%D \stoplinecorrection
446%D
447%D These macros closely cooperate with the \METAPOST\ module
448%D \type {mp-spec.mp}, which is part of the \CONTEXT\
449%D distribution.
450%D
451%D The low level (\PDF) implementation is based on the \TEX\
452%D based \METAPOST\ to \PDF\ converter. Shading is supported
453%D by overloading the \type {fill} operator as implemented
454%D earlier. In \PDF\ type~2 and~3 shading functions are
455%D specified in terms of:
456%D
457%D \starttabulate[|Tl|l|]
458%D \NC /Domain \NC sort of meeting range \NC \NR
459%D \NC /C0     \NC inner shade \NC \NR
460%D \NC /C1     \NC outer shade \NC \NR
461%D \NC /N      \NC smaller values, bigger inner circles \NC \NR
462%D \stoptabulate
463
464% \newinteger\currentPDFshade  % 0  % global (document wide) counter
465%
466% \def\dosetMPsomePDFshade#1#2%
467%   {\immediate\pdfobj
468%      {<</FunctionType 2
469%         /Domain [\gMPs1 \gMPs2]
470%         /C0 [\MPshadeA]
471%         /C1 [\MPshadeB]
472%         /N \gMPs3>>}%
473%    \immediate\pdfobj
474%      {<</ShadingType #1
475%         /ColorSpace /\MPresolvedspace
476%         /Function \the\pdflastobj\space 0 R
477%         /Coords [\MPshadeC]
478%         /Extend [true true]>>}%
479%    \global\advanceby\currentPDFshade \plusone
480%    \ctxlua{lpdf.adddocumentshade("Sh\the\currentPDFshade",lpdf.reference(\the\pdflastobj))}%
481%    \setxvalue{\@@MPSK#2}{\noexpand\dohandleMPshade{\the\currentPDFshade}}}
482%
483% \def\dosetMPlinearshade  {\dosetMPsomePDFshade2}% #1
484% \def\dosetMPcircularshade{\dosetMPsomePDFshade3}% #1
485%
486% \defineMPspecial{30}
487%   {\normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA
488%    \normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs{9}}{\gMPs{10}}{\gMPs{11}}}\to\MPshadeB
489%    \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs{12} \gMPs{13}}%
490%    \dosetMPlinearshade{\gMPs{14}}}
491%
492% \defineMPspecial{31}
493%   {\normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA
494%    \normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}}\to\MPshadeB
495%    \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs9 \gMPs{13} \gMPs{14} \gMPs{15}}%
496%    \dosetMPcircularshade{\gMPs{16}}}
497%
498% \defineMPspecial{32}
499%   {\normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
500%    \normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB
501%    \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}%
502%    \dosetMPlinearshade{\gMPs{16}}}
503%
504% \defineMPspecial{33}
505%   {\normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
506%    \normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB
507%    \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}%
508%    \dosetMPcircularshade{\gMPs{18}}}
509%
510% \defineMPspecial{34}
511%   {\normalexpanded{\noexpand\resolveMPspotcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
512%    \normalexpanded{\noexpand\resolveMPspotcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB
513%    \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}%
514%    \dosetMPlinearshade{\gMPs{16}}}
515%
516% \defineMPspecial{35}
517%   {\normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
518%    \normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB
519%    \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}%
520%    \dosetMPcircularshade{\gMPs{18}}}
521%
522% \newconditional\ignoreMPpath
523%
524% \def\dohandleMPshade#1%
525%   {\revokeMPtransparencyspecial
526%    \ignoreMPpath\conditionaltrue
527%    \def\extraMPpathcode{/Sh#1 sh Q}%
528%    \pdfliteral{q /Pattern cs}}
529%
530% \defineMPspecial{10}
531%   {\setxvalue{\@@MPSK\gMPs8}%
532%      {\noexpand\handleMPfigurespecial{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}{\gMPs8}}}
533%
534% \def\handleMPfigurespecial#1#2#3#4#5#6#7#8% todo : combine with ext fig
535%   {\letgvalueempty{\@@MPSK#8}%
536%    \vbox to \zeropoint
537%      {\vss
538%       \hbox to \zeropoint
539%         {\ifcase\pdfoutput\or % will be hooked into the special driver
540%            \doiffileelse{#7}
541%              {\doifundefinedelse{mps:x:#7}
542%                 {\immediate\pdfximage\s!width\onebasepoint\s!height\onebasepoint{#7}%
543%                  \setxvalue{mps:x:#7}{\pdfrefximage\the\pdflastximage}}%
544%                 {\message{[reusing figure #7]}}%
545%               \pdfliteral{q #1 #2 #3 #4 #5 #6 cm}%
546%               \rlap{\getvalue{mps:x:#7}}%
547%               \pdfliteral{Q}}
548%              {\message{[unknown figure #7]}}%
549%          \fi
550%          \hss}}}
551
552%D An example of using both special features is the
553%D following.
554%D
555%D \starttyping
556%D \startMPpage
557%D   externalfigure "hakker1b.png" scaled 22cm rotated  10 shifted (-2cm,0cm);
558%D   externalfigure "hakker1b.png" scaled 10cm rotated -10 ;
559%D   externalfigure "hakker1b.png" scaled  7cm rotated  45 shifted (8cm,12cm) ;
560%D   path p ; p := unitcircle xscaled 15cm yscaled 20cm;
561%D   path q ; q := p rotatedaround(center p,90) ;
562%D   path r ; r := buildcycle(p,q) ; clip currentpicture to r ;
563%D   path s ; s := boundingbox currentpicture enlarged 5mm ;
564%D   picture c ; c := currentpicture ; currentpicture := nullpicture ;
565%D   circular_shade(s,0,.2red,.9red) ;
566%D   addto currentpicture also c ;
567%D \stopMPpage
568%D \stoptyping
569
570% \defineMPspecial{20}
571%   {\setxvalue{\@@MPSK\gMPs6}%
572%      {\noexpand\handleMPhyperlink{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}}}
573%
574% \def\handleMPhyperlink#1#2#3#4#5#6%
575%   {\letgvalueempty{\@@MPSK#6}%
576%    \setbox\scratchbox\hbox
577%      {\setbox\scratchbox\emptyhbox
578%       \wd\scratchbox\dimexpr-#1\onebasepoint+#3\onebasepoint\relax
579%       \ht\scratchbox\dimexpr-#2\onebasepoint+#4\onebasepoint\relax
580%       \gotobox{\box\scratchbox}[#5]}%
581%    \setbox\scratchbox\hbox
582%      {\hskip\dimexpr\MPxoffset\onebasepoint+#1\onebasepoint\relax
583%       \raise\dimexpr\MPyoffset\onebasepoint+#2\onebasepoint\relax
584%       \box\scratchbox}%
585%    \smashbox\scratchbox
586%    \box\scratchbox}
587
588%D This special (number 50) passes positions to a tex file.
589%D This method uses a two||pass approach an (mis|)|used the
590%D context positioning macros. In \type {core-pos} we will
591%D implement the low level submacro needed.
592%D
593%D \startbuffer
594%D \definelayer[test]
595%D
596%D \setlayer
597%D   [test]
598%D   [x=\MPx{somepos-1},y=\MPy{somepos-1}]
599%D   {Whatever we want here!}
600%D
601%D \setlayer
602%D   [test]
603%D   [x=\MPx{somepos-2},y=\MPy{somepos-2}]
604%D   {Whatever we need there!}
605%D
606%D \startuseMPgraphic{oeps}
607%D   draw fullcircle scaled 6cm withcolor red ;
608%D   register ("somepos-1",1cm,2cm,center currentpicture) ;
609%D   register ("somepos-2",4cm,3cm,(-1cm,-2cm)) ;
610%D \stopuseMPgraphic
611%D
612%D \framed[background=test,offset=overlay]{\useMPgraphic{oeps}}
613%D \stopbuffer
614%D
615%D \typebuffer
616%D
617%D Here the width and height are not realy used, but one can
618%D imagine situations where tex has to work with values
619%D calculated by \METAPOST.
620%D
621%D \startlinecorrection
622%D \getbuffer
623%D \stoplinecorrection
624%D
625%D Later we will implement a more convenient macro:
626%D
627%D \starttyping
628%D \setMPlayer [test] [somepos-1] {Whatever we want here!}
629%D \setMPlayer [test] [somepos-2] {Whatever we need there!}
630%D \stoptyping
631
632\startMPinitializations
633  mp_shade_version := 2 ;
634\stopMPinitializations
635
636%D This is done much cleaner in \MPLIB.
637
638\def\MPStextext#1#2#3#4#5% if we clean up this plugin model, we can
639  {\def\MPtextdata{#3}%  % delegate the splitter to lua + redesign
640   \def\MPtextsize{#2}%
641   \def\lastMPmoveX{#4}%
642   \def\lastMPmoveY{#5}%
643   \defconvertedcommand\MPtextdata\MPtextdata % no edef
644   \splitstring\MPtextdata\at::::\to\MPtexttag\and\MPtextnumber
645   \executeifdefined{handleMPtext\MPtexttag}
646     {\setbox\scratchbox\hbox % text
647        {\font\temp=#1\space at #2\onebasepoint
648         \let\c\char
649         \temp
650         \MPfshowcommand{#3}}%
651      \setbox\scratchbox\hpack
652        {\hskip#4\onebasepoint
653         \raise#5\onebasepoint
654         \box\scratchbox}%
655      \smashbox\scratchbox
656      \box\scratchbox}}
657
658We save the special variables on a stack. It's not that fast, but it make
659implementing the special more convenient.
660
661%D The boundingbox.
662
663\def\MPSboundingbox#1#2#3#4%
664  {\xdef\MPllx   {#1}\xdef\MPlly{#2}\xdef\MPurx{#3}\xdef\MPury{#4}%
665   \xdef\MPwidth {\the\dimexpr#3\onebasepoint-#1\onebasepoint\relax}%
666   \xdef\MPheight{\the\dimexpr#4\onebasepoint-#2\onebasepoint\relax}}
667
668\MPSboundingbox0000
669
670%D Test code:
671
672% \startMPcode
673%     fill fullcircle scaled 3cm withcolor red ;
674%     fill fullcircle scaled 2cm withcolor green ;
675%     fill fullcircle scaled 1cm withcolor blue ;
676%     currentpicture := currentpicture shifted (-4cm,0) ;
677%     fill fullcircle scaled 3cm withcolor cmyk(0,0,1,0) ;
678%     fill fullcircle scaled 2cm withcolor cmyk(0,1,0,0) ;
679%     fill fullcircle scaled 1cm withcolor cmyk(0,0,1,0) ;
680%     currentpicture := currentpicture shifted (-4cm,0) ;
681%     draw fullcircle scaled 3cm dashed evenly ;
682%     draw fullcircle scaled 2cm dashed withdots  ;
683%     draw origin withpen pencircle scaled 3mm;
684%     currentpicture := currentpicture shifted (-4cm,0) ;
685%     fill fullcircle scaled 2cm shifted (-.5cm,+.5cm) withcolor transparent(1,.5,red);
686%     fill fullcircle scaled 2cm shifted (-.5cm,-.5cm) withcolor transparent(1,.5,red);
687%     fill fullcircle scaled 2cm shifted (+.5cm,+.5cm) withcolor transparent(1,.5,green);
688%     fill fullcircle scaled 2cm shifted (+.5cm,-.5cm) withcolor transparent(1,.5,cmyk(1,0,1,.5));
689%     currentpicture := currentpicture shifted (12cm,-4cm) ;
690%     draw "o e p s" infont defaultfont scaled 2 shifted (-1cm,0) ;
691%     currentpicture := currentpicture shifted (-4cm,0) ;
692%     % bug: shift
693%     draw fullcircle scaled 3cm withpen pencircle yscaled 3mm xscaled 2mm rotated 30  ;
694%     draw fullcircle scaled 2cm withpen pencircle yscaled 3mm xscaled 2mm rotated 20 withcolor red ;
695%     filldraw fullcircle scaled 1cm withpen pencircle yscaled 3mm xscaled 2mm rotated 10 withcolor green ;
696%     currentpicture := currentpicture shifted (-4cm,0) ;
697%     % shade cannot handle shift
698%     circular_shade(fullcircle scaled 3cm,0,.2red,.9green) ;
699%     circular_shade(fullcircle scaled 3cm shifted(+4cm,0),0,cmyk(1,0,0,0),cmyk(0,1,0,0)) ;
700%     filldraw boundingbox currentpicture enlarged -3cm withpen pencircle scaled 1pt withcolor .5white ;
701% \stopMPcode
702
703% We cannot use attributes for switching colors in mp literals because
704% grouping (qQ) interferes.
705
706% \def\dohandleMPshade#1%
707%   {\revokeMPtransparencyspecial
708%    \ignoreMPpath\conditionaltrue
709%    \def\extraMPpathcode{/#1 sh Q}%
710%    \pdfliteral{q /Pattern cs}}
711
712\protect \endinput
713