You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1371 lines
42 KiB
1371 lines
42 KiB
%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 ADE \& \CONTEXT\ Development Team}]
|
|
%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 \makeMPintoPDFobject\plusone
|
|
%D \stoptyping
|
|
|
|
\ifx\writestatus\undefined
|
|
\immediate\write16{[Loading MPS to PDF extensions.]}
|
|
\else
|
|
\writestatus{loading}{ConTeXt Support Macros / MPS extensions}
|
|
\fi
|
|
|
|
%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
|
|
%D are no longer connected to a position.
|
|
%D
|
|
%D We implement specials by overloading the \type {fill}
|
|
%D operator. By counting the fills, we can let the converter
|
|
%D treat the appropriate fill in a special way. The
|
|
%D specification of the speciality can have two forms,
|
|
%D determined by the setting of a boolean variable:
|
|
%D
|
|
%D \starttyping
|
|
%D _inline_specials_ := false ; % comment like code (default)
|
|
%D _inline_specials_ := true ; % command like code
|
|
%D \stoptyping
|
|
%D
|
|
%D When the specification is embedded as comment, it looks
|
|
%D like:
|
|
%D
|
|
%D \starttyping
|
|
%D %%MetaPostSpecial <size> <data> <number> <identifier>
|
|
%D \stoptyping
|
|
%D
|
|
%D The in||line alternative is more tuned for \POSTSCRIPT,
|
|
%D since it permits us to define a macro \type {special}.
|
|
%D
|
|
%D \starttyping
|
|
%D inline : <data> <number> <identifier> <size> special
|
|
%D \stoptyping
|
|
%D
|
|
%D The \type {identifier} determines what to do, and the data
|
|
%D can be used to accomplish this. A type~2 shading function
|
|
%D has identifier~2. Alltogether, the number of parameters is
|
|
%D specified in \type {size}. The \type {number} is the number
|
|
%D of the fill that needs the special treatment. For a type~2
|
|
%D and~3 shaded fill, the datablock contains the following
|
|
|
|
%D data:
|
|
%D
|
|
%D \starttyping
|
|
%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
|
|
\setMPextensions
|
|
\handleMPsequence}
|
|
|
|
% one can say (in meta-ini):
|
|
%
|
|
% \prependtoks
|
|
% _special_div_ := 1000\ifconditional\manyMPspecials0\fi ;
|
|
% \to \MPextensions
|
|
|
|
%D In case of \PDF, we need to prepare resourcs.
|
|
|
|
\newtoks\MPstartresources
|
|
\newtoks\MPstopresources
|
|
|
|
\def\startMPresources
|
|
{\the\MPstartresources
|
|
\ifx\currentPDFresources\empty\else
|
|
\message{[unused resources]}%
|
|
\fi
|
|
\global\let\currentPDFresources\empty}
|
|
|
|
\def\stopMPresources
|
|
{\let\currentPDFresources\empty
|
|
\the\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
|
|
%D path with a red color component of \type {0.n}, so \type
|
|
%D {0.001} is the first path and \type {0.010} the tenth. Since
|
|
%D \METAPOST strips trailing zeros, we have to padd the string.
|
|
|
|
\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\normalhandleMPrgbcolor
|
|
{{\checkPDFMPstrokecolor\execcolorR\gMPa1:\gMPa2:\gMPa3:0:0\od}}
|
|
|
|
\def\normalhandleMPcmykcolor
|
|
{{\checkPDFMPstrokecolor\execcolorC\gMPa1:\gMPa2:\gMPa3:\gMPa4:0:0\od}}
|
|
|
|
\def\normalhandleMPgraycolor
|
|
{{\checkPDFMPstrokecolor\execcolorS\gMPa1:0:0\od}}
|
|
|
|
% \def\normalhandleMPspotcolor
|
|
% {{\checkPDFMPstrokecolor\execcolorP\gMPa1:\gMPa2: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}
|
|
|
|
%D We cannot use \type {\everyMPtoPDFconversion} because in \MPTOPDF\
|
|
%D we don't have the \type {\appendtoks} macro available.
|
|
|
|
\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}
|
|
|
|
%D The naive case looks like:
|
|
%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
|
|
%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
|
|
|
|
\def\@@MPSK{@MPSK@}
|
|
\def\@@MPSP{@MPSP@}
|
|
|
|
\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}%
|
|
\fi}
|
|
|
|
% ifcsname
|
|
|
|
\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}
|
|
|
|
\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\handleMPrgbcolor
|
|
{\resetMPcolor
|
|
\ifcase\MPspecialversion
|
|
\normalhandleMPrgbcolor
|
|
\else
|
|
\setMPcolor
|
|
\ifnum\MPrgbnumber\lastMPrvalue=\MPspecialsignal\relax
|
|
\interceptMPcmykcolor
|
|
\else
|
|
\revokeMPtransparencyspecial
|
|
\normalhandleMPrgbcolor
|
|
\fi
|
|
\fi}
|
|
|
|
\def\handleMPgraycolor
|
|
{\resetMPcolor
|
|
\ifcase\MPspecialversion \else \revokeMPtransparencyspecial \fi
|
|
\normalhandleMPgraycolor}
|
|
|
|
\def\handleMPcmykcolor
|
|
{\resetMPcolor
|
|
\ifcase\MPspecialversion \else \revokeMPtransparencyspecial \fi
|
|
\normalhandleMPcmykcolor}
|
|
|
|
%D Specials are define and recalled using:
|
|
|
|
\def\MPspecial
|
|
{MP special \gMPs\nofMParguments}
|
|
|
|
\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}%
|
|
\let\previousMPcolorspec\currentMPcolorspec
|
|
\edef\currentMPcolorspec{\lastMPrvalue\lastMPgvalue\lastMPbvalue}%
|
|
\ifx\previousMPcolorspec\currentMPcolorspec \else
|
|
\revokeMPtransparencyspecial
|
|
\fi
|
|
\ifnum\finiMPpath=2 % to outer level
|
|
\the\invokeMPspecials
|
|
\fi
|
|
\fi
|
|
\fi
|
|
\fi
|
|
\flushMPpath
|
|
\closeMPpath
|
|
\finishMPpath
|
|
\fi
|
|
\let\handleMPsequence\dohandleMPsequence
|
|
\resetMPstack
|
|
\nofMPsegments0
|
|
\handleMPsequence}
|
|
|
|
%D Shading is an example of a more advanced graphic feature,
|
|
%D but users will seldom encounter those complications. Here
|
|
%D we only show a few simple examples, but many other
|
|
%D alternatives are possible by setting up the functions built
|
|
%D in \PDF\ in the appropriate way.
|
|
%D
|
|
%D Shading has to do with interpolation between two or more
|
|
%D points or user supplied ranges. In \PDF, the specifications
|
|
%D of a shade has to be encapsulated in objects and passed on
|
|
%D as resources. This is a \PDF\ level 1.3. feature. One can
|
|
%D simulate three dimensional shades as well and define simple
|
|
%D functions using a limited set of \POSTSCRIPT\ primitives.
|
|
%D Given the power of \METAPOST\ and these \PDF\ features, we
|
|
%D can achieve superb graphic effects.
|
|
%D
|
|
%D Since everything is hidden in \TEX\ and \METAPOST\ graphics,
|
|
%D we can stick to high level \CONTEXT\ command, as shown in
|
|
%D the following exmples.
|
|
%D
|
|
%D \startbuffer
|
|
%D \startuniqueMPgraphic{CircularShade}
|
|
%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
|
|
%D circular_shade(p,0,.2red,.9red) ;
|
|
%D \stopuniqueMPgraphic
|
|
%D
|
|
%D \startuniqueMPgraphic{LinearShade}
|
|
%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
|
|
%D linear_shade(p,0,.2blue,.9blue) ;
|
|
%D \stopuniqueMPgraphic
|
|
%D
|
|
%D \startuniqueMPgraphic{DuotoneShade}
|
|
%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
|
|
%D linear_shade(p,2,.5green,.5red) ;
|
|
%D \stopuniqueMPgraphic
|
|
%D \stopbuffer
|
|
%D
|
|
%D \typebuffer
|
|
%D
|
|
%D \getbuffer
|
|
%D
|
|
%D These graphics can be hooked into the overlay mechanism,
|
|
%D which is available in many commands.
|
|
%D
|
|
%D \startbuffer
|
|
%D \defineoverlay[demo 1][\uniqueMPgraphic{CircularShade}]
|
|
%D \defineoverlay[demo 2][\uniqueMPgraphic {LinearShade}]
|
|
%D \defineoverlay[demo 3][\uniqueMPgraphic {DuotoneShade}]
|
|
%D \stopbuffer
|
|
%D
|
|
%D \typebuffer
|
|
%D
|
|
%D \getbuffer
|
|
%D
|
|
%D These backgrounds can for instance be applied to \type
|
|
%D {\framed}:
|
|
%D
|
|
%D \startbuffer
|
|
%D \setupframed[width=3cm,height=2cm,frame=off]
|
|
%D \startcombination[3*1]
|
|
%D {\framed[background=demo 1]{\bfd \white Demo 1}} {}
|
|
%D {\framed[background=demo 2]{\bfd \white Demo 2}} {}
|
|
%D {\framed[background=demo 3]{\bfd \white Demo 3}} {}
|
|
%D \stopcombination
|
|
%D \stopbuffer
|
|
%D
|
|
%D \typebuffer
|
|
%D
|
|
%D \startlinecorrection
|
|
%D \getbuffer
|
|
%D \stoplinecorrection
|
|
%D
|
|
%D There are a few more alternatives, determined by the second
|
|
%D parameter passed to \type {circular_shade} and alike.
|
|
%D
|
|
%D \def\SomeShade#1#2#3#4#5%
|
|
%D {\startuniqueMPgraphic{Shade-#1}
|
|
%D width := \overlaywidth ;
|
|
%D height := \overlayheight ;
|
|
%D path p ; p := unitsquare xscaled width yscaled height ;
|
|
%D #2_shade(p,#3,#4,#5) ;
|
|
%D \stopuniqueMPgraphic
|
|
%D \defineoverlay[Shade-#1][\uniqueMPgraphic{Shade-#1}]%
|
|
%D \framed[backgroundachtergrond=Shade-#1,width=2cm,height=2cm,frame=off]{}}
|
|
%D
|
|
%D \startlinecorrection
|
|
%D \startcombination[5*1]
|
|
%D {\SomeShade{10}{circular}{0}{.3blue}{.9blue}} {circular 0}
|
|
%D {\SomeShade{11}{circular}{1}{.3blue}{.9blue}} {circular 1}
|
|
%D {\SomeShade{12}{circular}{2}{.3blue}{.9blue}} {circular 2}
|
|
%D {\SomeShade{13}{circular}{3}{.3blue}{.9blue}} {circular 3}
|
|
%D {\SomeShade{14}{circular}{4}{.3blue}{.9blue}} {circular 4}
|
|
%D \stopcombination
|
|
%D \stoplinecorrection
|
|
%D
|
|
%D \blank
|
|
%D
|
|
%D \startlinecorrection
|
|
%D \startcombination[5*1]
|
|
%D {\SomeShade{20}{circular}{0}{.9green}{.3green}} {circular 0}
|
|
%D {\SomeShade{21}{circular}{1}{.9green}{.3green}} {circular 1}
|
|
%D {\SomeShade{22}{circular}{2}{.9green}{.3green}} {circular 2}
|
|
%D {\SomeShade{23}{circular}{3}{.9green}{.3green}} {circular 3}
|
|
%D {\SomeShade{24}{circular}{4}{.9green}{.3green}} {circular 4}
|
|
%D \stopcombination
|
|
%D \stoplinecorrection
|
|
%D
|
|
%D \blank
|
|
%D
|
|
%D \startlinecorrection
|
|
%D \startcombination[4*1]
|
|
%D {\SomeShade{30}{linear}{0}{.3red}{.9red}} {linear 0}
|
|
%D {\SomeShade{31}{linear}{1}{.3red}{.9red}} {linear 1}
|
|
%D {\SomeShade{32}{linear}{2}{.3red}{.9red}} {linear 2}
|
|
%D {\SomeShade{33}{linear}{3}{.3red}{.9red}} {linear 3}
|
|
%D \stopcombination
|
|
%D \stoplinecorrection
|
|
%D
|
|
%D These macros closely cooperate with the \METAPOST\ module
|
|
%D \type {mp-spec.mp}, which is part of the \CONTEXT\
|
|
%D distribution.
|
|
%D
|
|
%D The low level (\PDF) implementation is based on the \TEX\
|
|
%D based \METAPOST\ to \PDF\ converter. Shading is supported
|
|
%D by overloading the \type {fill} operator as implemented
|
|
%D earlier. In \PDF\ type~2 and~3 shading functions are
|
|
%D specified in terms of:
|
|
%D
|
|
%D \starttabulate[|Tl|l|]
|
|
%D \NC /Domain \NC sort of meeting range \NC \NR
|
|
%D \NC /C0 \NC inner shade \NC \NR
|
|
%D \NC /C1 \NC outer shade \NC \NR
|
|
%D \NC /N \NC smaller values, bigger inner circles \NC \NR
|
|
%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}%
|
|
% \edef#5%
|
|
% {\ifx\tempMPrvalue\tempMPgvalue
|
|
% \ifx\tempMPrvalue\tempMPbvalue
|
|
% \ifx\tempMPgvalue\tempMPbvalue
|
|
% \tempMPbvalue
|
|
% \fi
|
|
% \fi
|
|
% \fi}%
|
|
% \edef#4% todo : spotcolors
|
|
% {\ifnum\MPrgbnumber\tempMPrvalue=\MPspecialsignal\space
|
|
% \ifMPcmykcolors\getvalue{\@@MPSK\number\MPrgbnumber\tempMPbvalue}\fi
|
|
% \fi}}
|
|
|
|
\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
|
|
{<</FunctionType 2
|
|
/Domain [\gMPs1 \gMPs2]
|
|
/C0 [\MPshadeA]
|
|
/C1 [\MPshadeB]
|
|
/N \gMPs3>>}%
|
|
\immediate\pdfobj
|
|
{<</ShadingType 2
|
|
/ColorSpace /\MPshadeC\space
|
|
/Function \the\pdflastobj\space 0 R
|
|
/Coords [\gMPs7 \gMPs8 \gMPs{12} \gMPs{13}]
|
|
/Extend [true true]>>}%
|
|
\stopMPshading}
|
|
|
|
\defineMPspecial{31}
|
|
{\startMPshading{16}% type 3
|
|
\setMPshadingcolors{4}{5}{6}{10}{11}{12}%
|
|
\immediate\pdfobj
|
|
{<</FunctionType 2
|
|
/Domain [\gMPs1 \gMPs2]
|
|
/C0 [\MPshadeA]
|
|
/C1 [\MPshadeB]
|
|
/N \gMPs3>>}%
|
|
\immediate\pdfobj
|
|
{<</ShadingType 3
|
|
/ColorSpace /\MPshadeC\space
|
|
/Function \the\pdflastobj\space 0 R
|
|
/Coords [\gMPs7 \gMPs8 \gMPs9 \gMPs{13} \gMPs{14} \gMPs{15}]
|
|
/Extend [true true]>>}%
|
|
\stopMPshading}
|
|
|
|
%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}{}}}
|
|
|
|
% \def\handleMPfigurespecial#1#2#3#4#5#6#7%
|
|
% {\vbox to 0pt
|
|
% {\vss
|
|
% \hbox to 0pt
|
|
% {\pdfliteral{q #1 #2 #3 #4 #5 #6 cm}%
|
|
% \pdfimage width 1bp height 1bp {#7}% maybe 10 is better
|
|
% \pdfliteral{Q}%
|
|
% \hss}}}
|
|
%
|
|
% better, since xform reuse
|
|
|
|
\def\handleMPfigurespecial#1#2#3#4#5#6#7% todo : combine with ext fig
|
|
{\vbox to \zeropoint
|
|
{\vss
|
|
\hbox to \zeropoint
|
|
{\ifcase\pdfoutput\or % will be hooked into the special driver
|
|
\doiffileelse{#7}
|
|
{\doifundefinedelse{mps:x:#7}
|
|
{\immediate\pdfximage\!!width\onebasepoint\!!height\onebasepoint{#7}%
|
|
\setxvalue{mps:x:#7}{\pdfrefximage\the\pdflastximage}}%
|
|
{\message{[reusing figure #7]}}%
|
|
\PDFcode{q #1 #2 #3 #4 #5 #6 cm}%
|
|
\rlap{\getvalue{mps:x:#7}}%
|
|
\PDFcode{Q}}
|
|
{\message{[unknown figure #7]}}%
|
|
\fi
|
|
\hss}}}
|
|
|
|
%D An example of using both special features is the
|
|
%D following.
|
|
%D
|
|
%D \starttyping
|
|
%D \startMPpage
|
|
%D externalfigure "hakker1b.png" scaled 22cm rotated 10 shifted (-2cm,0cm);
|
|
%D externalfigure "hakker1b.png" scaled 10cm rotated -10 ;
|
|
%D externalfigure "hakker1b.png" scaled 7cm rotated 45 shifted (8cm,12cm) ;
|
|
%D path p ; p := unitcircle xscaled 15cm yscaled 20cm;
|
|
%D path q ; q := p rotatedaround(center p,90) ;
|
|
%D path r ; r := buildcycle(p,q) ; clip currentpicture to r ;
|
|
%D path s ; s := boundingbox currentpicture enlarged 5mm ;
|
|
%D picture c ; c := currentpicture ; currentpicture := nullpicture ;
|
|
%D circular_shade(s,0,.2red,.9red) ;
|
|
%D addto currentpicture also c ;
|
|
%D \stopMPpage
|
|
%D \stoptyping
|
|
|
|
%D This is some experimental hyperlink driver that I wrote
|
|
%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]}
|
|
|
|
\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 }%
|
|
% \fi}
|
|
|
|
% \defineMPspecial{2}
|
|
% {\ifMPspotcolors
|
|
% \setxvalue{\@@MPSP\gMPs1}{\gMPs2 \gMPs3 }%
|
|
% \checkMPspot{\gMPs2}{\gMPs3}%
|
|
% \fi}
|
|
%
|
|
% \def\setMPspot#1 #2 %
|
|
% {\setvalue{\@@MP01}{#1}%
|
|
% \setvalue{\@@MP02}{#2}}
|
|
%
|
|
% \def\checkMPspot#1#2%
|
|
% {\expanded{\resolveMPspotcolor#1 #2}\end
|
|
% \ifx\MPspotspace\MPresolvedspace
|
|
% \edef\MPspotspacespec{/\MPspotspace\space}%
|
|
% \doifinstringelse\MPspotspacespec\currentMPcolorspaces
|
|
% \donothing\registerMPcolorspace
|
|
% \fi}
|
|
|
|
\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}
|
|
|
|
%D This special (number 50) passes positions to a tex file.
|
|
%D This method uses a two||pass approach an (mis|)|used the
|
|
%D context positioning macros. In \type {core-pos} we will
|
|
%D implement the low level submacro needed.
|
|
%D
|
|
%D \startbuffer
|
|
%D \definelayer[test]
|
|
%D
|
|
%D \setlayer
|
|
%D [test]
|
|
%D [x=\MPx{somepos-1},y=\MPy{somepos-1}]
|
|
%D {Whatever we want here!}
|
|
%D
|
|
%D \setlayer
|
|
%D [test]
|
|
%D [x=\MPx{somepos-2},y=\MPy{somepos-2}]
|
|
%D {Whatever we need there!}
|
|
%D
|
|
%D \startuseMPgraphic{oeps}
|
|
%D draw fullcircle scaled 6cm withcolor red ;
|
|
%D register ("somepos-1",1cm,2cm,center currentpicture) ;
|
|
%D register ("somepos-2",4cm,3cm,(-1cm,-2cm)) ;
|
|
%D \stopuseMPgraphic
|
|
%D
|
|
%D \framed[background=test,offset=overlay]{\useMPgraphic{oeps}}
|
|
%D \stopbuffer
|
|
%D
|
|
%D \typebuffer
|
|
%D
|
|
%D Here the width and height are not realy used, but one can
|
|
%D imagine situations where tex has to work with values
|
|
%D calculated by \METAPOST.
|
|
%D
|
|
%D \startlinecorrection
|
|
%D \getbuffer
|
|
%D \stoplinecorrection
|
|
%D
|
|
%D Later we will implement a more convenient macro:
|
|
%D
|
|
%D \starttyping
|
|
%D \setMPlayer [test] [somepos-1] {Whatever we want here!}
|
|
%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
|
|
% {\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 \MPresolvedcolor\space sc
|
|
% /\MPresolvedspace\space CS \MPresolvedcolor\space SC%
|
|
% \fi\fi\fi\fi}
|
|
|
|
\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{\gMPs5}%
|
|
% \presetPDFtransparency{\gMPs1}{\gMPs2}%
|
|
% \checkMPspot{\gMPs3}{\gMPs4}%
|
|
% \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
|
|
|
|
% \def\invokeMPtransparencyspecial
|
|
% {\doifdefined{\@@MPST\currentMPspecial}
|
|
% {\getvalue{\@@MPST\currentMPspecial}%
|
|
% \doifinstringelse
|
|
% {\PDFtransparencyidentifier}{\currentMPtransparencies}
|
|
% {}
|
|
% {\xdef\currentMPtransparencies
|
|
% {\currentMPtransparencies
|
|
% \PDFtransparencyidentifier\space
|
|
% \PDFtransparencyreference\space}}%
|
|
% \def\extraMPpathcode{ Q}%
|
|
% \PDFcode{q
|
|
% \PDFtransparencycolorspecs\space
|
|
% \PDFtransparencyidentifier\space gs}}}
|
|
|
|
% 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 a simplified reset
|
|
|
|
% \def\dodorevokeMPtransparencyspecial % used after first invocation
|
|
% {\getvalue{\@@MPST0}%
|
|
% \PDFcode{\PDFtransparencyidentifier\space gs}}
|
|
|
|
\def\dodorevokeMPtransparencyspecial % used after first invocation
|
|
{\PDFcode{\PDFtransparencyresetidentifier\space gs}%
|
|
\let\revokeMPtransparencyspecial\relax} % invoke sets it
|
|
|
|
% add a resource entry
|
|
|
|
\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\or Hue\or Saturation\or Color\or
|
|
Luminosity\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:
|
|
|
|
\def\MPgrayspace{DeviceGray}
|
|
\def\MPrgbspace {DeviceRGB}
|
|
\def\MPcmykspace{DeviceCMYK}
|
|
\let\MPspotspace\MPgrayspace
|
|
|
|
\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\end
|
|
% {\startMPcolorresolve
|
|
% \execcolorP#1:#2: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
|
|
|
|
\protect \endinput
|
|
|