diff options
Diffstat (limited to 'tex/context/base/meta-pdf.tex')
-rw-r--r-- | tex/context/base/meta-pdf.tex | 3123 |
1 files changed, 357 insertions, 2766 deletions
diff --git a/tex/context/base/meta-pdf.tex b/tex/context/base/meta-pdf.tex index bddf932ef..ad4a57fd9 100644 --- a/tex/context/base/meta-pdf.tex +++ b/tex/context/base/meta-pdf.tex @@ -11,32 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -%D In due time this file will replace \type {supp-pdf} and -%D \type {supp-mpe}. - -% \input supp-pdf -% \input supp-mpe -% -% \endinput - -% we're going to experiment a bit with new code - -%D To be tested: texopt.rb on this file. - -%D Prelude to an optimized version: - -%D \module -%D [ file=supp-pdf, -%D version=2004.12.16, -%D title=\CONTEXT\ Support Macros, -%D subtitle=\METAPOST\ to \PDF\ conversion, -%D author=Hans Hagen \& others (see text), -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. +%D Formerly known as supp-pdf.tex and supp-mpe.tex. %D These macros are written as generic as possible. Some %D general support macro's are loaded from a small module @@ -52,10 +27,10 @@ %D his initials. (We keep the old code around because it's a %D nice illustration on how a module like this evolves.) -% Beware, we cannot use \zeropoint here since it may be +% Beware, we cannot use 0pt here by defaukt since it may be % defined in the range \dimen 0 - 20 which we happen to use -% as scratch registers; inside context we may consider -% using dedicated registers. +% as scratch registers; for this reason we start allocating +% scratch registers > 20 %D This module handles some \PDF\ conversion and insertions %D topics. By default, the macros use the \PDFTEX\ primitive @@ -63,23 +38,12 @@ %D default engine for \TEX\ distributions, we need a more complex %D test. -\writestatus{loading}{Context Support Macros / PDF (2004.03.26)} +\writestatus{loading}{Context Support Macros / MPS to PDF} \unprotect -\ifx\PDFcode\undefined - \ifx\pdfliteral\undefined - \def\PDFcode#1{\special{PDF: #1}} - \else\ifx\pdfoutput\undefined - \def\PDFcode#1{\special{PDF: #1}} - \else\ifcase\pdfoutput - \def\PDFcode#1{\special{PDF: #1}} - \else % pdftex as well as in pdf mode - \let\PDFcode\pdfliteral - \fi\fi\fi -\else - % we probably use context -\fi +\ifx\PDFcode \undefined \let\PDFcode \gobbleoneargument \fi +\ifx\PDFcomment\undefined \def\PDFcomment#1{\PDFcode{\letterpercent\space#1}} \fi %D First we define a handy constant: @@ -122,11 +86,8 @@ \def\dopdfimages#1#2#3% {\immediate\pdfximage#1{#2}% - \immediate\pdfobj - {[ << /Image \the\pdflastximage\space0 R - /DefaultForPrinting true >> ]}% - \immediate\pdfximage#1 - attr {/Alternates \the\pdflastobj\space0 R}{#3}% + \immediate\pdfobj{[ << /Image \the\pdflastximage\space0 R /DefaultForPrinting true >> ]}% + \immediate\pdfximage#1 attr {/Alternates \the\pdflastobj\space0 R}{#3}% \pdfrefximage\pdflastximage} \def\pdfclippedimage#1#% specs {file}{left}{right}{top}{bottom} @@ -135,14 +96,9 @@ \def\dopdfclippedimage#1#2#3#4#5#6% {\bgroup \pdfximage#1{#2}% - \setbox\scratchbox\hbox - {\pdfrefximage\pdflastximage}% - \hsize\wd\scratchbox - \advance\hsize -#3% - \advance\hsize -#4% - \vsize\ht\scratchbox - \advance\vsize -#5% - \advance\vsize -#6% + \setbox\scratchbox\hbox{\pdfrefximage\pdflastximage}% + \hsize\dimexpr\wd\scratchbox-#3-#4\relax + \vsize\dimexpr\ht\scratchbox-#5-#6\relax \setbox\scratchbox\vbox to \vsize {\vskip-#5\hbox to \hsize{\hskip-#3\box\scratchbox\hss}}% \pdfxform\scratchbox @@ -151,1635 +107,11 @@ \fi \fi -%D If you want to save a few hash entries, you may prefer the -%D less readable alternatives, like: -%D -%D \starttyping -%D \def\pdfimage#1#% This one is less readable but needs no additional -%D {\bgroup % hash entry for the second stage macro. -%D \def\pdfimage##1% -%D {\immediate\pdfximage##1{#2}% -%D \pdfrefximage\pdflastximage\egroup}} -%D \stoptyping - %D \macros %D {convertMPtoPDF} %D %D The next set of macros implements \METAPOST\ to \PDF\ -%D conversion. Because we want to test as fast as possible, we -%D first define the \POSTSCRIPT\ operators that \METAPOST\ -%D uses. We don't define irrelevant ones, because these are -%D skipped anyway. - -%D The converter can be made a bit faster by replacing the -%D two test macros (the ones with the many \type {\if's}) by -%D a call to named branch macros (something \typ {\getvalue -%D {xPSmoveto}}. For everyday documents with relatively -%D small graphics the gain in speed can be neglected. - -\def \PScurveto {curveto} -\def \PSlineto {lineto} -\def \PSmoveto {moveto} -\def \PSshowpage {showpage} -\def \PSnewpath {newpath} -\def \PSfshow {fshow} -\def \PSclosepath {closepath} -\def \PSfill {fill} -\def \PSstroke {stroke} -\def \PSclip {clip} -\def \PSrlineto {rlineto} -\def \PSsetlinejoin {setlinejoin} -\def \PSsetlinecap {setlinecap} -\def \PSsetmiterlimit {setmiterlimit} -\def \PSsetgray {setgray} -\def \PSsetrgbcolor {setrgbcolor} -\def \PSsetcmykcolor {setcmykcolor} -\def \PSsetdash {setdash} -\def \PSgsave {gsave} -\def \PSgrestore {grestore} -\def \PStranslate {translate} -\def \PSscale {scale} -\def \PSconcat {concat} -\def \PSdtransform {dtransform} -\def \PSsetlinewidth {setlinewidth} -\def \PSpop {pop} - -\def \PSnfont {nfont} % was needed for TUG98 proceedings -\def \PSspecial {special} % extensions to MetaPost - -%D A previous version set \type {%} to ignore, which -%D simplified the following definitions. At the start of -%D conversion the percent character was made active again. -%D Because the whole graphic is one paragraph (there are no -%D empty lines) this does not give the desired effect. This -%D went unnoticed untill Scott Pakin sent me a test file -%D percent characters in a string. So, from now on we have -%D to prefix the following strings with percentages. - -%D Some day I'll figure out a better solution (line by line reading -%D using \ETEX). - -\edef \PSBoundingBox {\letterpercent\letterpercent BoundingBox:} -\edef \PSHiResBoundingBox {\letterpercent\letterpercent HiResBoundingBox:} -\edef \PSExactBoundingBox {\letterpercent\letterpercent ExactBoundingBox:} -\edef \PSMetaPostSpecial {\letterpercent\letterpercent MetaPostSpecial:} -\edef \PSMetaPostSpecials {\letterpercent\letterpercent MetaPostSpecials:} -\edef \PSPage {\letterpercent\letterpercent Page:} - -%D By the way, the \type {setcmykcolor} operator is not -%D output by \METAPOST\ but can result from converting the -%D \cap{RGB} color specifications, as implemented in -%D \type{supp-mps}. - -%D In \POSTSCRIPT\ arguments precede the operators. Due to the -%D fact that in some translations we need access to those -%D arguments, and also because sometimes we have to skip them, -%D we stack them up. The stack is one||dimensional for non path -%D operators and two||dimensional for operators inside a path. -%D This is because we have to save the whole path for -%D (optional) postprocessing. Values are pushed onto the stack -%D by: -%D -%D \starttyping -%D \setMPargument {value} -%D \stoptyping -%D -%D They can be retrieved by the short named macros: -%D -%D \starttyping -%D \gMPa {number} -%D \gMPs {number} -%D \stoptyping -%D -%D When scanning a path specification, we also save the -%D operator, using -%D -%D \starttyping -%D \setMPkeyword {n} -%D \stoptyping -%D -%D The path drawing operators are coded for speed: \type{clip}, -%D \type{stroke}, \type{fill} and \type{fillstroke} become -%D 1, 2, 3 and~4. -%D -%D When processing the path this code can be retrieved -%D using -%D -%D \starttyping -%D \getMPkeyword % {n} -%D \stoptyping -%D -%D When setting an argument, the exact position on the stack -%D depends on the current value of the \COUNTERS\ -%D \type{\nofMPsegments} and \type{\nofMParguments}. - -\newcount\nofMPsegments -\newcount\nofMParguments - -%D These variables hold the coordinates. The argument part of -%D the stack is reset by: -%D -%D \starttyping -%D \resetMPstack -%D \stoptyping -%D -%D We use the prefix \type{@@MP} to keep the stack from -%D conflicting with existing macros. To speed up things a bit -%D more, we use the constant \type{\@@MP}. - -\def\@@MP{@@MP} - -\def\setMPargument% #1% - {\advance\nofMParguments \plusone - \expandafter\def - \csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname} % {#1} - -\def\letMPargument - {\advance\nofMParguments \plusone - \expandafter\let - \csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname} - -\def\setMPsequence#1 % - {\advance\nofMParguments \plusone - \expandafter\def - \csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname{#1}% - \handleMPsequence} - -\def\gMPa#1% - {\csname\@@MP0\number#1\endcsname} - -\def\gMPs#1% - {\csname\@@MP\the\nofMPsegments\number#1\endcsname} - -\def\dogMPa#1% - {\@EAEAEA\do\csname\@@MP0\number#1\endcsname} - -\def\setMPkeyword#1 % - {\expandafter\def\csname\@@MP\the\nofMPsegments0\endcsname{#1}% - \advance\nofMPsegments \plusone - \nofMParguments\zerocount} - -\def\getMPkeyword% #1% - {\csname\@@MP\the\nofMPsegments0\endcsname} % {\csname\@@MP#10\endcsname} - -\def\docleanupMPargument#1% we need this because args can have [ or ] pre/appended - {\expandafter\edef\csname\@@MP\the\nofMPsegments\number#1\endcsname - {\csname\@@MP\the\nofMPsegments\number#1\endcsname}} - -%D When we reset the stack, we can assume that all further -%D comment is to be ignored and handled in strings. -%D By redefining the reset macro after the first call, we -%D save some run time. Only use this macro after all -%D comments are processed and use the simple alternative -%D when dealing with comments. - -\def\doresetMPstack - {\nofMParguments\zerocount} - -\def\resetMPstack - {\let\handleMPgraphic\handleMPendgraphic - \let\resetMPstack\doresetMPstack - \resetMPstack} - -%D The arguments are saved with the preceding command -%D \type{\do}. By default this command expands to nothing, but -%D when we deal with strings it's used to strip off the -%D \type{(} and \type{)}. -%D -%D Strings are kind of tricky, because characters can be -%D passed verbatim \type{(hello)}, by octal number -%D \type{(\005)} or as command \type{(\()}. We therefore -%D cannot simply ignore \type{(} and \type{)}, the way we do -%D with \type{[} and \type{]}. Another complication is that -%D strings may contain characters that normally have a -%D special meaning in \TEX, like \type{$} and \type{{}}. -%D -%D A previous solution made \type{\} an active character and -%D let it look ahead for a number or characters. We had to -%D abandon this scheme because of the need for verbatim -%D support. The next solution involved some \CATCODE\ -%D trickery but works well. - -\def\octalMPcharacter#1#2#3% - {\char'#1#2#3\relax} - -%D curly braces and squarly brackets are stored in the argument stack -%D as part of strings, for instance in: -%D -%D \starttyping -%D /fshow {exch findfont exch scalefont setfont show}bind def -%D [3 3 ] 0 setdash -%D \stoptyping -%D -%D but we need to keep them in situation like -%D -%D \starttyping -%D ([bla bla] bla bla) ec-lmr10 9.96265 fshow -%D ({bla bla} bla bla) ec-lmr10 9.96265 fshow -%D \stoptyping -%D -%D So, when we store the snippets, we keep the special tokens, and -%D when needed we either ignore or obey them - -\bgroup -\catcode`\|=\@@comment -\catcode`\%=\@@active -\catcode`\[=\@@active -\catcode`\]=\@@active -\catcode`\{=\@@active -\catcode`\}=\@@active -\catcode`B=\@@begingroup -\catcode`E=\@@endgroup -\gdef\keepMPspecials| - B\let%\letterpercent| - \def[B\noexpand[E| - \def]B\noexpand]E| - \def{B\noexpand{E| - \def}B\noexpand}EE -\gdef\ignoreMPspecials| - B\let%\letterpercent| - \def[BE| - \def]BE| - \def{BE| - \def}BEE -\gdef\obeyMPspecials| - B\def%B\char 37\relax E| - \def[B\char 91\relax E| - \def]B\char 93\relax E| - \def{B\char123\relax E| - \def}B\char125\relax EE -\gdef\setMPspecials| - B\setnaturalcatcodes - \catcode`\\=\@@escape - \catcode`\%=\@@active - \catcode`\[=\@@active - \catcode`\]=\@@active - \catcode`\{=\@@active - \catcode`\}=\@@active - \lccode`\-=0 | latex sets this to `\- - \lccode`\%=`\% | otherwise it's seen as a number - \def\(B\char40\relax E| - \def\)B\char41\relax E| - \def\\B\char92\relax E| - \def\0B\octalMPcharacter0E| - \def\1B\octalMPcharacter1E| - \def\2B\octalMPcharacter2E| - \def\3B\octalMPcharacter3E| - \def\4B\octalMPcharacter4E| - \def\5B\octalMPcharacter5E| - \def\6B\octalMPcharacter6E| - \def\7B\octalMPcharacter7E| - \def\8B\octalMPcharacter8E| - \def\9B\octalMPcharacter9EE -\egroup - -%D We use the comment symbol as a sort of trigger. Beware! -%D The whole graphic is seen as on eparagraph, which means -%D that we cannot change the catcodes in between. - -\bgroup -\catcode`\%=\@@active -\gdef\startMPscanning{\let%=\startMPconversion} -\egroup - -%D In earlier versions we used the sequence -%D -%D \starttyping -%D \expandafter\handleMPsequence\input filename\relax -%D \stoptyping -%D -%D Persistent problems in \LATEX\ however forced us to use a -%D different scheme. Every \POSTSCRIPT\ file starts with a -%D \type{%}, so we temporary make this an active character -%D that starts the scanning and redefines itself. (The problem -%D originates in the redefinition by \LATEX\ of the -%D \type{\input} primitive.) - -\def\startMPconversion - {\keepMPspecials - \handleMPsequence} - -%D Here comes the main loop. Most arguments are numbers. This -%D means that they can be recognized by their \type{\lccode}. -%D This method saves a lot of processing time. We could -%D speed up the conversion by handling the \type{path} -%D seperately. - -\def\@EAEAEA{\expandafter\expandafter\expandafter} % to be sure - -\def\dohandleMPsequence#1% - {\ifdone - \ifcase\lccode`#1\relax - \@EAEAEA\dohandleMPsequenceA - \else - \@EAEAEA\dohandleMPsequenceB - \fi - \else - \@EA\dohandleMPsequenceC - \fi#1} - -\let\dohandleMPsequenceA\setMPsequence - -\def\dohandleMPsequenceB#1 % - {\edef\somestring{#1}% - \ifx\somestring\PSmoveto - \edef\lastMPmoveX{\gMPa1}% - \edef\lastMPmoveY{\gMPa2}% - \PDFcode{\!MPgMPa1 \!MPgMPa2 m}% - \resetMPstack - \else\ifx\somestring\PSnewpath - \let\handleMPsequence\handleMPpath - \else\ifx\somestring\PSgsave - \PDFcode{q}% - \resetMPstack - \else\ifx\somestring\PSgrestore - \PDFcode{Q}% - \resetMPstack - \else\ifx\somestring\PSdtransform % == setlinewidth - \let\handleMPsequence\handleMPdtransform - % after that we will encounter more tokens until setlinewidth+pop - % or pop+setlinewidth which we catch next; we explicitly need to - % reset the stack since [] n setdash may follow; a more clever - % approach would be to read on till the condition is met, but it's - % the only pop / setlinewidth we will encounter so ... - \else\ifx\somestring\PSsetlinewidth - % already handled in dtransform - \resetMPstack - \else\ifx\somestring\PSpop - % already handled in dtransform - \resetMPstack - \else\ifx\somestring\PSconcat - \cleanupMPconcat - \PDFcode{\gMPa1 \gMPa2 \gMPa3 \gMPa4 \gMPa5 \gMPa6 cm}% - \resetMPstack - \else\ifx\somestring\PSsetrgbcolor - \handleMPrgbcolor - \resetMPstack - \else\ifx\somestring\PSsetcmykcolor - \handleMPcmykcolor - \resetMPstack - \else\ifx\somestring\PSsetgray - \handleMPgraycolor - \resetMPstack - \else\ifx\somestring\PStranslate - \PDFcode{1 0 0 1 \gMPa1 \gMPa2 cm}% - \resetMPstack - \else\ifx\somestring\PSsetdash - \handleMPsetdash - \resetMPstack - \else\ifx\somestring\PSsetlinejoin - \PDFcode{\gMPa1 j}% - \resetMPstack - \else\ifx\somestring\PSsetmiterlimit - \PDFcode{\gMPa1 M}% - \resetMPstack - \else\ifx\somestring\PSfshow - \PDFcode{n}% - \handleMPfshow - \resetMPstack - \else\ifx\somestring\PSsetlinecap - \PDFcode{\gMPa1 J}% - \resetMPstack - \else\ifx\somestring\PSrlineto - \PDFcode{\!MP\lastMPmoveX\space\!MP\lastMPmoveY\space l S}% - \resetMPstack - \else\ifx\somestring\PSscale - \PDFcode{\gMPa1 0 0 \gMPa2 0 0 cm}% - \resetMPstack - \else\ifx\somestring\PSspecial - \handleMPspecialcommand - \resetMPstack - \else - \handleMPgraphic% {#1}% - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \handleMPsequence} - -\def\dohandleMPsequenceC#1 % - {\edef\somestring{#1}% - \handleMPgraphic % {#1}% - \handleMPsequence} - -%D Since colors are not sensitive to transformations, they -%D are sometimes used for signaling. Therefore, we handle them -%D separately. The next macro can be redefined if needed. - -\def\handleMPrgbcolor - {\PDFcode{\!MPgMPa1 \!MPgMPa2 \!MPgMPa3 rg - \!MPgMPa1 \!MPgMPa2 \!MPgMPa3 RG}} - -\def\handleMPcmykcolor - {\PDFcode{\!MPgMPa1 \!MPgMPa2 \!MPgMPa3 \!MPgMPa4 k - \!MPgMPa1 \!MPgMPa2 \!MPgMPa3 \!MPgMPa4 K}} - -\def\handleMPgraycolor - {\PDFcode{\!MPgMPa1 g - \!MPgMPa1 G}} - -\def\handleMPspotcolor - {\PDFcode{0 g - 0 G}} - -%D Beginning and ending the graphics is taken care of by the -%D macro \type{\handleMPgraphic}, which is redefined when -%D the first graphics operator is met. - -\def\handleMPendgraphic % #1% - {\ifx\somestring\PSshowpage - \let\handleMPsequence\finishMPgraphic - \else - \letMPargument\somestring % {#1}% - \fi} - -\def\handleMPbegingraphic % #1% - {\ifx\somestring\PSBoundingBox - \def\handleMPsequence{\handleMPboundingbox1}% - \else\ifx\somestring\PSHiResBoundingBox - \def\handleMPsequence{\handleMPboundingbox2}% - \else\ifx\somestring\PSExactBoundingBox - \def\handleMPsequence{\handleMPboundingbox3}% - \else\ifx\somestring\PSshowpage - \let\handleMPsequence\finishMPgraphic - \else\ifx\somestring\PSPage - \let\handleMPsequence\handleMPpage - \else\ifx\somestring\PSMetaPostSpecials - \let\handleMPsequence\handleMPspecialscomment - \else\ifx\somestring\PSMetaPostSpecial - \let\handleMPsequence\handleMPspecialcomment - \else - \letMPargument\somestring % {#1}% - \fi\fi\fi\fi\fi\fi\fi} - -\let\handleMPgraphic=\handleMPbegingraphic - -%D We check for three kind of bounding boxes: the normal one -%D and two high precision ones: -%D -%D \starttyping -%D BoundingBox: llx lly ucx ucy -%D HiResBoundingBox: llx lly ucx ucy -%D ExactBoundingBox: llx lly ucx ucy -%D \stoptyping -%D -%D The original as well as the recalculated dimensions are -%D saved for later use. - -\newif\ifskipemptyMPgraphic \skipemptyMPgraphicfalse - -\chardef\currentMPboundingbox=0 - -\def\handleMPboundingbox#1#2 #3 #4 #5 - {\ifnum#1>\currentMPboundingbox - \xdef\MPllx{#2}\xdef\MPlly{#3}% - \xdef\MPurx{#4}\xdef\MPury{#5}% - \dimen0=#2\onepoint - \dimen0=-\MPxscale\dimen0 - \dimen2=#3\onepoint - \dimen2=-\MPyscale\dimen2 - \xdef\MPxoffset{\withoutpt\the\dimen0}% - \xdef\MPyoffset{\withoutpt\the\dimen2}% - \dimen0=#2\onebasepoint - \dimen0=-\dimen0 - \dimen2=#3\onebasepoint - \dimen2=-\dimen2 - \advance\dimen0 #4\onebasepoint - \dimen0=\MPxscale\dimen0 - \xdef\MPwidth{\the\dimen0}% - \advance\dimen2 #5\onebasepoint - \xdef\MPyshift{\the\dimen2}% unscaled - \dimen2=\MPyscale\dimen2 - \xdef\MPheight{\the\dimen2}% - \chardef\currentMPboundingbox#1\relax - \fi - \doresetMPstack - \let\handleMPsequence\dohandleMPsequence - \let\next\handleMPsequence - \ifskipemptyMPgraphic - \ifdim\MPheight=\zeropoint\relax\ifdim\MPwidth=\zeropoint\relax - \def\next{\endinput\finishMPgraphic}% - \fi\fi - \fi - \next} - -%D Unless defined otherwise, we simply ignore specialcomments. - -\def\handleMPspecialcomment - {\doresetMPstack - \let\handleMPsequence\dohandleMPsequence - \handleMPsequence} - -\let\handleMPspecialscomment\handleMPspecialcomment - -%D We use the \type{page} comment as a signal that -%D stackbuilding can be started. - -\def\handleMPpage #1 #2 - {\doresetMPstack - \donetrue - \let\handleMPsequence\dohandleMPsequence - \handleMPsequence} - -%D The same applies to the special extensions. - -\def\handleMPspecialcommand - {\doresetMPstack - \let\handleMPsequence\dohandleMPsequence - \handleMPsequence} - -%D \METAPOST\ draws its dots by moving to a location and -%D invoking \type{0 0 rlineto}. This operator is not -%D available in \PDF. Our solution is straightforward: we draw -%D a line from $(current\_x, current\_y)$ to itself. This -%D means that the arguments of the preceding \type{moveto} have -%D to be saved. - -\def\lastMPmoveX{0} -\def\lastMPmoveY{0} - -%D These saved coordinates are also used when we handle the -%D texts. Text handling proved to be a bit of a nuisance, but -%D finally I saw the light. It proved that we also had to -%D take care of \type{(split arguments)}. - -\def\setMPfshowfont#1#2% - {\font\temp=#1\space at #2\relax\temp} - -\let\MPfshowcommand\empty - -% \def\dohandleMPfshow -% {\bgroup -% \setbox\scratchbox\hbox -% {\obeyMPspecials -% \let\ \relax % mp breaks long lines and appends a \ -% \edef\size{\gMPa\nofMParguments}% -% \ifx\size\PSnfont % round font size (to pt) -% \advance\nofMParguments \minusone -% \expandafter\scratchdimen\gMPa\nofMParguments\onepoint\relax -% \ifdim\scratchdimen<\onepoint -% \def\size{1pt}% -% \else -% \advance\scratchdimen .5\onepoint -% \def\size##1.##2\relax{\def\size{##1pt}}% -% \expandafter\size\the\scratchdimen\relax -% \fi -% \else -% \edef\size{\size bp}% -% \fi -% \advance\nofMParguments \minusone -% %\font\temp=\gMPa\nofMParguments\space at \size -% \let\temp\relax % to be sure -% \setMPfshowfont{\gMPa\nofMParguments}\size -% \advance\nofMParguments \minusone -% \temp -% \MPfshowcommand -% {\ifnum\nofMParguments=\plusone -% \def\do(##1){##1}% -% \dogMPa1% -% \else -% % we need to catch ( a ) (a a a) (\123 \123 \123) etc -% \scratchcounter\plusone -% \def\dodo##1% Andreas Fieger's bug: (\304...) -% {\edef\!!stringa{##1\empty\empty}% and another one: ( 11) -> \ifx 11 -% \ifx\!!stringa\MPspacechar\MPspacechar\else\expandafter##1\fi}% -% \def\do(##1{\dodo{##1}}% -% \dogMPa\scratchcounter\MPspacechar -% \let\do\relax -% \loop -% \advance\scratchcounter \plusone -% \ifnum\scratchcounter<\nofMParguments\relax -% \gMPa\scratchcounter\MPspacechar -% \repeat -% \def\do##1){\dodo{##1}}% -% \dogMPa\scratchcounter -% \fi -% \unskip}}% -% % -% % this fails in some versions of pdftex -% % -% % \dimen0=\lastMPmoveY bp -% % \advance\dimen0 by \ht0 -% % \ScaledPointsToBigPoints{\number\dimen0}\lastMPmoveY -% % \PDFcode{n q 1 0 0 1 \lastMPmoveX\space\lastMPmoveY\space cm}% -% % \dimen0=\ht0 -% % \advance\dimen0 by \dp0 -% % \box0 -% % \vskip-\dimen0 -% % \PDFcode{Q}% -% % \egroup} -% % -% \setbox\scratchbox\hbox -% {\hskip\lastMPmoveX\onebasepoint\raise\lastMPmoveY\onebasepoint\box\scratchbox}% -% \ht\scratchbox\zeropoint -% \dp\scratchbox\zeropoint -% \wd\scratchbox\zeropoint -% \box\scratchbox -% \egroup} -% -% \let\handleMPfshow\dohandleMPfshow % so we can overload this one later -% -% we will support plug-ins: - -\def\dohandleMPfshow - {\setbox\scratchbox\hbox - {\obeyMPspecials - \edef\MPtextsize{\gMPa\nofMParguments}% - \def\do(##1){##1}% - \edef\MPtextdata{\dogMPa1}% beware, stack can have more - \handleMPtext}% - \setbox\scratchbox\hbox - {\hskip\lastMPmoveX\onebasepoint\raise\lastMPmoveY\onebasepoint - \box\scratchbox}% - % - % this fails in some versions of pdftex - % - % \dimen0=\lastMPmoveY bp - % \advance\dimen0 by \ht0 - % \ScaledPointsToBigPoints{\number\dimen0}\lastMPmoveY - % \PDFcode{n q 1 0 0 1 \lastMPmoveX\space\lastMPmoveY\space cm}% - % \dimen0=\ht0 - % \advance\dimen0 by \dp0 - % \box0 - % \vskip-\dimen0 - % \PDFcode{Q}% - % \egroup} - % - \ht\scratchbox\zeropoint - \dp\scratchbox\zeropoint - \wd\scratchbox\zeropoint - \box\scratchbox} - -\def\handleMPtext {\handleMPtextnormal} % so we can overload this one later -\def\handleMPfshow{\dohandleMPfshow } % so we can overload this one later - -\def\handleMPtext - {\ifnum\nofMParguments>\plusthree - \handleMPtextnormal - \else - \convertcommand\MPtextdata\to\MPtextdata - \expanded{\splitstring\MPtextdata}\at::::\to\MPtexttag\and\MPtextnumber - \executeifdefined{handleMPtext\MPtexttag}\handleMPtextnormal - \fi} - -% elsewhere we will implement \handleMPtextmptxt - -\def\handleMPtextnormal - {\let\ \relax % mp breaks long lines and appends a \ - \ifx\MPtextsize\PSnfont % round font size (to pt) - \advance\nofMParguments \minusone - \expandafter\scratchdimen\gMPa\nofMParguments\onepoint\relax - \ifdim\scratchdimen<\onepoint - \def\MPtextsize{1pt}% - \else - \advance\scratchdimen .5\onepoint - \def\MPtextsize##1.##2\relax{\def\MPtextsize{##1pt}}% - \expandafter\MPtextsize\the\scratchdimen\relax - \fi - \else - \edef\MPtextsize{\MPtextsize bp}% - \fi - \advance\nofMParguments \minusone - \font\temp=\gMPa\nofMParguments\space at \MPtextsize - \let\temp\relax % to be sure - \setMPfshowfont{\gMPa\nofMParguments}\MPtextsize - \advance\nofMParguments \minusone - \temp - \MPfshowcommand - {\ifnum\nofMParguments=\plusone - \def\do(##1){##1}% - \dogMPa1% - \else - % we need to catch ( a ) (a a a) (\123 \123 \123) etc - \scratchcounter\plusone - \def\dodo##1% Andreas Fieger's bug: (\304...) - {\edef\!!stringa{##1\empty\empty}% and another one: ( 11) -> \ifx 11 - \ifx\!!stringa\MPspacechar\MPspacechar\else\expandafter##1\fi}% - \def\do(##1{\dodo{##1}}% - \dogMPa\scratchcounter\MPspacechar - \let\do\relax - \loop - \advance\scratchcounter \plusone - \ifnum\scratchcounter<\nofMParguments\relax - \gMPa\scratchcounter\MPspacechar - \repeat - \def\do##1){\dodo{##1}}% - \dogMPa\scratchcounter - \fi - \unskip}} - -%D You could consider the following definition to be the most -%D natural one. - -% \def\MPspacechar{\space} % normal case - -\def\MPspacechar{\char32\relax} % old solution does not work with math - -%D However, the following implementation is more robust, since -%D some fonts have funny visible spaces in the space slot. This -%D gives a mismatch between the space that \METAPOST\ took into -%D account and the \quote {natural} space. This only happens in -%D labels, since \type {btex}||\type {etex} thingies don't have -%D spaces. This phenomena showed up when preparing the -%D \METAFUN\ manual, where Palatino fonts are used. We can -%D safely assume that \METAPOST\ considers \type {\char32} to -%D be the space. - -\def\MPspacechar{\setbox\scratchbox\hbox{\char32}\kern\wd\scratchbox} - -%D Well, this does not work with math fonts, so: - -\def\MPspacechar{\char32\relax} - -%D Most operators are just converted and keep their -%D arguments. Dashes however need a bit different treatment, -%D otherwise \PDF\ viewers complain loudly. Another -%D complication is that one argument comes after the \type{]}. -%D When reading the data, we simply ignore the array boundary -%D characters. We save ourselves some redundant newlines and -%D at the same time keep the output readable by packing the -%D literals. - -\def\handleMPsetdash - {\bgroup - \ignoreMPspecials - \def\somestring{[}% - \scratchcounter\plusone - \loop - \ifnum\scratchcounter<\nofMParguments - \edef\somestring{\somestring\space\gMPa\scratchcounter}% - \advance\scratchcounter \plusone - \repeat - \edef\somestring{\somestring]\gMPa\scratchcounter\space d}% - \PDFcode{\somestring}% - \egroup} - -%D The \type{setlinewidth} commands looks a bit complicated. There are -%D two alternatives, that result in a similar look in both -%D $x$- and $y$-dorection. As John Hobby says: -%D -%D \startnarrower \switchtobodyfont[ss] -%D \starttyping -%D x 0 dtransform exch truncate exch idtransform pop setlinewidth -%D 0 y dtransform truncate idtransform setlinewidth pop -%D \stoptyping -%D -%D These are just fancy versions of \type{x setlinewidth} and -%D \type{y setlinewidth}. The \type{x 0 ...} form is used if -%D the path is {\em primarily vertical}. It rounds the width -%D so that vertical lines come out an integer number of pixels -%D wide in device space. The \type{0 y ...} form does the same -%D for paths that are {\em primarily horizontal}. The reason -%D why I did this is Knuth insists on getting exactly the -%D widths \TEX\ intends for the horizontal and vertical rules -%D in \type{btex...etex} output. (Note that PostScript scan -%D conversion rules cause a horizontal or vertical line of -%D integer width $n$ in device space to come out $n+1$ pixels -%D wide, regardless of the phase relative to the pixel grid.) -%D \stopnarrower -%D -%D The common operator in these sequences is \type{dtransform}, -%D so we can use this one to trigger setting the linewidth. - -\def\handleMPdtransform - {\ifdim\gMPa1\onepoint>\zeropoint - \PDFcode{\gMPa1 w}% - \def\next##1 ##2 ##3 ##4 ##5 ##6 {\handleMPsequence}% - \else - \PDFcode{\gMPa2 w}% - \def\next##1 ##2 ##3 ##4 {\handleMPsequence}% - \fi - \let\handleMPsequence\dohandleMPsequence - \resetMPstack - \next} - -%D The most complicated command is \type{concat}. \METAPOST\ -%D applies this operator to \type{stroke}. At that moment the -%D points set by \type{curveto} and \type{moveto}, are already -%D fixed. In \PDF\ however the \type{cm} operator affects the -%D points as well as the pen (stroke). Like more \PDF\ -%D operators, \type{cm} is defined in a bit ambiguous way. -%D The only save route for non||circular penshapes, is saving -%D the path, recalculating the points and applying the -%D transformation matrix in such a way that we can be sure -%D that its behavior is well defined. This comes down to -%D inverting the path and applying \type{cm} to that path as -%D well as the pen. This all means that we have to save the -%D path. - -%D In \METAPOST\ there are three ways to handle a path $p$: -%D -%D \starttyping -%D draw p; fill p; filldraw p; -%D \stoptyping -%D -%D The last case outputs a \type{gsave fill grestore} before -%D \type{stroke}. Handling the path outside the main loops -%D saves about 40\% run time.\footnote{We can save some more by -%D following the \METAPOST\ output routine, but for the moment -%D we keep things simple.} Switching between the main loop and -%D the path loop is done by means of the recursely called -%D macro \type{\handleMPsequence}. - -\def\handleMPpath - {\chardef\finiMPpath0 - \let\closeMPpath\relax - \let\flushMPpath\flushnormalMPpath - \resetMPstack - \nofMPsegments\plusone - \let\handleMPsequence\dohandleMPpath - \dohandleMPpath} - -%D Most paths are drawn with simple round pens. Therefore we've -%D split up the routine in two. - -\def\flushnormalMPsegment - {\ifcase\getMPkeyword\relax - \PDFcode{\!MPgMPs1 \!MPgMPs2 l}% - \or - \PDFcode{\!MPgMPs1 \!MPgMPs2 \!MPgMPs3 \!MPgMPs4 \!MPgMPs5 \!MPgMPs6 c}% - \or - \PDFcode{\!MP\lastMPmoveX\space\!MP\lastMPmoveY\space l S}% - \or - \edef\lastMPmoveX{\gMPs1}% evt \!MP here - \edef\lastMPmoveY{\gMPs2}% - \PDFcode{\!MP\lastMPmoveX\space \!MP\lastMPmoveY\space m}% - \fi} - -\def\flushconcatMPsegment - {\ifcase\getMPkeyword\relax - \doMPconcat{\gMPs1}\a{\gMPs2}\b% - \PDFcode{\!MP\a\space\!MP\b\space l}% - \or - \doMPconcat{\gMPs1}\a{\gMPs2}\b% - \doMPconcat{\gMPs3}\c{\gMPs4}\d% - \doMPconcat{\gMPs5}\e{\gMPs6}\f% - \PDFcode{\!MP\a\space\!MP\b\space - \!MP\c\space\!MP\d\space - \!MP\e\space\!MP\f\space c}% - \or - \bgroup - \noMPtranslate - \doMPconcat\lastMPmoveX\a\lastMPmoveY\b% - \PDFcode{\!MP\a\space\!MP\b\space l S}% - \egroup - \or - \edef\lastMPmoveX{\gMPs1}% - \edef\lastMPmoveY{\gMPs2}% - \doMPconcat\lastMPmoveX\a\lastMPmoveY\b% - \PDFcode{\!MP\a\space\!MP\b\space m}% - \fi} - -\def\doflushsomeMPpath - {\dodoflushsomeMPpath - \advance\nofMPsegments \plusone - \ifnum\nofMPsegments<\scratchcounter - \expandafter\doflushsomeMPpath - \fi} - -\def\flushsomeMPpath - {\scratchcounter\nofMPsegments - \nofMPsegments\plusone - \doflushsomeMPpath} - -\def\flushnormalMPpath{\let\dodoflushsomeMPpath\flushnormalMPsegment\flushsomeMPpath} - -%OLD \def\flushconcatMPpath{\let\dodoflushsomeMPpath\flushconcatMPsegment\flushsomeMPpath} - -%NEW pre-calculate 1/D so it needn't be repeated for each control point. - -\def\flushconcatMPpath - {\MPreciprocaldeterminant - \let\dodoflushsomeMPpath\flushconcatMPsegment\flushsomeMPpath} - -%D The transformation of the coordinates is handled by one of -%D the macros Tanmoy posted to the \PDFTEX\ mailing list. -%D I rewrote and optimized the original macro to suit the other -%D macros in this module. -%D -%D \starttyping -%D \doMPconcat {x position} \xresult {y position} \yresult -%D \stoptyping -%D -%D By setting the auxiliary \DIMENSIONS\ \type{\dimen0} upto -%D \type{\dimen10} only once per path, we save over 20\% run -%D time. Some more speed was gained by removing some parameter -%D passing. These macros can be optimized a bit more by using -%D more constants. There is however not much need for further -%D optimization because penshapes usually are round and -%D therefore need no transformation. Nevertheless we move the -%D factor to the outer level and use a bit different \type{pt} -%D removal macro. Although the values represent base points, -%D we converted them to pure points, simply because those can -%D be converted back. - -%OLD \mathchardef\MPconcatfactor=256 % beware don't remove spaces before it - -%OLD \def\doMPreducedimen#1 -%OLD {\count0\MPconcatfactor -%OLD \advance\dimen#1 \ifdim\dimen#1>\zeropoint .5\else -.5\fi\count0 -%OLD \divide\dimen#1 \count0\relax} - -%OLD % too inaccurate (see old pragma logo) -%OLD -%OLD \def\doMPreducedimen#1 -%OLD {\count0=\MPconcatfactor -%OLD \divide\dimen#1 \count0\relax} - -%OLD \def\doMPreducedimen#1 -%OLD {\advance\dimen#1 \ifdim\dimen#1>\zeropoint .5\else -.5\fi\MPconcatfactor -%OLD \divide\dimen#1 \MPconcatfactor} - -%D The transformation code is rewritten by Daniel H. Luecking who -%D describes his patch as follows: -%D -%D We would like to divide 1 by $X$, but all divisions are integer so -%D for accuracy we want to convert to large integers and make sure the -%D integer quotient has as many significant digits as possible. Thus we -%D need to replace $1/X$ with $M/N$ where $N$ is as large as possible -%D and $M/N$ is as large as possible. Also for simplicity $M$ should be -%D a power of 2. So we make $M = 2^{30}$ \footnote{$2^{31} - 1$ is the -%D largest legal integer. Using it (and simply ignoring the inaccuracy -%D caused by $-1$) turns out to be at least as accurate in all cases, -%D and more accurate in some.} (largest legal power of 2) and adjust -%D $X$ downward (if necessary) to the the range $1-2^{16}$. This gives -%D at least 15 significant binary digits, (almost as accurate as -%D \METAPOST\ for numbers near 1) or almost 5 significant figures -%D (decimal). - -\newcount\MPscratchCnt -\newdimen\MPscratchDim % will be assigned global - -\def\MPadjustdimen % sets \MPscratchDim and \MPscratchCnt - {\MPscratchCnt\zerocount - \doMPadjustdimen} - -\def\doMPadjustdimen - {\ifdim\MPscratchDim>\onepoint - \divide\MPscratchDim 2 - \advance\MPscratchCnt \plusone - \expandafter\doMPadjustdimen - \fi} - -%OLD \def\doMPexpanddimen#1 -%OLD {\multiply\dimen#1 \MPconcatfactor\relax} - -%D DHL: When viewed as an integer, $1 \hbox{pt}=2^{16}$ so $2^{32}/X$ -%D is the right way to do $(1 \hbox{pt})/(X \hbox{pt})$ and get the -%D answer in points. But we are limited to $2^{30}/X$. However, we -%D actually do $[ 2^{30} / (X/2^K) ]*2^{2-K}$ where $K$ is the number -%D of halvings it takes to bring $X$ below $1 \hbox{pt}$. If $K$ is 0 -%D or 1 we readjust by multiplying by 4 or 2, otherwise by halving -%D $(K-2)$ times \type {\MPscratchCnt} holds the value of $K$ from -%D \type {\MPadjustdimen}. - -\def\MPreadjustdimen % acts on \MPscratchDim and MPscratchCnt - {\ifcase\MPscratchCnt - \multiply\scratchdimen 4 - \or - \multiply\scratchdimen 2 - \else - \expandafter\doMPreadjustdimen - \fi} - -\def\doMPreadjustdimen - {\ifnum\MPscratchCnt>2 - \divide\scratchdimen 2 - \advance\MPscratchCnt \minusone - \expandafter\doMPreadjustdimen - \fi} - -\def\MPreciprocaldeterminant - {\scratchdimen\withoutpt\the\dimen0 \dimen6 % s_x*s_y - \advance\scratchdimen - \withoutpt\the\dimen2 \dimen4 % s_x*s_y - r_x*r_y - \ifdim\scratchdimen<\zeropoint % we need a positive dimension - \scratchdimen-\scratchdimen % for \MPadjustdimen (?) - \doMPreciprocal - \scratchdimen-\scratchdimen - \else - \doMPreciprocal - \fi - \edef\MPreciprocal{\withoutpt\the\scratchdimen}} - -\newcount\MPnumerator \MPnumerator = 1073741824 % 2^{30} - -% todo: dimexpr - -\def\doMPreciprocal % replace \scratchdimen with its reciprocal - {\ifdim\scratchdimen=\onepoint \else - \MPadjustdimen - \scratchcounter\MPnumerator - \divide\scratchcounter\scratchdimen - \scratchdimen1\scratchcounter % 1 needed ! - \MPreadjustdimen - \fi} - -%OLD \def\presetMPconcat -%OLD {\dimen 0=\gMPs1\onepoint \doMPreducedimen 0 % r_x -%OLD \dimen 2=\gMPs2\onepoint \doMPreducedimen 2 % s_x -%OLD \dimen 4=\gMPs3\onepoint \doMPreducedimen 4 % s_y -%OLD \dimen 6=\gMPs4\onepoint \doMPreducedimen 6 % r_y -%OLD \dimen 8=\gMPs5\onepoint \doMPreducedimen 8 % t_x -%OLD \dimen10=\gMPs6\onepoint \doMPreducedimen10 } % t_y -%OLD -%OLD \def\presetMPscale -%OLD {\dimen 0=\gMPs1\onepoint \doMPreducedimen 0 -%OLD \dimen 2 \zeropoint -%OLD \dimen 4 \zeropoint -%OLD \dimen 6=\gMPs2\onepoint \doMPreducedimen 6 -%OLD \dimen 8 \zeropoint -%OLD \dimen10 \zeropoint} - -\def\cleanupMPconcat - {\ignoreMPspecials - \docleanupMPargument1% - \docleanupMPargument6% - \keepMPspecials} - -\def\presetMPconcat - {\dimen 0=\gMPs1\onepoint % s_x - \dimen 2=\gMPs2\onepoint % r_x - \dimen 4=\gMPs3\onepoint % r_y - \dimen 6=\gMPs4\onepoint % s_y - \dimen 8=\gMPs5\onepoint % t_x - \dimen10=\gMPs6\onepoint} % t_y - -\def\presetMPscale - {\dimen 0=\gMPs1\onepoint - \dimen 2 \zeropoint - \dimen 4 \zeropoint - \dimen 6=\gMPs2\onepoint - \dimen 8 \zeropoint - \dimen10 \zeropoint} - -\def\noMPtranslate % use this one grouped - {\dimen 8 \zeropoint % t_x - \dimen10 \zeropoint} % t_y - -%D \starttyping -%D \def\doMPconcat#1#2#3#4% -%D {\dimen12=#1 pt \doMPreducedimen12 % p_x -%D \dimen14=#3 pt \doMPreducedimen14 % p_y -%D % -%D \dimen16 \dimen 0 -%D \multiply \dimen16 \dimen 6 -%D \dimen20 \dimen 2 -%D \multiply \dimen20 \dimen 4 -%D \advance \dimen16 -\dimen20 -%D % -%D \dimen18 \dimen12 -%D \multiply \dimen18 \dimen 6 -%D \dimen20 \dimen14 -%D \multiply \dimen20 \dimen 4 -%D \advance \dimen18 -\dimen20 -%D \dimen20 \dimen 4 -%D \multiply \dimen20 \dimen10 -%D \advance \dimen18 \dimen20 -%D \dimen20 \dimen 6 -%D \multiply \dimen20 \dimen 8 -%D \advance \dimen18 -\dimen20 -%D % -%D \multiply \dimen12 -\dimen 2 -%D \multiply \dimen14 \dimen 0 -%D \advance \dimen12 \dimen14 -%D \dimen20 \dimen 2 -%D \multiply \dimen20 \dimen 8 -%D \advance \dimen12 \dimen20 -%D \dimen20 \dimen 0 -%D \multiply \dimen20 \dimen10 -%D \advance \dimen12 -\dimen20 -%D % -%D \doMPreducedimen16 -%D \divide \dimen18 \dimen16 \doMPexpanddimen18 -%D \divide \dimen12 \dimen16 \doMPexpanddimen12 -%D % -%D \edef#2{\withoutpt\the\dimen18}% % p_x^\prime -%D \edef#4{\withoutpt\the\dimen12}} % p_y^\prime -%D \stoptyping - -%D The following optimization resulted from some tests by -%D and email exchanges with Sanjoy Mahajan. -%D -%D \starttyping -%D \def\doMPconcat#1#2#3#4% -%D {\dimen12=#1 pt \doMPreducedimen12 % p_x -%D \dimen14=#3 pt \doMPreducedimen14 % p_y -%D % -%D \dimen16 \dimen 0 -%D \multiply \dimen16 \dimen 6 -%D \dimen20 \dimen 2 -%D \multiply \dimen20 \dimen 4 -%D \advance \dimen16 -\dimen20 -%D % -%D \dimen18 \dimen12 -%D \multiply \dimen18 \dimen 6 -%D \dimen20 \dimen14 -%D \multiply \dimen20 \dimen 4 -%D \advance \dimen18 -\dimen20 -%D \dimen20 \dimen 4 -%D \multiply \dimen20 \dimen10 -%D \advance \dimen18 \dimen20 -%D \dimen20 \dimen 6 -%D \multiply \dimen20 \dimen 8 -%D \advance \dimen18 -\dimen20 -%D % -%D \multiply \dimen12 -\dimen 2 -%D \multiply \dimen14 \dimen 0 -%D \advance \dimen12 \dimen14 -%D \dimen20 \dimen 2 -%D \multiply \dimen20 \dimen 8 -%D \advance \dimen12 \dimen20 -%D \dimen20 \dimen 0 -%D \multiply \dimen20 \dimen10 -%D \advance \dimen12 -\dimen20 -%D % -%D %\ifdim\dimen16>1pt % oeps, can be < 1pt too -%D \ifdim\dimen16=1pt \else -%D \ifdim\dimen16>\MPconcatfactor pt -%D \doMPreducedimen16 -%D \divide \dimen18 \dimen16 \doMPexpanddimen18 -%D \divide \dimen12 \dimen16 \doMPexpanddimen12 -%D \else -%D \divide \dimen18 \dimen16 \doMPexpanddimen18 \doMPexpanddimen18 -%D \divide \dimen12 \dimen16 \doMPexpanddimen12 \doMPexpanddimen12 -%D \fi -%D \fi -%D % -%D \edef#2{\withoutpt\the\dimen18}% % p_x^\prime -%D \edef#4{\withoutpt\the\dimen12}} % p_y^\prime -%D \stoptyping -%D -%D But, this one is still too inaccurate, so we now have: - -%D We cannot use \type {\beginETEX} here since in plain we -%D get \type {\outer} problems, sigh. - -%OLD \beginTEX -%OLD -%OLD \def\MPcriteriumA {512pt} % scale -%OLD \def\MPcriteriumB {2pt} % scale -%OLD -%OLD \endTEX -%OLD -%OLD \ifx\MPcriteriumA\undefined -%OLD -%OLD \newdimen\MPcriteriumA \MPcriteriumA=512pt -%OLD \newdimen\MPcriteriumB \MPcriteriumB= 2pt -%OLD -%OLD \fi - -%OLD \def\doMPconcat#1#2#3#4% -%OLD {\dimen12=#1pt % p_x -%OLD \dimen14=#3pt % p_y -%OLD % -%OLD \chardef\MPfactor\zerocount -%OLD \ifdim\dimen4<\MPcriteriumB\ifdim\dimen4>-\MPcriteriumB -%OLD \ifdim\dimen6<\MPcriteriumB\ifdim\dimen6>-\MPcriteriumB -%OLD \ifdim\dimen8<\MPcriteriumB\ifdim\dimen8>-\MPcriteriumB -%OLD \ifdim\dimen10<\MPcriteriumB\ifdim\dimen10>-\MPcriteriumB -%OLD \chardef\MPfactor\plusone -%OLD \fi\fi -%OLD \fi\fi -%OLD \fi\fi -%OLD \fi\fi -%OLD \ifcase\MPfactor % spurious 0 removed -%OLD \chardef\MPfactor\plusone -%OLD \ifdim\dimen12<\MPcriteriumA\ifdim\dimen12>-\MPcriteriumA -%OLD \ifdim\dimen14<\MPcriteriumA\ifdim\dimen14>-\MPcriteriumA -%OLD \chardef\MPfactor16 -%OLD \fi\fi -%OLD \fi\fi -%OLD \fi -%OLD % -%OLD \multiply\dimen12 \MPfactor -%OLD \multiply\dimen14 \MPfactor -%OLD % -%OLD \doMPreducedimen12 -%OLD \doMPreducedimen14 -%OLD % -%OLD \dimen16 \dimen 0 -%OLD \multiply \dimen16 \dimen 6 -%OLD \dimen20 \dimen 2 -%OLD \multiply \dimen20 \dimen 4 -%OLD \advance \dimen16 -\dimen20 -%OLD % -%OLD \dimen18 \dimen12 -%OLD \multiply \dimen18 \dimen 6 -%OLD \dimen20 \dimen14 -%OLD \multiply \dimen20 \dimen 4 -%OLD \advance \dimen18 -\dimen20 -%OLD \dimen20 \dimen 4 -%OLD \multiply \dimen20 \dimen10 -%OLD \advance \dimen18 \dimen20 -%OLD \dimen20 \dimen 6 -%OLD \multiply \dimen20 \dimen 8 -%OLD \advance \dimen18 -\dimen20 -%OLD % -%OLD \multiply \dimen12 -\dimen 2 -%OLD \multiply \dimen14 \dimen 0 -%OLD \advance \dimen12 \dimen14 -%OLD \dimen20 \dimen 2 -%OLD \multiply \dimen20 \dimen 8 -%OLD \advance \dimen12 \dimen20 -%OLD \dimen20 \dimen 0 -%OLD \multiply \dimen20 \dimen10 -%OLD \advance \dimen12 -\dimen20 -%OLD % -%OLD \ifdim\dimen16=\onepoint \else -%OLD \ifdim\dimen16>\MPconcatfactor \onepoint \relax -%OLD \doMPreducedimen16 -%OLD \divide \dimen18 \dimen16 \doMPexpanddimen18 -%OLD \divide \dimen12 \dimen16 \doMPexpanddimen12 -%OLD \else -%OLD \divide \dimen18 \dimen16 \doMPexpanddimen18 \doMPexpanddimen18 -%OLD \divide \dimen12 \dimen16 \doMPexpanddimen12 \doMPexpanddimen12 -%OLD \fi -%OLD \fi -%OLD % -%OLD \divide\dimen18 \MPfactor -%OLD \divide\dimen12 \MPfactor -%OLD % -%OLD \edef#2{\withoutpt\the\dimen18}% % p_x^\prime -%OLD \edef#4{\withoutpt\the\dimen12}} % p_y^\prime - -%D DHL: Ideally, $r_x$, $r_y$, $s_x$, $s_y$ should be in macros, not -%D dimensions (they are scalar quantities after all, not lengths). I -%D suppose the authors decided to do calculations with integer -%D arithmetic instead of using real factors because it's faster. -%D However, the actual macros test slower, possibly because I've -%D omitted three nested loops. In my test files, my approach is more -%D accurate. It is also far simpler and overflow does not seem to be a -%D significant concern. The scale factors written by Metapost are (?) -%D always $<=1$ (it scales coordinates internally) and coordinates are -%D always likely to be less than \type {\maxdimen}. -%D -%D If this should ever cause problems, the scale factors can be reduced. - -\def\doMPconcat#1#2#3#4% - {\dimen12=#1pt % p_x % #1\onepoint - \dimen14=#3pt % p_y % #3\onepoint - \advance\dimen12 -\dimen8 % p_x - t_x - \advance\dimen14 -\dimen10 % p_y - t_y - \dimen18=\withoutpt\the\dimen6 \dimen12 % s_y(p_x - t_x) - \advance\dimen18 -\withoutpt\the\dimen4 \dimen14 % - r_y(p_y-t_y) - \dimen14=\withoutpt\the\dimen0 \dimen14 % s_x(p_y-t_y) - \advance\dimen14 -\withoutpt\the\dimen2 \dimen12 % - r_x(p_x-t_x) - % \MPreciprocal contains precomputed 1/D: - \dimen18=\MPreciprocal\dimen18 - \dimen14=\MPreciprocal\dimen14 - \edef#2{\withoutpt\the\dimen18}% % p_x^\prime - \edef#4{\withoutpt\the\dimen14}} % p_y^\prime - -% faster but not that often used -% -% \def\doMPconcat#1#2#3#4% -% {\dimen12\dimexpr#1\points-\dimen 8\relax % p_x-t_x -% \dimen14\dimexpr#3\points-\dimen10\relax % p_y-t_y -% \dimen18\dimexpr\withoutpt\the\dimen6\dimen12-\withoutpt\the\dimen4\dimen14\relax % s_y(p_x-t_x)-r_y(p_y-t_y) -% \dimen14\dimexpr\withoutpt\the\dimen0\dimen14-\withoutpt\the\dimen2\dimen12\relax % s_x(p_y-t_y)-r_x(p_x-t_x) -% \edef#2{\withoutpt\the\dimexpr\MPreciprocal\dimen18\relax}% % p_x^\prime -% \edef#4{\withoutpt\the\dimexpr\MPreciprocal\dimen14\relax}} % p_y^\prime - -%D One reason for Daniel to write this patch was that at small sizes -%D the accuracy was less than optimal. Here is a test that demonstrates -%D that his alternative is pretty good: -%D -%D \startlinecorrection -%D \startMPcode -%D for i = 5cm,1cm,5mm,1mm,.5mm,.1mm,.01mm : -%D draw fullcircle scaled i withpen pencircle xscaled (i/10) yscaled (i/20) rotated 45 ; -%D endfor ; -%D \stopMPcode -%D \stoplinecorrection - -%D The following explanation of the conversion process was -%D posted to the \PDFTEX\ mailing list by Tanmoy. The original -%D macro was part of a set of macro's that included sinus and -%D cosinus calculations as well as scaling and translating. The -%D \METAPOST\ to \PDF\ conversion however only needs -%D transformation. - -%M \start \switchtobodyfont [ss] - -%D Given a point $(U_x, U_y)$ in user coordinates, the business -%D of \POSTSCRIPT\ is to convert it to device space. Let us say -%D that the device space coordinates are $(D_x, D_y)$. Then, in -%D \POSTSCRIPT\ $(D_x, D_y)$ can be written in terms of -%D $(U_x, U_y)$ in matrix notation, either as -%D -%D \placeformula -%D \startformula -%D \pmatrix{D_x&D_y&1\cr} = \pmatrix{U_x&U_y&1\cr} -%D \pmatrix{s_x&r_x&0\cr -%D r_y&s_y&0\cr -%D t_x&t_y&1\cr} -%D \stopformula -%D -%D or -%D -%D \placeformula -%D \startformula -%D \pmatrix{D_x\cr D_y\cr 1} = \pmatrix{s_x&r_y&t_x\cr -%D r_x&s_y&t_y\cr -%D 0 &0 &1 \cr} -%D \pmatrix{U_x\cr -%D U_y\cr -%D 1 \cr} -%D \stopformula -%D -%D both of which is a shorthand for the same set of equations: -%D -%D \placeformula -%D \startformula -%D D_x = s_x U_x + r_y U_y + t_x -%D \stopformula -%D -%D \placeformula -%D \startformula -%D D_y = r_x U_x + s_y U_y + t_y -%D \stopformula -%D -%D which define what is called an `affine transformation'. -%D -%D \POSTSCRIPT\ represents the `transformation matrix' as a -%D six element matrix instead of a $3\times 3$ array because -%D three of the elements are always~0, 0 and~1. Thus the above -%D transformation is written in postscript as $[s_x\, r_x\, -%D r_y\, s_y\, t_x\, t_y]$. However, when doing any -%D calculations, it is useful to go back to the original -%D matrix notation (whichever: I will use the second) and -%D continue from there. -%D -%D As an example, if the current transformation matrix is -%D $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$ and you say \typ{[a b -%D c d e f] concat}, this means: -%D -%D \startnarrower -%D Take the user space coordinates and transform them to an -%D intermediate set of coordinates using array $[a\, b\, c\, d\, -%D e\, f]$ as the transformation matrix. -%D -%D Take the intermediate set of coordinates and change them to -%D device coordinates using array $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$ -%D as the transformation matrix. -%D \stopnarrower -%D -%D Well, what is the net effect? In matrix notation, it is -%D -%D \placeformula -%D \startformula -%D \pmatrix{I_x\cr I_y\cr 1\cr} = \pmatrix{a&c&e\cr -%D b&d&f\cr -%D 0&0&1\cr} -%D \pmatrix{U_x\cr -%D U_y\cr -%D 1 \cr} -%D \stopformula -%D -%D \placeformula -%D \startformula -%D \pmatrix{D_y\cr D_y\cr 1\cr} = \pmatrix{s_x&r_y&t_x\cr -%D r_x&s_y&t_y\cr -%D 0 &0 &1 \cr} -%D \pmatrix{I_x\cr -%D I_y\cr -%D 1 \cr} -%D \stopformula -%D -%D where $(I_x, I_y)$ is the intermediate coordinate. -%D -%D Now, the beauty of the matrix notation is that when there is -%D a chain of such matrix equations, one can always compose -%D them into one matrix equation using the standard matrix -%D composition law. The composite matrix from two matrices can -%D be derived very easily: the element in the $i$\high{th} -%D horizontal row and $j$\high{th} vertical column is -%D calculated by`multiplying' the $i$\high{th} row of the first -%D matrix and the $j$\high{th} column of the second matrix (and -%D summing over the elements). Thus, in the above: -%D -%D \placeformula -%D \startformula -%D \pmatrix{D_x\cr D_y\cr 1} = \pmatrix{s_x^\prime&r_y^\prime&t_x^\prime\cr -%D r_x^\prime&s_y^\prime&t_y^\prime\cr -%D 0 &0 &0 \cr} -%D \pmatrix{U_x\cr -%D U_y\cr -%D 1 \cr} -%D \stopformula -%D -%D with -%D -%D \placeformula -%D \startformula -%D \eqalign -%D {s_x^\prime & = s_x a + r_y b \cr -%D r_x^\prime & = r_x a + s_y b \cr -%D r_y^\prime & = s_x c + r_y d \cr -%D s_y^\prime & = r_x c + s_y d \cr -%D t_x^\prime & = s_x e + r_y f + t_x \cr -%D t_y^\prime & = r_x e + s_y f + t_y \cr} -%D \stopformula - -%D In fact, the same rule is true not only when one is going -%D from user coordinates to device coordinates, but whenever -%D one is composing two `transformations' together -%D (transformations are `associative'). Note that the formula -%D is not symmetric: you have to keep track of which -%D transformation existed before (i.e.\ the equivalent of -%D $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$) and which was -%D specified later (i.e.\ the equivalent of $[a\, b\, c\, d\, -%D e\, f]$). Note also that the language can be rather -%D confusing: the one specified later `acts earlier', -%D converting the user space coordinates to intermediate -%D coordinates, which are then acted upon by the pre||existing -%D transformation. The important point is that order of -%D transformation matrices cannot be flipped (transformations -%D are not `commutative'). -%D -%D Now what does it mean to move a transformation matrix -%D before a drawing? What it means is that given a point -%D $(P_x, P_y)$ we need a different set of coordinates -%D $(P_x^\prime, P_y^\prime)$ such that if the transformation -%D acts on $(P_x^\prime, P_y^\prime)$, they produce $(P_x, -%D P_y)$. That is we need to solve the set of equations: -%D -%D \placeformula -%D \startformula -%D \pmatrix{P_x\cr P_y\cr 1\cr} = \pmatrix{s_x&r_y&t_x\cr -%D r_x&s_y&t_y\cr -%D 0 &0 &1 \cr} -%D \pmatrix{P_x^\prime\cr -%D P_y^\prime\cr -%D 1 \cr} -%D \stopformula -%D -%D Again matrix notation comes in handy (i.e. someone has -%D already solved the problem for us): we need the inverse -%D transformation matrix. The inverse transformation matrix can -%D be calculated very easily: -%D -%D \placeformula -%D \startformula -%D \pmatrix{P_x^\prime\cr P_y^\prime\cr 1\cr} = -%D \pmatrix{s_x^\prime&r_y^\prime&t_x^\prime\cr -%D r_x^\prime&s_y^\prime&t_y^\prime\cr -%D 0 &0 &1 \cr} -%D \pmatrix{P_x\cr -%D P_y\cr -%D 1 \cr} -%D \stopformula -%D -%D where, the inverse transformation matrix is given by -%D -%D \placeformula -%D \startformula -%D \eqalign -%D {D & = s_x s_y - r_x r_y \cr -%D s_x^\prime & = s_y / D \cr -%D s_y^\prime & = s_x / D \cr -%D r_x^\prime & = - r_x / D \cr -%D r_y^\prime & = - r_y / D \cr -%D t_x^\prime & = ( - s_y t_x + r_y t_y ) / D \cr -%D t_y^\prime & = ( r_x t_x - s_x t_y ) / D \cr} -%D \stopformula -%D -%D And you can see that when expanded out, this does -%D give the formulas: -%D -%D \placeformula -%D \startformula -%D P_x^\prime = { { s_y(p_x-t_x) + r_y(t_y-p_y) } \over -%D { s_x s_y-r_x r_y } } -%D \stopformula -%D -%D \placeformula -%D \startformula -%D P_y^\prime = { { s_x(p_y-t_y) + r_x(t_x-p_x) } \over -%D { s_x*s_y-r_x*r_y } } -%D \stopformula -%D -%D The code works by representing a real number by converting -%D it to a dimension to be put into a \DIMENSION\ register: 2.3 would -%D be represented as 2.3pt for example. In this scheme, -%D multiplying two numbers involves multiplying the \DIMENSION\ -%D registers and dividing by 65536. Accuracy demands that the -%D division be done as late as possible, but overflow -%D considerations need early division. -%D -%D Division involves dividing the two \DIMENSION\ registers and -%D multiplying the result by 65536. Again, accuracy would -%D demand that the numerator be multiplied (and|/|or the -%D denominator divided) early: but that can lead to overflow -%D which needs to be avoided. -%D -%D If nothing is known about the numbers to start with (in -%D concat), I have chosen to divide the 65536 as a 256 in each -%D operand. However, in the series calculating the sine and -%D cosine, I know that the terms are small (because I never -%D have an angle greater than 45 degrees), so I chose to -%D apportion the factor in a different way. - -%M \stop - -%D The path is output using the values saved on the stack. If -%D needed, all coordinates are recalculated. - -\def\finishMPpath - {\PDFcode{\ifcase\finiMPpath W n\or S\or f\or B\fi}} - -\def\processMPpath - {\checkMPpath - \ifcase\nofMPsegments\else - \flushMPpath - \closeMPpath - \finishMPpath - \fi - \let\handleMPsequence\dohandleMPsequence - \resetMPstack - \nofMPsegments\zerocount - \handleMPsequence} - -%D The following \METAPOST\ code is quite valid but, when -%D processed and converted to \PDF, will make a file -%D unprintable on a Hewlett Packard printer (from Acrobat -%D $v<=5$). Who is to blame, the driver of the OS layer in -%D between, is hard to determine, so we add an additional -%D check. -%D -%D \starttyping -%D clip currentpicture to origin -- cycle ; -%D setbounds currentpicture to fullsquare scaled 5cm ; -%D \stoptyping - -\def\checkMPpath - {\ifcase\finiMPpath - \ifnum\nofMPsegments<3 % n is one ahead - \message{omitting zero clip path}% - \nofMPsegments\zerocount - \fi - \fi} - -%D In \PDF\ the \type{cm} operator must precede the path -%D specification. We therefore can output the \type{cm} at -%D the moment we encounter it. - -\def\handleMPpathconcat - {\presetMPconcat - \PDFcode{\gMPs1 \gMPs2 \gMPs3 \gMPs4 \gMPs5 \gMPs6 cm}% - \resetMPstack} - -\def\handleMPpathscale - {\presetMPscale - \PDFcode{\gMPs1 0 0 \gMPs2 0 0 cm}% - \resetMPstack} - -%D This macro interprets the path and saves it as compact as -%D possible. - -\def\dohandleMPpath#1% - {\ifcase\lccode`#1\relax - \@EA\dohandleMPpathA - \else - \@EA\dohandleMPpathB - \fi#1} - -\let\dohandleMPpathA\setMPsequence - -\def\dohandleMPpathB#1 % - {\def\somestring{#1}% - \ifx\somestring\PSlineto - \setMPkeyword0 - \else\ifx\somestring\PScurveto - \setMPkeyword1 - \else\ifx\somestring\PSrlineto - \setMPkeyword2 - \else\ifx\somestring\PSmoveto - \setMPkeyword3 - \else\ifx\somestring\PSclip - % \chardef\finiMPpath0 % already - \let\handleMPsequence\processMPpath - \else\ifx\somestring\PSgsave - \chardef\finiMPpath3 - \else\ifx\somestring\PSgrestore - \else\ifx\somestring\PSfill - \ifcase\finiMPpath - \chardef\finiMPpath2 - \let\handleMPsequence\processMPpath - \fi - \else\ifx\somestring\PSstroke - \ifcase\finiMPpath - \chardef\finiMPpath1 - \fi - \let\handleMPsequence\processMPpath - \else\ifx\somestring\PSclosepath - \def\closeMPpath{\PDFcode{h}}% - \else\ifx\somestring\PSconcat - \cleanupMPconcat - \let\flushMPpath\flushconcatMPpath - \handleMPpathconcat - \else\ifx\somestring\PSscale - \let\flushMPpath\flushconcatMPpath - \handleMPpathscale - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \handleMPsequence} +%D conversion. The traditional method is in the MkII file. %D The main conversion command is: %D @@ -1815,147 +147,46 @@ %D The last object number used is avaliable in the macro %D \type {\lastPDFMPobject}. -\ifx\makeMPintoPDFobject\undefined \chardef\makeMPintoPDFobject=0 \fi +\ifx\makeMPintoPDFobject \undefined \chardef\makeMPintoPDFobject \zerocount \fi +\ifx\blackoutMPgraphic \undefined \chardef\blackoutMPgraphic \plusone \fi +\ifx\everyMPtoPDFconversion\undefined \newtoks\everyMPtoPDFconversion \fi -\def\lastPDFMPobject{0} +\let\lastPDFMPobject \!!zerocount +\let\currentPDFresources\empty +\let\setMPextensions \relax -%D The additional code needed can be made available in the -%D (global) macro \type {\currentPDFresources}. +\def\PDFMPformoffset + {\ifx\objectoffset\undefined\zeropoint\else\objectoffset\fi} -\let\currentPDFresources\empty +\def\resetMPvariables#1#2#3% + {\global\let\MPwidth \!!zeropoint + \global\let\MPheight\!!zeropoint + \global\let\MPllx \!!zerocount + \global\let\MPlly \!!zerocount + \global\let\MPurx \!!zerocount + \global\let\MPury \!!zerocount + \xdef\MPxscale {#2}\ifx\MPxscale\empty\let\MPxscale\!!plusone\fi + \xdef\MPyscale {#3}\ifx\MPyscale\empty\let\MPyscale\!!plusone\fi + \xdef\MPfilename {#1}} -\newtoks\everyMPtoPDFconversion +%D The main macro: -\def\convertMPtoPDF % #1#2#3% - {\bgroup - \ifx\pdfdecimaldigits\undefined\else \pdfdecimaldigits=5 \fi % new - \setbox\scratchbox\vbox\bgroup - \xdef\MPheight{\zeropoint}% - \xdef\MPwidth {\zeropoint}% - \forgetall - \offinterlineskip - \startMPresources - \doprocessMPtoPDFfile} % - -%D The next one is kind of private and probably will become obsolete): - -\def\processMPtoPDFfile % file xscale yscale - {\bgroup - \let\finishMPgraphic\egroup - \doprocessMPtoPDFfile} - -\let\setMPextensions\relax - -\def\doprocessMPtoPDFfile#1#2#3% file xscale yscale - {% the following line is needed for latex where onepoint is not - % onepoint but a number (maxdimen); some day i'll make a latex - % variant of this file so that i no longer have to deal with such - % issues; then i'll also speed up this module using a few context - % tricks - % - \let\onepoint\onerealpoint - % - \setMPspecials - \setMPextensions - \the\everyMPtoPDFconversion - \catcode`\^^M=\@@endofline - \startMPscanning - \let\do\empty - \xdef\MPxscale{#2}% - \xdef\MPyscale{#3}% - \xdef\MPxoffset{0}% - \xdef\MPyoffset{0}% - \xdef\MPyshift{\zeropoint}% - \donefalse - \let\handleMPsequence\dohandleMPsequence - \message{[MP to PDF]}% was: [MP to PDF #1] but there is a (#1) anyway - \input#1\relax} - -% strange rounding/clip in pdftex/viewer -% -% \def\finishMPgraphic -% {\stopMPresources -% \egroup -% \ifx\pdftexversion\undefined\else\ifnum\pdftexversion<14 % for the moment -% \chardef\makeMPintoPDFobject=0 -% \fi\fi -% \ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else -% \chardef\makeMPintoPDFobject=1 -% \fi\fi -% \setbox\scratchbox=\vbox -% {\forgetall -% \hbox -% {\PDFcode{q \MPxscale\space 0 0 \MPyscale\space \MPxoffset\space \MPyoffset\space cm}% -% \lower\MPyshift\box\scratchbox % unscaled shift -% \PDFcode{Q}}}% -% \ht\scratchbox\MPheight -% \wd\scratchbox\MPwidth -% \dp\scratchbox\zeropoint -% \ifcase\makeMPintoPDFobject -% \box\scratchbox -% \or -% \immediate\pdfxform resources{\currentPDFresources}\scratchbox -% \xdef\lastPDFMPobject{\the\pdflastxform}% -% \pdfrefxform\lastPDFMPobject -% \global\let\currentPDFresources\empty -% \else -% \box\scratchbox -% \fi -% \egroup} -% -% funny clip in viewer -% -% \setbox\scratchbox=\vbox -% {\forgetall -% \dimen0=\MPllx bp -% \dimen2=\MPlly bp -% \setbox\scratchbox=\hbox{\hskip-\dimen0\raise-\dimen2\box\scratchbox}% -% \ht\scratchbox=\zeropoint -% \dp\scratchbox=\zeropoint -% \wd\scratchbox=\zeropoint -% \hbox -% {\PDFcode{q \MPxscale\space 0 0 \MPyscale\space 0 0 cm}% -% \lower\MPshift\box\scratchbox -% \PDFcode{Q}}}% - -% \let\PDFMPformoffset\zeropoint +\def\convertMPtoPDF#1#2#3% + {\resetMPvariables{#1}{#2}{#3}% + \mkconvertMPtoPDF} -\def\PDFMPformoffset - {\ifx\objectoffset\undefined\zeropoint\else\objectoffset\fi} +\def\processMPtoPDFfile#1#2#3% obsolete + {\resetMPvariables{#1}{#2}{#3}% + \mkprocessMPtoPDFfile} -\chardef\blackoutMPgraphic\plusone % in supp-pdf it's \zerocount +%D A common hook. -\def\finishMPgraphic - {\stopMPresources - \egroup - \setbox\scratchbox\vbox - {\forgetall - \hbox - {\PDFcode{q \MPxscale\space 0 0 \MPyscale\space \MPxoffset\space \MPyoffset\space cm}% - \ifcase\blackoutMPgraphic\or\PDFcode{0 g 0 G}\fi - \lower\MPyshift\box\scratchbox % unscaled shift - \PDFcode{Q}}}% - \ht\scratchbox\MPheight - \wd\scratchbox\MPwidth - \dp\scratchbox\zeropoint\relax - \dopackageMPgraphic\scratchbox - \egroup - \endinput} +\let\MPfshowcommand\empty -%D Alternative for \PDFTEX. We cannot come up with something more contexy -%D because this module is also used in \LATEX. +%D Objects. \def\dopackageMPgraphic#1% #1 = boxregister - {%\ifx\pdfxform\undefined - % \chardef\makeMPintoPDFobject\zerocount % no pdftex at all - %\else\ifx\pdftexversion\undefined - % \chardef\makeMPintoPDFobject\zerocount % no pdftex at all - %\else\ifnum\pdftexversion<14 - % \chardef\makeMPintoPDFobject\zerocount % no resource support - %\else - % % keep the default value - %\fi\fi\fi - \ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else + {\ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else % an existing value of 2 signals object support (set elsewhere) \chardef\makeMPintoPDFobject\plusone \fi\fi @@ -1998,8 +229,6 @@ %D {deleteMPgraphic, %D startMPresources, %D stopMPresources} -%D -%D Here are a few hooks for \CONTEXT\ specific things. \ifx\deleteMPgraphic\undefined \def\deleteMPgraphic#1{} @@ -2010,77 +239,6 @@ \let\stopMPresources\relax \fi -%D \macros -%D {twodigitMPoutput} -%D -%D We can limit the precision to two digits after the comma -%D by saying: -%D -%D \starttyping -%D \twodigitMPoutput -%D \stoptyping -%D -%D This option only works in \CONTEXT\ combined with \ETEX. - -\def\twodigitMPoutput - {\let\!MP \twodigitrounding - \def\!MPgMPs##1{\twodigitrounding{\gMPs##1}}% - \def\!MPgMPa##1{\twodigitrounding{\gMPa##1}}} - -\let\!MP \empty -\let\!MPgMPa\gMPa -\let\!MPgMPs\gMPs - -%D This kind of conversion is possible because \METAPOST\ -%D does all the calculations. Converting other \POSTSCRIPT\ -%D files would drive both me and \TEX\ crazy. - -\ifx\undefined\StopLatexHack \else \StopLatexHack \fi - -\protect % \endinput - -%D \module -%D [ file=supp-mpe, -%D version=1999.07.10, -%D title=\CONTEXT\ Support Macros, -%D subtitle=METAPOST Special Extensions, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -% fuzzy and complicating is the fact that we need to support -% context as well as mptopdf, so we cannot fall back on the -% special drivers and color module (although there may be -% good reasons to use a smaller context instead); also, -% shading is handled here while it should move to the special -% driver - to do! - -%D This module is still experimental and deals with some -%D extensions to \METAPOST. When using \POSTSCRIPT\ output, -%D these extensions can be supplied by means of proper -%D preamble definitions, but when producing \PDF\ we have to -%D set up the appropriate datastructures ourselves. It acts as -%D a plug in into \type {supp-pdf}. As soon as we need more -%D extensions, we will generalize these macro. Some -%D definitions will move to the special drivers. - -%D For usage in plain \TEX, say something: -%D -%D \starttyping -%D \input supp-pdf -%D \input supp-mpe -%D -%D \MPcmykcolorstrue -%D \MPspotcolorstrue -%D \chardef\makeMPintoPDFobject\plusone -%D \stoptyping - -\writestatus{loading}{MetaPost Special Extensions} - %D We implement extensions by using the \METAPOST\ special %D mechanism. Opposite to \TEX's specials, the \METAPOST\ ones %D are flushed before or after the graphic data, but thereby @@ -2124,107 +282,8 @@ %D from to n inner_r g b x y outer_r g b x y %D from to n inner_r g b x y radius outer_r g b x y radius %D \stoptyping -%D -%D The implementation below saves the data on the stack in -%D a way similar to the macros in \type {supp-pdf.tex}, and -%D just overload a few already defined handlers. That way, -%D the existing macros are still generic. \footnote {Actually, -%D the macros here are just as generic.} -%D -%D Currently the only extension concerns shading, which is -%D accomplished by handling yet another value of \type -%D {\finiMPpath}. The recource disctionary is stored and -%D later picked up by the general \CONTEXT\ figure inclusion -%D macros. - -\unprotect - -%D The \type {%%MetaPostSpecials: version.revision signal} line -%D triggers this module into handling color specifications kind -%D of special. We need this safeguard for non||special -%D usage. - -\chardef\MPspecialversion = 0 % specials when >1 -\chardef\MPspecialrevision = 0 % specials when >1 -\chardef\MPspecialsignal = 0 % passed on by graphic - -\chardef\inlineMPspecials = 1 % only needed for stack resetting - -%D This macro handles the special definitions that are -%D passed as comment. - -\def\dohandleMPspecialcomment#1 - {\setMPargument{#1}% - \advance\scratchcounter \minusone - \ifcase\scratchcounter - \handleMPspecialcommand - \donetrue - \doresetMPstack - \let\handleMPsequence\dohandleMPsequence - \expandafter\handleMPsequence - \else - \expandafter\dohandleMPspecialcomment - \fi} - -\def\handleMPspecialcomment #1 % number of arguments - {\doresetMPstack - \scratchcounter#1\relax - \ifcase\scratchcounter % when zero, inline shading is used - \chardef\inlineMPspecials\plusone - \let\handleMPsequence\dohandleMPsequence - \expandafter\handleMPsequence - \else - \chardef\inlineMPspecials\zerocount - \expandafter\dohandleMPspecialcomment - \fi} - -%D When defined inline, we use another macro to handle the -%D definitions. Actually, this macro is called by the -%D previous ones. - -\def\handleMPspecialcommand - {\ifcase\inlineMPspecials\or - \advance\nofMParguments \minusone % pop the size - \fi - \ifundefined\MPspecial - \message{[unknown \MPspecial]}% - \else - \csname\MPspecial\endcsname - \fi - \ifcase\inlineMPspecials - \doresetMPstack % 0 - \else - \resetMPstack % 1 - \fi} - -%D This macro triggers special support. Currently, the -%D version and revision number are not used. Any version number -%D greater than zero will enable special support. - -\newconditional\manyMPspecials % \settrue\manyMPspecials - -\def\handleMPspecialscomment #1.#2 #3 % version.revision signal #4=div=1000|10000 - {\doresetMPstack - \chardef\MPspecialversion #1% - \chardef\MPspecialrevision#2% - \chardef\MPspecialsignal #3% - \let\handleMPsequence\dohandleMPsequence - \ifnum#1=\plusone - \expandafter\handleMPsequence - \else - \expandafter\handleMPspecialscommentx - \fi} - -\def\handleMPspecialscommentx #1 % version 2 -% {\doifelsedoifelse{#1}{10000}{\settrue\manyMPspecials}{\setfalse\manyMPspecials}% local - {\ifnum10000=0#1\relax\settrue\manyMPspecials\else\setfalse\manyMPspecials\fi - \handleMPsequence} -% one can say (in meta-ini): -% -% \prependtoks -% _special_div_ := 1000\ifconditional\manyMPspecials0\fi ; -% \to \MPextensions +\newconditional\manyMPspecials \settrue\manyMPspecials %D In case of \PDF, we need to prepare resourcs. @@ -2232,15 +291,25 @@ \newtoks\MPstopresources \def\startMPresources - {\the\MPstartresources - \ifx\currentPDFresources\empty\else - \message{[unused resources]}% - \fi - \global\let\currentPDFresources\empty} + {\the\MPstartresources} \def\stopMPresources - {\let\currentPDFresources\empty - \the\MPstopresources} + {\the\MPstopresources} + +%D Some day we may consider collecting local resources. + +\appendtoks + \global\let\currentPDFresources\empty % kind of redundant +\to \MPstartresources + +% \appendtoks +% \collectPDFresources +% \global\let\currentPDFresources\collectedPDFresources +% \to \MPstopresources + +\appendtoksonce + \the\everyPDFxform +\to \MPstopresources %D Since colors are not subjected to transformations, we can %D only use colors as signal. In our case, we use a dummy colored @@ -2251,224 +320,139 @@ \newif\ifMPcmykcolors \newif\ifMPspotcolors -\ifx\normalhandleMPrgbcolor\undefined % in case we reload this module - - \let\normalhandleMPrgbcolor \handleMPrgbcolor - \let\normalhandleMPcmykcolor\handleMPcmykcolor - \let\normalhandleMPgraycolor\handleMPgraycolor - \let\normalhandleMPspotcolor\handleMPspotcolor - -\fi - -%D When we are using \CONTEXT, we will fall back to the -%D better color conversion routines. This also has the advantage -%D that we don't have to parse and convert the file. In this -%D alternative, \type {\!MP} is not (yet) supported. Because -%D we can (for efficiency reasons) turn off strokecolor, -%D something we cannot do in \METAPOST\ converted code. - -\newif\ifPDFMPstrokecolor \PDFMPstrokecolortrue - -%D [This code should move to meta-ini.] - -\ifCONTEXT % we can use this for a better xgstate handling - - \def\checkPDFMPstrokecolor - {\ifPDFMPstrokecolor \PDFstrokecolortrue \fi} +\def\dohandleMPrgb #1#2#3{\revokeMPtransparencyspecial\execcolorR #1:#2:#3:0:0\od} +\def\dohandleMPcmyk#1#2#3#4{\revokeMPtransparencyspecial\execcolorC#1:#2:#3:#4:0:0\od} +\def\dohandleMPgray #1{\revokeMPtransparencyspecial\execcolorS #1:0:0\od} +\def\dohandleMPspot#1#2#3#4{\revokeMPtransparencyspecial\execcolorP#1:#2:#3:#4:0:0\od} - \def\normalhandleMPrgbcolor - {{\checkPDFMPstrokecolor\execcolorR\gMPa1:\gMPa2:\gMPa3:0:0\od}} +%D Specials: - \def\normalhandleMPcmykcolor - {{\checkPDFMPstrokecolor\execcolorC\gMPa1:\gMPa2:\gMPa3:\gMPa4:0:0\od}} +\settrue \manyMPspecials \newcount\nofMParguments \let\extraMPpathcode\empty - \def\normalhandleMPgraycolor - {{\checkPDFMPstrokecolor\execcolorS\gMPa1:0:0\od}} - - \def\normalhandleMPspotcolor % ??? - {{\checkPDFMPstrokecolor\execcolorP\gMPa1:\gMPa2:\gMPa3:\gMPa4:0:0\od}} - -\fi - -% In the previous macros we use the special drivers. A more -% direct approach would have been: -% -% \def\doPDFstartrgbcolormode#1#2#3% -% {\PDFcode{#1 #2 #3 rg #1 #2 #3 RG}} -% -% \def\doPDFstartcmykcolormode#1#2#3#4% -% {\PDFcode{#1 #2 #3 #4 k #1 #2 #3 #4 K}} -% -% \def\doPDFstartgraycolormode#1% -% {\PDFcode{#1 g #1 G}} -% -% \appendtoks -% \let\dostartrgbcolormode \doPDFstartrgbcolormode -% \let\dostartcmykcolormode\doPDFstartcmykcolormode -% \let\dostartgraycolormode\doPDFstartgraycolormode -% \to \everyMPtoPDFconversion - -%D Now we can handle special color signals. We only do this -%D when special are detected. - -% \def\MPrgbnumber#1{\expandafter\doMPrgbnumber#1000.0000\relax} -% \def\doMPrgbnumber#1.#2#3#4#5\relax{#2#3#4} +\def\@@MP {@@MP} +\def\@@MPSK{@MPSK@} -%D We cannot use \type {\everyMPtoPDFconversion} because in \MPTOPDF\ -%D we don't have the \type {\appendtoks} macro available. +\def\MPspecial{\@@MPSK\@@MPSK\gMPs\nofMParguments} -\def\setMPextensions - {\ifconditional\manyMPspecials - \def\MPrgbnumber##1{\expandafter\doMPrgbnumber##10000.00000\relax}% - \def\doMPrgbnumber##1.##2##3##4##5##6\relax{##2##3##4##5}% - \else - \def\MPrgbnumber##1{\expandafter\doMPrgbnumber##1000.0000\relax}% - \def\doMPrgbnumber##1.##2##3##4##5\relax{##2##3##4}% - \fi} +\def\defineMPspecial#1#2% + {\setvalue{\@@MPSK\@@MPSK#1}{#2}} -%D The naive case looks like: +%D Special number~1 is dedicated to \CMYK\ support. If you +%D want to know why: look at this: %D -%D \starttyping -%D \def\handleMPrgbcolor% -%D {\setMPcolor -%D \ifcase\MPspecialversion -%D \resetMPcolor\normalhandleMPrgbcolor -%D \else\ifnum\MPrgbnumber\lastMPrvalue=\MPspecialsignal -%D % consider it to be a signal -%D \else -%D \resetMPcolor\normalhandleMPrgbcolor -%D \fi\fi} -%D \stoptyping +%D \startbuffer[mp] +%D fill fullcircle xyscaled (3cm,1cm) withcolor \MPcolor{test} ; +%D \stopbuffer %D -%D However, since we want \CMYK\ support, we will use the -%D following implementation: - -% \def\setMPcolor -% {\edef\lastMPrvalue{\gMPa1}% -% \edef\lastMPgvalue{\gMPa2}% -% \edef\lastMPbvalue{\gMPa3}} -% -% speed up (hardly called, so no let is needed) - -\def\setMPcolor - {\edef\lastMPrvalue{\csname\@@MP01\endcsname}% - \edef\lastMPgvalue{\csname\@@MP02\endcsname}% - \edef\lastMPbvalue{\csname\@@MP03\endcsname}} - -\def\zeroMPrgbvalue{0.0} - -\def\resetMPcolor - {\let\lastMPrvalue\zeroMPrgbvalue - \let\lastMPgvalue\zeroMPrgbvalue - \let\lastMPbvalue\zeroMPrgbvalue} - -\resetMPcolor +%D \startbuffer[cmyk] +%D \startcombination[4*1] +%D {\definecolor[test][c=1,y=.3,k=.3] \processMPbuffer[mp]} {c=1 y=.3 k=.3} +%D {\definecolor[test][c=.9,y=.15] \processMPbuffer[mp]} {c=.9 y=.15} +%D {\definecolor[test][c=.25,y=.8] \processMPbuffer[mp]} {c=.25 y=.8} +%D {\definecolor[test][c=.45,y=.1] \processMPbuffer[mp]} {c=.45 y=.1} +%D \stopcombination +%D \stopbuffer +%D +%D \placefigure +%D {\CMYK\ support disabled, +%D conversion to \RGB.} +%D {\setupcolors[cmyk=nee,state=start]\getbuffer[cmyk]} +%D +%D \placefigure +%D {\CMYK\ support enabled, +%D no support in \METAPOST.} +%D {\setupcolors[cmyk=ja,mpcmyk=nee,state=start]\getbuffer[cmyk]} +%D +%D \placefigure +%D {\CMYK\ support enabled, +%D no conversion to \RGB, +%D support in \METAPOST} +%D {\setupcolors[cmyk=ja,state=start]\getbuffer[cmyk]} -\def\@@MPSK{@MPSK@} -\def\@@MPSP{@MPSP@} +\defineMPspecial{1} + {\ifMPcmykcolors + \setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPcmykcolor{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}}% + \fi} -\def\interceptMPcmykcolor % todo : \ifMPcmykcolors - {\ifcase\MPrgbnumber\lastMPgvalue - % cannot happen - \or - % 1 == cmyk color spec - \ifMPcmykcolors \dointerceptMPcmykcolor \fi - \or - % 2 == spot color - \ifMPspotcolors \dointerceptMPspotcolor \fi - \or - % 3 == rgb transparency - \invokeMPtransparencyspecial - \or - % 4 == cmyk transparency - \ifMPcmykcolors \invokeMPtransparencyspecial \fi - \or - % 5 == spot transparency - \ifMPspotcolors \invokeMPtransparencyspecial \fi - \else - % \writestatus{MPtoPDF}{unknown direct special}% +\defineMPspecial{2} + {\ifMPspotcolors + \setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPspotcolor{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}}% +% \checkMPspot{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}% \fi} -% ifcsname +% \def\checkMPspot#1#2#3#4% +% {\expanded{\resolveMPspotcolor#1 #2 #3 #4}\end +% \ifx\MPspotspace\MPresolvedspace +% \edef\MPspotspacespec{/\MPspotspace\space}% +% \doifinstringelse\MPspotspacespec\currentMPcolorspaces +% \donothing\registerMPcolorspace +% \fi} -\def\dointerceptMPcmykcolor - {\revokeMPtransparencyspecial - \@EA\ifx\csname\@@MPSK\number\MPrgbnumber\lastMPbvalue\endcsname\relax\else - \@EA\@EA\@EA\setMPcmyk\csname\@@MPSK\number\MPrgbnumber\lastMPbvalue\endcsname - \normalhandleMPcmykcolor - \fi} +\let\revokeMPtransparencyspecial\relax -\def\dointerceptMPspotcolor - {\revokeMPtransparencyspecial - \@EA\ifx\csname\@@MPSP\number\MPrgbnumber\lastMPbvalue\endcsname\relax\else - \@EA\@EA\@EA\setMPspot\csname\@@MPSP\number\MPrgbnumber\lastMPbvalue\endcsname - \normalhandleMPspotcolor - \fi} +\def\dohandleMPrgbcolor #1#2#3{\revokeMPtransparencyspecial\execcolorR #1:#2:#3:0:0\od} +\def\dohandleMPcmykcolor#1#2#3#4{\revokeMPtransparencyspecial\execcolorC#1:#2:#3:#4:0:0\od} +\def\dohandleMPgraycolor #1{\revokeMPtransparencyspecial\execcolorS #1:0:0\od} +\def\dohandleMPspotcolor#1#2#3#4{\revokeMPtransparencyspecial\execcolorP#1:#2:#3:#4:0:0\od} -\def\handleMPrgbcolor - {\resetMPcolor - \ifcase\MPspecialversion - \normalhandleMPrgbcolor - \else - \setMPcolor - \ifnum\MPrgbnumber\lastMPrvalue=\MPspecialsignal\relax - \interceptMPcmykcolor - \else - \revokeMPtransparencyspecial - \normalhandleMPrgbcolor - \fi - \fi} +%D Transparency support used specials 60 (rgb) and 61 +%D (cmyk). +%D +%D \startbufferFshade + +%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0); +%D +%D fill p rotated 90 withcolor transparent(1,.5,yellow) ; +%D fill p rotated 210 withcolor transparent(1,.5,green) ; +%D fill p rotated 330 withcolor transparent(1,.5,blue) ; +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlinecorrection \processMPbuffer \stoplinecorrection +%D +%D One can also communicate colors between \CONTEXT\ and +%D \METAPOST: +%D +%D \startbuffer +%D \definecolor[tcyan] [c=1,k=.2,t=.5] +%D \definecolor[tmagenta][m=1,k=.2,t=.5] +%D \definecolor[tyellow] [y=1,k=.2,t=.5] +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0); +%D +%D fill p rotated 90 withcolor \MPcolor{tcyan} ; +%D fill p rotated 210 withcolor \MPcolor{tmagenta} ; +%D fill p rotated 330 withcolor \MPcolor{tyellow} ; +%D \stopbuffer +%D +%D \startlinecorrection \processMPbuffer \stoplinecorrection +%D +%D We save all the three components needed in one macro, +%D just to save hash space. -\def\handleMPgraycolor - {\resetMPcolor - \ifcase\MPspecialversion \else \revokeMPtransparencyspecial \fi - \normalhandleMPgraycolor} +\def\dohandleMPrgbtransparency #1#2#3#4#5{\execcolorR #1:#2:#3:#4:#5\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial} +\def\dohandleMPcmyktransparency#1#2#3#4#5#6{\execcolorC#1:#2:#3:#4:#5:#6\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial} +\def\dohandleMPgraytransparency #1#2#3{\execcolorS #1:#2:#3\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial} +\def\dohandleMPspottransparency#1#2#3#4#5#6{\execcolorP#1:#2:#3:#4:#5:#6\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial} -\def\handleMPcmykcolor - {\resetMPcolor - \ifcase\MPspecialversion \else \revokeMPtransparencyspecial \fi - \normalhandleMPcmykcolor} +\def\dorevokeMPtransparencyspecial + {\PDFcode{\PDFtransparencyresetidentifier\space gs}% + \let\revokeMPtransparencyspecial\relax} -%D Specials are define and recalled using: +\defineMPspecial{3} % rgb + {\setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPrgbtransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs1}{\gMPs2}}} -\def\MPspecial - {MP special \gMPs\nofMParguments} +\defineMPspecial{4} % cmyk + {\setxvalue{\@@MPSK\gMPs7}{\noexpand\dohandleMPcmyktransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs1}{\gMPs2}}} -\def\defineMPspecial#1#2% - {\setvalue{MP special #1}{#2}} - -%D The path processing macro is slightly extended. - -\newtoks \invokeMPspecials - -\def\finishMPpath - {\PDFcode - {\ifcase\finiMPpath W n\or S\or f\or B\else W n\fi - \extraMPpathcode}} - -\def\processMPpath - {\checkMPpath % ! - \ifcase\nofMPsegments\else - \let\extraMPpathcode\empty - \ifcase\MPspecialversion\else - \ifnum\MPrgbnumber\lastMPrvalue=\MPspecialsignal - \ifnum\MPrgbnumber\lastMPgvalue>10 % really needed - \scratchcounter\MPrgbnumber\lastMPbvalue - \edef\currentMPspecial{\the\scratchcounter}% - \ifnum\finiMPpath=2 % to outer level - \the\invokeMPspecials - \fi - \fi - \fi - \fi - \flushMPpath - \closeMPpath - \finishMPpath - \fi - \let\handleMPsequence\dohandleMPsequence - \resetMPstack - \nofMPsegments0 - \handleMPsequence} +\defineMPspecial{5} % spot + {\setxvalue{\@@MPSK\gMPs7}{\noexpand\dohandleMPspottransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs1}{\gMPs2}}% + }%\checkMPspot{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}} %D Shading is an example of a more advanced graphic feature, %D but users will seldom encounter those complications. Here @@ -2605,137 +589,9 @@ %D \stoptabulate \newcount\currentPDFshade % 0 % global (document wide) counter -\let\currentMPshades\empty - -\def\startMPshading#1% - {\edef\currentMPspecial{\gMPs{#1}}} - -\def\stopMPshading - {\global\advance\currentPDFshade \plusone - \setxvalue{obj:Sh:\currentMPspecial}% - {/Sh\the\currentPDFshade\space\the\pdflastobj\space0 R }% - \setxvalue{mps:Sh:\currentMPspecial}% - {\the\currentPDFshade}} - -\appendtoks - \global\let\currentMPshades\empty -\to \MPstartresources - -\appendtoks - \ifx\currentMPshades\empty \else - \xdef\currentPDFresources{\currentPDFresources - /Shading <<\currentMPshades>>}% - \fi -\to \MPstopresources - -\def\invokeMPshadespecial - {\ifundefined{mps:Sh:\currentMPspecial}\else - \edef\currentMPshade{\getvalue{obj:Sh:\currentMPspecial}}% - \doifinstringelse\currentMPshade\currentMPshades \donothing - {\xdef\currentMPshades{\currentMPshades\currentMPshade}}% - \def\extraMPpathcode{/Sh\getvalue{mps:Sh:\currentMPspecial} sh Q}% - \chardef\finiMPpath\zerocount - \PDFcode{q /Pattern cs}% - \fi} - -\appendtoks \invokeMPshadespecial \to \invokeMPspecials - -%D We need to convert the \CMYK\ specials into colors, because -%D we have to do it twice, we define a macro. - -\def\checkMPshadingcolor#1#2#3#4#5% - {\edef\tempMPrvalue{\csname\@@MP0#1\endcsname}% - \edef\tempMPgvalue{\csname\@@MP0#2\endcsname}% - \edef\tempMPbvalue{\csname\@@MP0#3\endcsname}% - \global\let\MPresolvedspace\MPgrayspace - \global\let\MPresolvedcolor\!!zerocount - \ifnum\MPrgbnumber\tempMPrvalue=\MPspecialsignal\relax - \ifcase\MPrgbnumber\tempMPgvalue - \or % 1 = cmyk - \ifMPcmykcolors - \expanded{\resolveMPcmykcolor\getvalue{\@@MPSK\number\MPrgbnumber\tempMPbvalue}}\end - \fi - \or % 2 = spot - \ifMPspotcolors - \expanded{\resolveMPspotcolor\getvalue{\@@MPSP\number\MPrgbnumber\tempMPbvalue}}\end - \fi - \or - % 3 = rgb transparency - % to do - \or - % 4 == cmyk transparency - % \ifMPcmykcolors - % to do - % \fi - \or - % 5 == spot transparency - % \ifMPspotcolors - % to do - % \fi - \fi - \else - \ifx\tempMPrvalue\tempMPgvalue - \ifx\tempMPrvalue\tempMPbvalue - \expanded{\resolveMPgraycolor\tempMPbvalue}\end - \else - \expanded{\resolveMPrgbcolor\tempMPrvalue\space\tempMPgvalue\space\tempMPbvalue}\end - \fi - \else - \expanded{\resolveMPrgbcolor\tempMPrvalue\space\tempMPgvalue\space\tempMPbvalue}\end - \fi - \fi - \let#4\MPresolvedcolor - \let#5\MPresolvedspace} - -%D We also need to make sure that we have two \RGB\ or -%D \CMYK colors, since we have to set the colorspace. - -\def\setMPshadingcolors#1#2#3#4#5#6% color space - {\checkMPshadingcolor{#1}{#2}{#3}\MPshadeAc\MPshadeAs - \checkMPshadingcolor{#4}{#5}{#6}\MPshadeBc\MPshadeBs - \ifx\MPshadeAs\MPshadeBs - \let\MPshadeA\MPshadeAc - \let\MPshadeB\MPshadeBc - \let\MPshadeC\MPshadeAs - \else\ifx\MPshadeAs\MPgrayspace - \ifx\MPshadeBs\MPrgbspace - \edef\MPshadeA{\MPshadeAc\space\MPshadeAc\space\MPshadeAc}% - \else - \negatecolorcomponent\MPshadeAc - \edef\MPshadeA{0 0 0 \MPshadeAc}% - \fi - \let\MPshadeB\MPshadeBc - \let\MPshadeC\MPshadeBs - \else\ifx\MPshadeBs\MPgrayspace - \let\MPshadeA\MPshadeAc - \ifx\MPshadeAs\MPrgbspace - \edef\MPshadeB{\MPshadeBc\space\MPshadeBc\space\MPshadeBc}% - \else - \negatecolorcomponent\MPshadeBc - \edef\MPshadeB{0 0 0 \MPshadeBc}% - \fi - \let\MPshadeC\MPshadeAs - \else - % different color spaces - \def\MPshadeA{1}% - \def\MPshadeB{1}% - \let\MPshadeC\MPgrayspace - \fi\fi\fi} - -\let\MPshadeA\MPcmykWhite -\let\MPshadeB\MPcmykBlack -\let\MPshadeC\MPgrayspace -%D The reason why this macro is a bit complicates is that we -%D handle black and white situations (otherwise we would have -%D to use \CMYK\ b/w in case of a \CMYK\ shade). - -%D Here are the special handlers: - -\defineMPspecial{30} - {\startMPshading{14}% type 2 - \setMPshadingcolors{4}{5}{6}{9}{10}{11}% - \immediate\pdfobj +\def\dosetMPlinearshade#1% + {\immediate\pdfobj {<</FunctionType 2 /Domain [\gMPs1 \gMPs2] /C0 [\MPshadeA] @@ -2743,16 +599,34 @@ /N \gMPs3>>}% \immediate\pdfobj {<</ShadingType 2 - /ColorSpace /\MPshadeC\space + /ColorSpace /\MPresolvedspace /Function \the\pdflastobj\space 0 R - /Coords [\gMPs7 \gMPs8 \gMPs{12} \gMPs{13}] + /Coords [\MPshadeC] /Extend [true true]>>}% - \stopMPshading} + \global\advance\currentPDFshade \plusone + \appendtoPDFdocumentshades{/Sh\the\currentPDFshade\space\the\pdflastobj\space0 R }% + \setxvalue{\@@MPSK#1}{\noexpand\dohandleMPshade{\the\currentPDFshade}}} -\defineMPspecial{31} - {\startMPshading{16}% type 3 - \setMPshadingcolors{4}{5}{6}{10}{11}{12}% - \immediate\pdfobj +\defineMPspecial{30} + {\expanded{\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA + \expanded{\resolveMPrgbcolor{\gMPs{9}}{\gMPs{10}}{\gMPs{11}}}\to\MPshadeB + \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs{12} \gMPs{13}}% + \dosetMPlinearshade{\gMPs{14}}} + +\defineMPspecial{32} + {\expanded{\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA + \expanded{\resolveMPcmykcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB + \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}% + \dosetMPlinearshade{\gMPs{16}}} + +\defineMPspecial{34} + {\expanded{\resolveMPspotcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA + \expanded{\resolveMPspotcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB + \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}% + \dosetMPlinearshade{\gMPs{16}}} + +\def\dosetMPcircularshade#1% + {\immediate\pdfobj {<</FunctionType 2 /Domain [\gMPs1 \gMPs2] /C0 [\MPshadeA] @@ -2760,29 +634,52 @@ /N \gMPs3>>}% \immediate\pdfobj {<</ShadingType 3 - /ColorSpace /\MPshadeC\space + /ColorSpace /\MPresolvedspace /Function \the\pdflastobj\space 0 R - /Coords [\gMPs7 \gMPs8 \gMPs9 \gMPs{13} \gMPs{14} \gMPs{15}] + /Coords [\MPshadeC] /Extend [true true]>>}% - \stopMPshading} + \global\advance\currentPDFshade \plusone + \appendtoPDFdocumentshades{/Sh\the\currentPDFshade\space\the\pdflastobj\space0 R }% + \setxvalue{\@@MPSK#1}{\noexpand\dohandleMPshade{\the\currentPDFshade}}} + +\defineMPspecial{31} + {\expanded{\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA + \expanded{\resolveMPrgbcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}}\to\MPshadeB + \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs9 \gMPs{13} \gMPs{14} \gMPs{15}}% + \dosetMPcircularshade{\gMPs{16}}} + +\defineMPspecial{33} + {\expanded{\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA + \expanded{\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB + \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}% + \dosetMPcircularshade{\gMPs{18}}} + +\defineMPspecial{35} + {\expanded{\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA + \expanded{\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB + \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}% + \dosetMPcircularshade{\gMPs{18}}} + +\newconditional\ignoreMPpath + +\def\dohandleMPshade#1% + {\revokeMPtransparencyspecial + \settrue\ignoreMPpath + \def\extraMPpathcode{/Sh#1 sh Q}% + \chardef\finiMPpath\zerocount + \PDFcode{q /Pattern cs}} %D Figure inclusion is kind of strange to \METAPOST, but when %D Santiago Muelas started discussing this with me, I was able %D to cook up a solution using specials. -\def\invokeMPfigurespecial% - {\getvalue{mps:gr:\currentMPspecial}} % or \relax - -\appendtoks \invokeMPfigurespecial \to \invokeMPspecials - \defineMPspecial{10} - {\setxvalue{mps:gr:\gMPs8}% - {\noexpand\handleMPfigurespecial - {\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}% - \noexpand\setxvalue{mps:gr:\gMPs8}{}}} + {\setxvalue{\@@MPSK\gMPs8}% + {\noexpand\handleMPfigurespecial{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}{\gMPs8}}} -\def\handleMPfigurespecial#1#2#3#4#5#6#7% todo : combine with ext fig - {\vbox to \zeropoint +\def\handleMPfigurespecial#1#2#3#4#5#6#7#8% todo : combine with ext fig + {\global\letvalue{\@@MPSK#8}\empty + \vbox to \zeropoint {\vss \hbox to \zeropoint {\ifcase\pdfoutput\or % will be hooked into the special driver @@ -2820,99 +717,23 @@ %D for Mark Wicks. \defineMPspecial{20} - {\setxvalue{mps:hl:\gMPs6}% - {\noexpand\handleMPhyperlink - {\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}% - \noexpand\setxvalue{mps:hl:\gMPs6}{}}} - -\def\handleMPhyperlink#1#2#3#4#5% - {%\ifcase\pdfoutput\or - \setbox\scratchbox\hbox - {\setbox\scratchbox\null - \scratchdimen#1\onebasepoint\scratchdimen-\scratchdimen - \advance\scratchdimen#3\onebasepoint - \wd\scratchbox\scratchdimen - \scratchdimen#2\onebasepoint\scratchdimen-\scratchdimen - \advance\scratchdimen#4\onebasepoint - \ht\scratchbox\scratchdimen - \incolorfalse - \gotobox{\box\scratchbox}[#5]}% - \setbox\scratchbox\hbox - {\scratchdimen\MPxoffset\onebasepoint\advance\scratchdimen#1\onebasepoint - \hskip\scratchdimen - \scratchdimen\MPyoffset\onebasepoint\advance\scratchdimen#2\onebasepoint - \raise\scratchdimen\box\scratchbox}% - \smashbox\scratchbox - \box\scratchbox - }%\fi} - -\def\invokeMPhyperlinkspecial% - {\getvalue{mps:hl:\currentMPspecial}} % or \relax - -\appendtoks \invokeMPhyperlinkspecial \to \invokeMPspecials - -%D Special number~1 is dedicated to \CMYK\ support. If you -%D want to know why: look at this: -%D -%D \startbuffer[mp] -%D fill fullcircle xyscaled (3cm,1cm) withcolor \MPcolor{test} ; -%D \stopbuffer -%D -%D \startbuffer[cmyk] -%D \startcombination[4*1] -%D {\definecolor[test][c=1,y=.3,k=.3] \processMPbuffer[mp]} {c=1 y=.3 k=.3} -%D {\definecolor[test][c=.9,y=.15] \processMPbuffer[mp]} {c=.9 y=.15} -%D {\definecolor[test][c=.25,y=.8] \processMPbuffer[mp]} {c=.25 y=.8} -%D {\definecolor[test][c=.45,y=.1] \processMPbuffer[mp]} {c=.45 y=.1} -%D \stopcombination -%D \stopbuffer -%D -%D \placefigure -%D {\CMYK\ support disabled, -%D conversion to \RGB.} -%D {\setupcolors[cmyk=nee,state=start]\getbuffer[cmyk]} -%D -%D \placefigure -%D {\CMYK\ support enabled, -%D no support in \METAPOST.} -%D {\setupcolors[cmyk=ja,mpcmyk=nee,state=start]\getbuffer[cmyk]} -%D -%D \placefigure -%D {\CMYK\ support enabled, -%D no conversion to \RGB, -%D support in \METAPOST} -%D {\setupcolors[cmyk=ja,state=start]\getbuffer[cmyk]} + {\setxvalue{\@@MPSK\gMPs6}% + {\noexpand\handleMPhyperlink{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}}} -\defineMPspecial{1} - {\ifMPcmykcolors - \setxvalue{\@@MPSK\gMPs1}{\gMPs2 \gMPs3 \gMPs4 \gMPs5 }% - \fi} - -\def\setMPcmyk#1 #2 #3 #4 % - {\setvalue{\@@MP01}{#1}% - \setvalue{\@@MP02}{#2}% - \setvalue{\@@MP03}{#3}% - \setvalue{\@@MP04}{#4}} - -\defineMPspecial{2} - {\ifMPspotcolors - \setxvalue{\@@MPSP\gMPs1}{\gMPs2 \gMPs3 \gMPs4 \gMPs5 }% space is essential - \checkMPspot{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}% - \fi} - -\def\setMPspot#1 #2 #3 #4 % - {\setvalue{\@@MP01}{#1}% - \setvalue{\@@MP02}{#2}% - \setvalue{\@@MP03}{#3}% - \setvalue{\@@MP04}{#4}} - -\def\checkMPspot#1#2#3#4% - {\expanded{\resolveMPspotcolor#1 #2 #3 #4}\end - \ifx\MPspotspace\MPresolvedspace - \edef\MPspotspacespec{/\MPspotspace\space}% - \doifinstringelse\MPspotspacespec\currentMPcolorspaces - \donothing\registerMPcolorspace - \fi} +\def\handleMPhyperlink#1#2#3#4#5#6% + {\global\letvalue{\@@MPSK#6}\empty + \setbox\scratchbox\hbox + {\setbox\scratchbox\null + \wd\scratchbox\dimexpr-#1\onebasepoint+#3\onebasepoint\relax + \ht\scratchbox\dimexpr-#2\onebasepoint+#4\onebasepoint\relax + \incolorfalse + \gotobox{\box\scratchbox}[#5]}% + \setbox\scratchbox\hbox + {\hskip\dimexpr\MPxoffset\onebasepoint+#1\onebasepoint\relax + \raise\dimexpr\MPyoffset\onebasepoint+#2\onebasepoint\relax + \box\scratchbox}% + \smashbox\scratchbox + \box\scratchbox} %D This special (number 50) passes positions to a tex file. %D This method uses a two||pass approach an (mis|)|used the @@ -2958,268 +779,17 @@ %D \setMPlayer [test] [somepos-2] {Whatever we need there!} %D \stoptyping -\ifx\dosavepositionwhd\undefined - \let\dosavepositionwhd\gobblesevenarguments -\fi - \defineMPspecial{50} % x y width height label - {\bgroup - \scratchdimen\MPllx\onebasepoint\scratchdimen-\scratchdimen - % \scratchdimen-\MPllx\onebasepoint % moet ook werken - \advance\scratchdimen\gMPs1\onebasepoint - \edef\x{\number\scratchdimen}% - \scratchdimen\gMPs2\onebasepoint - \scratchdimen-\scratchdimen - \advance\scratchdimen\MPury\onebasepoint - \edef\y{\number\scratchdimen}% - \scratchdimen\gMPs3\onebasepoint - \edef\w{\number\scratchdimen}% - \scratchdimen\gMPs4\onebasepoint - \edef\h{\number\scratchdimen}% - \dosavepositionwhd{\gMPs5}0\x\y\w\h0% - \egroup} - -%D Transparency support used specials 60 (rgb) and 61 -%D (cmyk). -%D -%D \startbuffer -%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0); -%D -%D fill p rotated 90 withcolor transparent(1,.5,yellow) ; -%D fill p rotated 210 withcolor transparent(1,.5,green) ; -%D fill p rotated 330 withcolor transparent(1,.5,blue) ; -%D \stopbuffer -%D -%D \typebuffer -%D -%D \startlinecorrection \processMPbuffer \stoplinecorrection -%D -%D One can also communicate colors between \CONTEXT\ and -%D \METAPOST: -%D -%D \startbuffer -%D \definecolor[tcyan] [c=1,k=.2,t=.5] -%D \definecolor[tmagenta][m=1,k=.2,t=.5] -%D \definecolor[tyellow] [y=1,k=.2,t=.5] -%D \stopbuffer -%D -%D \typebuffer \getbuffer -%D -%D \startbuffer -%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0); -%D -%D fill p rotated 90 withcolor \MPcolor{tcyan} ; -%D fill p rotated 210 withcolor \MPcolor{tmagenta} ; -%D fill p rotated 330 withcolor \MPcolor{tyellow} ; -%D \stopbuffer -%D -%D \startlinecorrection \processMPbuffer \stoplinecorrection -%D -%D We save all the three components needed in one macro, -%D just to save hash space. - -\def\@@MPST{@MPST@} - -\def\assignMPStransparency#1#2#3% - {\edef\PDFtransparencyidentifier{#1}% - \edef\PDFtransparencyreference {#2}% - \edef\PDFtransparencycolorspecs{#3}} - -\def\PDFtransparencyspec % todo - {\ifx\MPresolvedspace\MPgrayspace - \MPresolvedcolor\space g - \MPresolvedcolor\space G% - \else\ifx\MPresolvedspace\MPrgbspace - \MPresolvedcolor\space rg - \MPresolvedcolor\space RG% - \else\ifx\MPresolvedspace\MPcmykspace - \MPresolvedcolor\space k - \MPresolvedcolor\space K% - \else\ifx\MPresolvedspace\empty\else - /\MPresolvedspace\space cs - /\MPresolvedspace\space CS - \PDFgetspotcolorspec\MPresolvedcolor - \fi\fi\fi\fi} - -\defineMPspecial{3} % rgb - {\edef\currentMPspecial{\gMPs6}% - \presetPDFtransparency{\gMPs1}{\gMPs2}% - \expanded{\resolveMPrgbcolor\gMPs3 \gMPs4 \gMPs5}\end - \setevalue{\@@MPST\currentMPspecial}% was \setxvalue, bug ! - {\noexpand\assignMPStransparency - {\PDFtransparencyidentifier}% - {\PDFtransparencyreference}% - {\PDFtransparencyspec}}} - -\defineMPspecial{4} % cmyk - {\edef\currentMPspecial{\gMPs7}% - \presetPDFtransparency{\gMPs1}{\gMPs2}% - \expanded{\resolveMPcmykcolor\gMPs3 \gMPs4 \gMPs5 \gMPs6}\end - \setevalue{\@@MPST\currentMPspecial}% was \setxvalue, bug ! - {\noexpand\assignMPStransparency - {\PDFtransparencyidentifier}% - {\PDFtransparencyreference}% - {\PDFtransparencyspec}}} - -\defineMPspecial{5} % spot - {\edef\currentMPspecial{\gMPs7}% - \presetPDFtransparency{\gMPs1}{\gMPs2}% - \checkMPspot{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}% - \setevalue{\@@MPST\currentMPspecial}% was \setxvalue, bug ! - {\noexpand\assignMPStransparency - {\PDFtransparencyidentifier}% - {\PDFtransparencyreference}% - {\PDFtransparencyspec}}} - -% beware: for the moment only supported in pdftex; needs a cleanup! - -\def\registerMPcolorspace - {\doifobjectreferencefoundelse{PDFCS}\MPspotspace - {\doPDFgetobjectreference{PDFCS}\MPspotspace\PDFobjectreference - \xdef\currentMPcolorspaces - {\currentMPcolorspaces\MPspotspacespec\PDFobjectreference\space}} - \donothing} - -%D We need to add resource specifications! - -\appendtoks - \global\let\currentMPcolorspaces\empty -\to \MPstartresources - -\appendtoks - \ifx\currentMPcolorspaces\empty \else - \xdef\currentPDFresources{\currentPDFresources - /ColorSpace <<\currentMPcolorspaces>>}% - \fi -\to \MPstopresources - -%D For efficiency reasons, we fall back on the allocation -%D mechanisms already present. For use within \MPTOPDF, we -%D provide a fall back routine. - -\let\currentMPtransparencies\empty - -% this one triggers a new graphic state - -\def\invokeMPtransparencyspecial - {\scratchcounter\MPrgbnumber\lastMPbvalue - \edef\currentMPspecial{\the\scratchcounter}% - \ifundefined{\@@MPST\currentMPspecial}\else - \getvalue{\@@MPST\currentMPspecial}% - \doifinstringelse\PDFtransparencyidentifier\currentMPtransparencies - \donothing\registerMPtransparencyresource % slow - \PDFcode - {\PDFtransparencycolorspecs\space - \PDFtransparencyidentifier\space gs}% - % potential optimization - % \setevalue{\@@MPST\currentMPspecial}% - % {\PDFcode - % {\PDFtransparencycolorspecs\space - % \PDFtransparencyidentifier\space gs}}% - % \getvalue{\@@MPST\currentMPspecial}% - \let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial - \fi} - -% this one does a reset - -\let\revokeMPtransparencyspecial\relax - -\appendtoks - \revokeMPtransparencyspecial -\to \MPstopresources - -\def\dorevokeMPtransparencyspecial % only called if state is set - {\ifx\PDFtransparencyresetidentifier\empty\else - \doifinstringelse\PDFtransparencyresetidentifier\currentMPtransparencies - \donothing\registerMPtransparencyresetresource - \PDFcode{\PDFtransparencyresetidentifier\space gs}% - % potential optimization - % \def\dorevokeMPtransparencyspecial - % {\PDFcode - % {\PDFtransparencycolorspecs\space - % \PDFtransparencyidentifier\space gs}}% - \let\dorevokeMPtransparencyspecial\dodorevokeMPtransparencyspecial - \let\revokeMPtransparencyspecial\relax % invoke sets it - \fi} - -% and this one does a simplified reset - -\def\dodorevokeMPtransparencyspecial % used after first invocation - {\PDFcode{\PDFtransparencyresetidentifier\space gs}% - \let\revokeMPtransparencyspecial\relax} % invoke sets it - -% add a resource entry + {\dosavepositionwhd + {\gMPs5}% + {0}% + {\the\dimexpr-\MPllx\onebasepoint+\gMPs1\onebasepoint\relax} + {\the\dimexpr\gMPs2\onebasepoint-\scratchdimen+\MPury\onebasepoint\relax}% + {\the\dimexpr\gMPs3\onebasepoint\relax}% + {\the\dimexpr\gMPs4\onebasepoint\relax}% + {0pt}} -\def\registerMPtransparencyresource - {\xdef\currentMPtransparencies - {\currentMPtransparencies - \PDFtransparencyidentifier\space - \PDFtransparencyreference\space}} - -\def\registerMPtransparencyresetresource - {\xdef\currentMPtransparencies - {\currentMPtransparencies - \PDFtransparencyresetidentifier\space - \PDFtransparencyresetreference\space}} - -\appendtoks \invokeMPtransparencyspecial \to \invokeMPspecials - -\ifCONTEXT \else - - \def\@@MPSTN{@MPSTN@} - \def\@@MPSTO{@MPSTO@} - - \newcount\PDFcurrenttransparency - - \let\PDFtransparencyresetidentifier\empty - \let\PDFtransparencyresetreference \empty - - \let\PDFtransparencyidentifier\empty - \let\PDFtransparencyreference \empty - - \def\initializePDFtransparency - {\global\let\initializePDFtransparency\relax - \presetPDFtransparency{1}{1}% - \xdef\PDFtransparencyresetidentifier{/Tr0}% - \xdef\PDFtransparencyresetreference{\the\pdflastobj\space 0 R}} - - \def\presetPDFtransparency#1#2% - {\initializePDFtransparency - \@EA\ifx\csname\@@MPSTO#1:#2\endcsname\relax - \global\advance\PDFcurrenttransparency \plusone - \immediate\pdfobj{\PDFtransparencydictionary{#1}{#2}{}}% - \setxvalue{\@@MPSTN#1:#2}{\the\PDFcurrenttransparency}% - \setxvalue{\@@MPSTO#1:#2}{\the\pdflastobj}% - \fi - \edef\PDFtransparencyidentifier{/Tr\getvalue{\@@MPSTN#1:#2}}% - \edef\PDFtransparencyreference{\getvalue{\@@MPSTO#1:#2} 0 R}} - - \def\PDFtransparencydictionary#1#2#3% type fraction extras - {<</Type /ExtGState - /ca #2 /CA #2 - /BM /\ifcase#1 Normal\or Normal\or Multiply\or Screen\or - Overlay\or SoftLight\or HardLight\or ColorDodge\or - ColorBurn\or Darken\or Lighten\or Difference\or - Exclusion\else Compatible\fi - #3>>} - -\fi - -\appendtoks - \global\let\currentMPtransparencies\empty -\to \MPstartresources - -\appendtoks - \ifx\currentMPtransparencies\empty \else - \xdef\currentPDFresources{\currentPDFresources - /ExtGState <<\currentMPtransparencies>>}% - \fi -\to \MPstopresources - -%D In all cases, we need to keep track of the resources -%D used. - -%D A few auxiliary macros: +%D A few auxiliary macros. This will move to colo-ini. \def\MPgrayspace{DeviceGray} \def\MPrgbspace {DeviceRGB} @@ -3229,72 +799,52 @@ \def\MPcmykBlack{0 0 0 0} \def\MPcmykWhite{0 0 0 1} -\ifCONTEXT - - \def\startMPcolorresolve - {\bgroup - \def\dostartgraycolormode##1% - {\global\let\MPresolvedspace\MPgrayspace - \xdef\MPresolvedcolor{##1}}% - \def\dostartrgbcolormode ##1##2##3% - {\global\let\MPresolvedspace\MPrgbspace - \xdef\MPresolvedcolor{##1 ##2 ##3}}% - \def\dostartcmykcolormode##1##2##3##4% - {\global\let\MPresolvedspace\MPcmykspace - \xdef\MPresolvedcolor{##1 ##2 ##3 ##4}}% - \def\dostartspotcolormode##1##2% - {\global\let\MPspotspace\empty - \xdef\MPresolvedspace{##1}% - \xdef\MPresolvedcolor{##2}% - \global\let\MPspotspace\MPresolvedspace}% signal - \dostartgraycolormode\!!zerocount} % kind of hackery initialization - - \let\stopMPcolorresolve\egroup - - \def\resolveMPrgbcolor#1 #2 #3\end - {\startMPcolorresolve - \execcolorR#1:#2:#3:0:0\od - \stopMPcolorresolve} - - \def\resolveMPcmykcolor#1 #2 #3 #4\end - {\startMPcolorresolve - \execcolorC#1:#2:#3:#4:0:0\od - \stopMPcolorresolve} - - \def\resolveMPgraycolor#1\end - {\startMPcolorresolve - \execcolorS#1:0:0\od - \stopMPcolorresolve} - - \def\resolveMPspotcolor#1 #2 #3 #4\end - {\startMPcolorresolve - \ifnum#2>\plusone - \checkmultitonecolor{#1}% - \fi - \execcolorP#1:#2:#3:#4:0:0\od - \stopMPcolorresolve} - -\else - - \def\resolveMPspotcolor#1 #2\end - {\global\let\MPresolvedspace\MPgrayspace - \xdef\MPresolvedcolor{0}} - - \def\resolveMPrgbcolor#1 #2 #3\end - {\global\let\MPresolvedspace\MPrgbspace - \xdef\MPresolvedcolor{#1 #2 #3}} - - \def\resolveMPcmykcolor#1 #2 #3 #4\end - {\global\let\MPresolvedspace\MPcmykspace - \xdef\MPresolvedcolor{#1 #2 #3 #4}} - - \def\resolveMPgraycolor#1\end - {\global\let\MPresolvedspace\MPgrayspace - \xdef\MPresolvedcolor{#1}} % should be inverted - -\fi - -%D Begin of soon obsolete code. +\def\startMPcolorresolve + {\bgroup + \def\dostartgraycolormode##1% + {\global\let\MPresolvedspace\MPgrayspace + \xdef\MPresolvedcolor{##1}}% + \def\dostartrgbcolormode ##1##2##3% + {\global\let\MPresolvedspace\MPrgbspace + \xdef\MPresolvedcolor{##1 ##2 ##3}}% + \def\dostartcmykcolormode##1##2##3##4% + {\global\let\MPresolvedspace\MPcmykspace + \xdef\MPresolvedcolor{##1 ##2 ##3 ##4}}% + \def\dostartspotcolormode##1##2% + {\global\let\MPspotspace\empty + \xdef\MPresolvedspace{##1}% + \xdef\MPresolvedcolor{##2}% + \global\let\MPspotspace\MPresolvedspace}% signal + \dostartgraycolormode\!!zerocount} % kind of hackery initialization + +\let\stopMPcolorresolve\egroup + +\def\resolveMPrgbcolor#1#2#3\to#4% + {\startMPcolorresolve + \execcolorR#1:#2:#3:0:0\od + \stopMPcolorresolve + \let#4\MPresolvedcolor} + +\def\resolveMPcmykcolor#1#2#3#4\to#5% + {\startMPcolorresolve + \execcolorC#1:#2:#3:#4:0:0\od + \stopMPcolorresolve + \let#5\MPresolvedcolor} + +\def\resolveMPgraycolor#1\end\to#2% + {\startMPcolorresolve + \execcolorS#1:0:0\od + \stopMPcolorresolve + \let#2\MPresolvedcolor} + +\def\resolveMPspotcolor#1#2#3#4\end\to#5% + {\startMPcolorresolve + \ifnum#2>\plusone + \checkmultitonecolor{#1}% + \fi + \execcolorP#1:#2:#3:#4:0:0\od + \stopMPcolorresolve + \let#5\MPresolvedcolor} %D \macros %D {dogetPDFmediabox} @@ -3338,10 +888,10 @@ \doprocessfile\scratchread{#1}\doprocessPDFline \egroup \ifx\PDFxoffset\undefined - #2\zeropoint - #3\zeropoint - #4\zeropoint - #5\zeropoint + #2=\zeropoint + #3=\zeropoint + #4=\zeropoint + #5=\zeropoint \else #2=\PDFxoffset\onebasepoint #3=\PDFyoffset\onebasepoint @@ -3362,12 +912,53 @@ \global\let\PDFyoffset\PDFyoffset} \def\setPDFmediabox#1[#2 #3 #4 #5]#6\done - {\dimen2=#2bp\dimen2=-\dimen2 % \dimen2=-#2bp also works since tex handles -- - \dimen4=#3bp\dimen4=-\dimen4 % \dimen4=-#3bp also works since tex handles -- - \dimen6=#4bp\advance\dimen6 \dimen2 - \dimen8=#5bp\advance\dimen8 \dimen4 + {\dimen2=#2\onebasepoint\dimen2=-\dimen2 % \dimen2=-#2\onebasepoint also works since tex handles -- + \dimen4=#3\onebasepoint\dimen4=-\dimen4 % \dimen4=-#3\onebasepoint also works since tex handles -- + \dimen6=#4\onebasepoint\advance\dimen6 \dimen2 + \dimen8=#5\onebasepoint\advance\dimen8 \dimen4 \setPDFboundingbox{\dimen2}{\dimen4}{\dimen6}{\dimen8}\PDFxscale\PDFyscale} %D End of soon obsolete code. +%D The plugins: + +\startMPinitializations + mp_shade_version := 2 ; +\stopMPinitializations + +\loadmarkfile{meta-pdf} + +%D Test code: + +% \startMPcode +% fill fullcircle scaled 3cm withcolor red ; +% fill fullcircle scaled 2cm withcolor green ; +% fill fullcircle scaled 1cm withcolor blue ; +% currentpicture := currentpicture shifted (-4cm,0) ; +% fill fullcircle scaled 3cm withcolor cmyk(0,0,1,0) ; +% fill fullcircle scaled 2cm withcolor cmyk(0,1,0,0) ; +% fill fullcircle scaled 1cm withcolor cmyk(0,0,1,0) ; +% currentpicture := currentpicture shifted (-4cm,0) ; +% draw fullcircle scaled 3cm dashed evenly ; +% draw fullcircle scaled 2cm dashed withdots ; +% draw origin withpen pencircle scaled 3mm; +% currentpicture := currentpicture shifted (-4cm,0) ; +% fill fullcircle scaled 2cm shifted (-.5cm,+.5cm) withcolor transparent(1,.5,red); +% fill fullcircle scaled 2cm shifted (-.5cm,-.5cm) withcolor transparent(1,.5,red); +% fill fullcircle scaled 2cm shifted (+.5cm,+.5cm) withcolor transparent(1,.5,green); +% fill fullcircle scaled 2cm shifted (+.5cm,-.5cm) withcolor transparent(1,.5,cmyk(1,0,1,.5)); +% currentpicture := currentpicture shifted (12cm,-4cm) ; +% draw "o e p s" infont defaultfont scaled 2 shifted (-1cm,0) ; +% currentpicture := currentpicture shifted (-4cm,0) ; +% % bug: shift +% draw fullcircle scaled 3cm withpen pencircle yscaled 3mm xscaled 2mm rotated 30 ; +% draw fullcircle scaled 2cm withpen pencircle yscaled 3mm xscaled 2mm rotated 20 withcolor red ; +% filldraw fullcircle scaled 1cm withpen pencircle yscaled 3mm xscaled 2mm rotated 10 withcolor green ; +% currentpicture := currentpicture shifted (-4cm,0) ; +% % shade cannot handle shift +% circular_shade(fullcircle scaled 3cm,0,.2red,.9green) ; +% circular_shade(fullcircle scaled 3cm shifted(+4cm,0),0,cmyk(1,0,0,0),cmyk(0,1,0,0)) ; +% filldraw boundingbox currentpicture enlarged -3cm withpen pencircle scaled 1pt withcolor .5white ; +% \stopMPcode + \protect \endinput |