summaryrefslogtreecommitdiff
path: root/tex/context/base/spec-tpd.mkii
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/spec-tpd.mkii')
-rw-r--r--tex/context/base/spec-tpd.mkii1334
1 files changed, 1334 insertions, 0 deletions
diff --git a/tex/context/base/spec-tpd.mkii b/tex/context/base/spec-tpd.mkii
new file mode 100644
index 000000000..6af3b1272
--- /dev/null
+++ b/tex/context/base/spec-tpd.mkii
@@ -0,0 +1,1334 @@
+%D \module
+%D [ file=spec-tpd,
+%D version=1996.01.25,
+%D title=\CONTEXT\ Special Macros,
+%D subtitle=\PDFTEX,
+%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.
+
+% once we can be sure that the latest versions of pdftex are
+% available we can use:
+%
+% \pdfobj reserveobjnum \edef\one{\the\pdflastobj}
+% \pdfobj reserveobjnum \edef\two{\the\pdflastobj}
+%
+% \pdfobj useobjnum \one {x}
+% \pdfobj useobjnum \two {x}
+%
+% we then can rewrite part of spec-fdf because the other drivers
+% already support symbolic references
+
+% layers and links don't work while the spec says they should
+
+% method = auto
+%
+% \definefileinsertion{tpd}{auto}%
+% {\executesystemcommand{t:/ruby/pstopdf.rb #2}%
+% \dofileinsertion{tpd}{pdf}}
+
+% \let\PDFdestvoffset\zeropoint
+% \newbox\pdfdestbox
+%
+% \def\doPDFdestination#1%
+% {\ifdim\PDFdestvoffset=\zeropoint\relax
+% \pdfdest name {#1}\PDFpageviewkey
+% \else
+% \setbox\pdfdestbox\hbox to \zeropoint
+% {\raise\PDFdestvoffset\hbox{\pdfdest name {#1}\PDFpageviewkey}}%
+% \ht\pdfdestbox\zeropoint
+% \box\pdfdestbox
+% \fi}
+%
+% \def\PDFdestvoffset{2\lineheight} % {1.5\strutht}
+
+%D \macros
+%D {jobsuffix}
+%D
+%D Being one of the first typographical systems able to support
+%D advances \PDF\ support, \TEX\ is also one of the first
+%D systems to produce high quality \PDF\ code directly. Thanks
+%D to Han The Thanh c.s. the \TEX\ community can leap forward
+%D once again.
+%D
+%D One important characteristic of \PDFTEX\ is that is can
+%D produce standard \DVI\ code as well as \PDF\ code. This
+%D enables us to use one format file to support both output
+%D formats.
+
+%D All modules in this group use specials to tell drivers what
+%D non||\TEX\ actions to take. Because from the \TEX\ point of
+%D view, there is no difference between \DVI\ and \PDF, we
+%D therefore only have to bend the \DVI\ driver support into
+%D \PDF\ support. Technically spoken, specials no longer serve
+%D a purpose, except from ending up as comment in the \PDF\
+%D file.
+%D
+%D Before we continue we need to make sure if indeed those
+%D \PDFTEX\ primitives are permitted. If no primitives are
+%D available, we just stop reading any further.
+
+\unprotect
+
+\ifx\pdftexversion\undefined
+ \writestatus\m!systems{you should use pdfTeX binaries}\wait
+ \protect\expandafter\endinput
+\fi
+
+\ifnum\pdftexversion<13
+ \writestatus\m!systems{your pdfTeX version is much too old}\wait
+ \protect\expandafter\endinput
+\fi
+
+\ifnum\pdftexversion<14
+ \writestatus\m!systems{please update your pdfTeX binaries}
+\fi
+
+\ifnum\pdftexversion>19
+ \pdfhorigin=1 true in
+ \pdfvorigin=1 true in
+\fi
+
+%D We default to 300 dots per inch image resolution and 600 dpi
+%D bitmap fonts (when asked for).
+
+\ifx\pdfimageresolution\undefined \newcount\pdfimageresolution \fi
+\ifx\pdfpkresolution \undefined \newcount\pdfpkresolution \fi
+
+\pdfimageresolution=300
+\pdfpkresolution =600
+
+%D Another downward compatible hack:
+
+\ifx\pdflastximagepages\undefined
+ \newcount\pdflastximagepages \pdflastximagepages=1
+\fi
+
+%D And:
+
+\ifx\pdfpageresources\undefined
+ \newtoks\pdfpageresources
+\fi
+
+%D In order to get high quality \METAPOST\ inclusion, we set
+%D the number of digits to~5 (prevents rounding errors).
+
+\ifx\pdfdecimaldigits\undefined
+ \newcount\pdfdecimaldigits
+\fi
+
+\pdfdecimaldigits=10
+
+\ifx\pdfinclusionerrorlevel\undefined
+ \ifx\pdfoptionpdfinclusionerrorlevel\undefined
+ \newcount\pdfinclusionerrorlevel
+ \else
+ \let\pdfinclusionerrorlevel\pdfoptionpdfinclusionerrorlevel
+ \fi
+\fi
+
+\pdfinclusionerrorlevel=0
+
+\ifx\pdfminorversion\undefined
+ \ifx\pdfoptionpdfminorversion\undefined
+ \newcount\pdfminorversion
+ \else
+ \let\pdfminorversion\pdfoptionpdfminorversion
+ \fi
+\fi
+
+\pdfminorversion=5
+
+\def\PDFversion{1.\number\pdfminorversion}
+
+% %D Why are the Acrobat viewers so buggy? To prevent font cache
+% %D mismatches, we say:
+%
+% \ifx\pdfuniqueresname\undefined \else
+% \pdfuniqueresname=1
+% \fi
+
+%D Once we are sure that we're indeed supporting \PDFTEX, we
+%D force \PDF\ output at the highest compression. For debugging
+%D purposes one can set the compresslevel to~0. We also have to
+%D make sure no other specials are supported, else \PDFTEX\
+%D will keep on telling us that we're wrong. We also load the
+%D general \PDF\ macros that are shared between this driver and
+%D the \ACROBAT\ one.
+
+\startspecials[tpd][reset,fdf]
+
+%D This means that by saying
+%D
+%D \starttyping
+%D \usespecials[tpd]
+%D \stoptyping
+%D
+%D we get ourselves full \PDF\ output.
+
+%D For some internal testing we need to know the output
+%D suffix.
+
+\setjobsuffix{pdf}
+
+%D We don't use specials here, which means that we must flush
+%D settings before the page is shipped out.
+
+\specialbasedsettingsfalse
+
+%D Some more internal settings.
+
+\appendtoksonce
+ \pdfoutput\zerocount
+\to \everyresetspecials
+
+\pdfoutput=1 % we reset that one with \everyresetspecials
+
+%D Just in case we mimmick specials, we have to make sure no
+%D default specials end up in the process.
+
+\let\defaultspecial=\gobbleoneargument
+
+\appendtoksonce
+ \let\defaultspecial\normalspecial
+\to \everyresetspecials
+
+\let\PDFcode \pdfliteral
+\def\PDFcontentcode{\pdfliteral}
+\def\PDFdirectcode {\pdfliteral direct}
+
+%D \macros
+%D {everyPDFximage}
+%D
+%D This token register is flushed before an ximage is loaded.
+
+\ifdefined\everyPDFximage \else \newtoks\everyPDFximage \fi
+\ifdefined\everyPDFxform \else \newtoks\everyPDFxform \fi
+
+%D \macros
+%D {dosetuppaper}
+%D
+%D If we don't set the paper size, \PDFTEX\ will certainly do
+%D it in a way we don't want, therefore we need:
+
+\definespecial\dosetuppaper#1#2#3%
+ {\global\pdfpagewidth #2\relax
+ \global\pdfpageheight#3\relax}
+
+%D \macros
+%D {doloadmapfile,doloadmapline,doresetmapfilelist}
+
+\ifx\pdfmapfile\undefined \let\pdfmapfile\gobbletwoarguments \fi
+\ifx\pdfmapline\undefined \let\pdfmapline\gobbletwoarguments \fi
+
+\definespecial\doresetmapfilelist
+ {\global\let\doresetmapfilelist\relax
+ \pdfmapfile{original-empty.map}}
+
+\ifnum\pdftexversion<120
+
+ \definespecial\doloadmapfile #1#2{\pdfmapfile{+#2}}
+ \definespecial\doloadmapline #1#2{}
+
+\else
+
+ \definespecial\doloadmapfile #1#2{\pdfmapfile{#1#2}}
+ \definespecial\doloadmapline #1#2{\pdfmapline{#1#2}}
+
+\fi
+
+%D nasty but needed
+
+\appendtoksonce \loadallfontmapfiles \to \everyPDFximage
+\appendtoksonce \loadallfontmapfiles \to \everyPDFxform
+
+%D \macros
+%D {doinsertfile,dogetnofinsertpages}
+%D
+%D Graphics are not part of \TEX\ and therefore not part of the
+%D \DVI\ standard. \PDF\ on the other hand has several graphic
+%D primitives. During the multi||step process \TEX\
+%D $\rightarrow$ \DVI\ $\rightarrow$ \POSTSCRIPT\ $\rightarrow$
+%D \PDF\ one can insert graphics using specials. In \PDFTEX\
+%D however there is only one step! This means that \PDFTEX\
+%D itself has to do the inclusion.
+%D
+%D At the moment \PDFTEX\ supports inclusion of bitmap \PNG\
+%D graphics as well as not too complicated \PDF\ code. Using
+%D this last option, we are able to include both \METAPOST\ and
+%D \PDF\ output produced by \GHOSTSCRIPT.
+%D
+%D We fall back on the generic \CONTEXT\ module supp-pdf to
+%D accomplish \PDF\ inclusion. The methods implemented there
+%D are hooked into both the figure placement mechanisms of
+%D \CONTEXT\ and the specials inclusion mechanism.
+
+\definespecial\doinsertfile
+ {\dofileinsertion{tpd}{\truegraphictype\@@DriverImageType}}
+
+%D The number of pages in (for instance an \PDF) insert
+%D file, can be asked for using:
+
+\definespecial\dogetnofinsertpages#1%
+ {\xdef\nofinsertpages{1}% global
+ \doifvalidpdfimagefileelse{#1}%
+ {\pdfximage{#1}\xdef\nofinsertpages{\the\pdflastximagepages}}
+ {}}
+
+%D Currently we support \type{pdf} for \PDF\ files, \type{mps}
+%D for \METAPOST\ graphics, \type{png} and \type{jpg} for
+%D bitmap graphics.
+
+\definefileinsertion{tpd}{mps}
+ {\hbox
+ {\convertMPtoPDF\@@DriverImageFile{1}{1}%
+ \global\let\PDFimagereference\empty}}
+
+\definefileinsertion{tpd}{pdf}{\handlepdfimage}
+\definefileinsertion{tpd}{png}{\handlepdfimage}
+\definefileinsertion{tpd}{jpg}{\handlepdfimage}
+\definefileinsertion{tpd}{jb2}{\handlepdfimage}
+
+% \definefileinsertion{tpd}{jpeg} {\handlepdfimage}
+% \definefileinsertion{tpd}{jbig2}{\handlepdfimage}
+
+%D Experimental:
+
+%D The main file insertion macro is as follows. Because
+%D \PDFTEX\ does not support arbitrary suffixes, we double
+%D check on a user supplied filename, because \PDFTEX\ chokes
+%D on unknown suffixes.
+
+\def\doifvalidpdfimagefileelse#1% todo: greedy split
+ {\doiffileelse{#1}
+ {\edef\filesuffix{#1}%
+ \doloop
+ {\@EA\aftersplitstring\filesuffix\at.\to\temp
+ \ifx\temp\empty
+ \exitloop
+ \else
+ \lowercasestring\temp\to\filesuffix % insertion check also needs lowercase
+ % a temporary hack
+ \doif\filesuffix{pdf}{\pdfimageresolution72}%
+ % because pdfTeX scales back
+ \fi}}
+ {\let\filesuffix\s!unknown}%
+ \doiffileinsertionsupportedelse\filesuffix}
+
+\ifx\pdflastximagepages\undefined \chardef\pdflastximagepages=1 \fi
+
+\def\checkpdfimagepagenumber
+ {\edef\pdfimagepagenumber
+ {\ifx\@@DriverImagePage\empty\else\ifnum\@@DriverImagePage>\zerocount
+ \space page\space\@@DriverImagePage\space
+ \fi\fi}}
+
+\ifnum\pdftexversion>13
+
+ \def\handlepdfimage
+ {\bgroup
+ \the\everyPDFximage
+ \doifvalidpdfimagefileelse\@@DriverImageFile
+ {\checkpdfimagepagenumber
+ \ifx\pdfimagepagenumber\empty\@EA\pdfimmediateximage\else\@EA\pdfximage\fi
+ \ifdim\@@DriverImageWidth >\zeropoint \!!width \@@DriverImageWidth \fi
+ \ifdim\@@DriverImageHeight>\zeropoint \!!height\@@DriverImageHeight\fi
+ \pdfimagepagenumber
+ \@@DriverImageBox
+ {\@@DriverImageFile}
+ \xdef\PDFimagereference{\the\pdflastximage}%
+ \xdef\nofinsertpages{\the\pdflastximagepages}%
+ \pdfrefximage\pdflastximage}
+ {\framed[\c!width=\@@DriverImageWidth,\c!height=\@@DriverImageHeight]{\@@DriverImageFile}}%
+ \egroup}
+
+\else
+
+ \def\handlepdfimage
+ {\bgroup
+ \doifvalidpdfimagefileelse\@@DriverImageFile
+ {\pdfimage
+ \ifdim\@@DriverImageWidth >\zeropoint \!!width \@@DriverImageWidth \fi
+ \ifdim\@@DriverImageHeight>\zeropoint \!!height \@@DriverImageHeight\fi
+ {\@@DriverImageFile}}%
+ {\framed[\c!width=\@@DriverImageWidth,\c!height=\@@DriverImageHeight]{\@@DriverImageFile}}%
+ \egroup}
+
+\fi
+
+%D As we will see now, \PDFTEX\ not only directly supports
+%D \type{mps}, \type{png}, \type{pdf}, \type{jpg} but also
+%D \type{mov}. In \CONTEXT\ we support movie inserts in a way
+%D similar to figure inclusion. The next macro calls the
+%D general \PDF\ one.
+
+\definefileinsertion{tpd}{mov}{\doPDFinsertmov}
+\definefileinsertion{tpd}{avi}{\doPDFinsertmov}
+
+%D \macros
+%D {doinsertsoundtrack}
+%D
+%D We use numbers instead of labels to keep track of sounds.
+
+\definespecial\doinsertsoundtrack{\doPDFinsertsoundtrack}
+
+%D For the moment we don't test for alternatives that
+%D themselves have alternatives, especially cylcic
+%D dependencies.
+
+% some day we will do a proper check on bitmap depth,
+%
+% \pdfobj reserveobjnum\relax
+% \pdfximage colorspace \pdflastobj {some file}
+% ... \pdflastximagecolordepth ...
+% \immediate\pdfobj useobjnum \pdflastobj {some spec}
+
+\ifx\@@DriverImageBox\undefined \def\@@DriverImageBox{artbox} \fi
+
+\def\pdfimmediateximage{\immediate\pdfximage}
+
+\ifnum\pdftexversion>13
+
+ \def\checkpdfimageattributes
+ {\ifx\PDFfigurereference\empty
+ \global\let\pdfimageattributes\empty
+ \else
+ \immediate\pdfobj
+ {[ << /Image \PDFobjref\PDFfigurereference
+ /DefaultForPrinting true >> ]}%
+ \xdef\pdfimageattributes
+ {attr {/Alternates \PDFobjref\pdflastobj}}%
+ \fi}
+
+ \global\let\PDFimagecolorreference\empty
+
+ \def\checkpdfimagecolorspecs
+ {\ifx\pdflastximagecolordepth \undefined
+ \global\let\pdfimagecolorspecs\empty
+ \else\ifx\PDFimagecolorreference\empty
+ \global\let\pdfimagecolorspecs\empty
+ \else
+ \xdef\pdfimagecolorspecs{colorspace \PDFimagecolorreference\space}%
+ \fi\fi
+ \global\let\PDFimagecolorreference\empty}
+
+ \def\dogetTPDfiguresize
+ {\doifvalidpdfimagefileelse\@@DriverImageFile
+ {\ifvoid\foundexternalfigure
+ \donetrue
+ \else\ifx\PDFfigurereference\empty
+ \donetrue
+ \else
+ % hm, is this still needed
+ \doifinstringelse\filesuffix{\c!png,\c!jpg}\donetrue\donefalse
+ \fi\fi}
+ {\donefalse}%
+ \ifdone
+ \the\everyPDFximage
+ \checkpdfimageattributes
+ \checkpdfimagecolorspecs
+ \checkpdfimagepagenumber
+ \global\setbox\foundexternalfigure\hbox
+ {\ifx\pdfimagepagenumber\empty\@EA\pdfimmediateximage\else\@EA\pdfximage\fi
+ \pdfimageattributes
+ \pdfimagecolorspecs
+ \pdfimagepagenumber
+ \@@DriverImageBox
+ {\@@DriverImageFile}%
+ \xdef\PDFimagereference{\the\pdflastximage}%
+ \xdef\nofinsertpages{\the\pdflastximagepages}%
+ \pdfrefximage\pdflastximage}%
+ \xdef\analyzedfigurewidth {\the\wd\foundexternalfigure}%
+ \xdef\analyzedfigureheight{\the\ht\foundexternalfigure}%
+ \global\let\PDFfigurereference\empty
+ \global\let\PDFimageattributes\empty
+ \else
+ \global\let\analyzedfigurewidth \!!zeropoint
+ \global\let\analyzedfigureheight\!!zeropoint
+ \fi}
+
+\else
+
+ \def\dogetTPDfiguresize
+ {\doifvalidpdfimagefileelse\@@DriverImageFile
+ {\global\setbox\foundexternalfigure\vbox{\pdfimage{\@@DriverImageFile}}%
+ \xdef\analyzedfigurewidth {\the\wd\foundexternalfigure}%
+ \xdef\analyzedfigureheight{\the\ht\foundexternalfigure}}
+ {\global\let\analyzedfigurewidth \!!zeropoint
+ \global\let\analyzedfigureheight\!!zeropoint}}
+
+\fi
+
+\definefilechecker{tpd}{pdf}{\dogetTPDfiguresize}
+\definefilechecker{tpd}{png}{\dogetTPDfiguresize}
+\definefilechecker{tpd}{jpg}{\dogetTPDfiguresize}
+\definefilechecker{tpd}{jb2}{\dogetTPDfiguresize}
+
+\definespecial\dogetfiguresize
+ {\dofilechecker{tpd}{\truegraphictype\@@DriverImageType}}
+
+%D \macros
+%D {doregisterfigure}
+%D
+%D Here is the fuzzy, very special dependant figure
+%D registration special. We need to refer to the innermost
+%D object (ximage).
+
+\ifnum\pdftexversion>13
+
+ \definespecial\doregisterfigure#1#2%
+ {\doifundefined{IM::#1::#2}
+ {\setxvalue{IM::#1::#2}{\the\pdflastximage}}%
+ \xdef\PDFfigurereference{\getvalue{IM::#1::#2}}}
+
+\fi
+
+%D \macros
+%D {doovalbox}
+%D
+%D Drawing frames with round corners is inherited from the
+%D main module.
+
+\definespecial\doovalbox {\doPDFovalbox}
+
+%D \macros
+%D {dostartgraymode,dostopgraymode,
+%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode,
+%D dostopcolormode,
+%D dostartrotation,dostoprotation,
+%D dostartscaling,dostopscaling,
+%D dostartmirroring,dostopmirroring,
+%D dostartnegative,dostopnegative,
+%D dostartoverprint,dostopoverprint}
+%D
+%D These are implemented in the main \PDF\ module.
+
+\definespecial\dostartgraymode {\doPDFstartgraymode}
+\definespecial\dostopgraymode {\doPDFstopgraymode}
+\definespecial\dostartrgbcolormode {\doPDFstartrgbcolormode}
+\definespecial\dostartcmykcolormode{\doPDFstartcmykcolormode}
+\definespecial\dostartgraycolormode{\doPDFstartgraycolormode}
+\definespecial\dostartspotcolormode{\doPDFstartspotcolormode}
+\definespecial\dostopcolormode {\doPDFstopcolormode}
+\definespecial\dostartrotation {\doPDFstartrotation}
+\definespecial\dostoprotation {\doPDFstoprotation}
+\definespecial\dostartscaling {\doPDFstartscaling}
+\definespecial\dostopscaling {\doPDFstopscaling}
+\definespecial\dostartmirroring {\doPDFstartmirroring}
+\definespecial\dostopmirroring {\doPDFstopmirroring}
+\definespecial\dostartnegative {\doPDFstartnegative}
+\definespecial\dostopnegative {\doPDFstopnegative}
+\definespecial\dostartoverprint {\doPDFstartoverprint}
+\definespecial\dostopoverprint {\doPDFstopoverprint}
+
+\definespecial\doregistercmykspotcolor{\doPDFregistercmykspotcolor}
+\definespecial\doregisterrgbspotcolor {\doPDFregisterrgbspotcolor}
+\definespecial\doregistergrayspotcolor{\doPDFregistergrayspotcolor}
+
+\definespecial\doregistercmykindexcolor{\doPDFregistercmykindexcolor}
+\definespecial\doregisterrgbindexcolor {\doPDFregisterrgbindexcolor}
+\definespecial\doregistergrayindexcolor{\doPDFregistergrayindexcolor}
+
+\definespecial\doregisterfigurecolor{\doPDFregisterfigurecolor}
+
+\definespecial\dostartnonecolormode{\doPDFstartnonecolormode}
+\definespecial\doregisternonecolor {\doPDFregisternonecolor}
+
+\def\doPDFregisterspotcolorname#1#2% no need for escape in luatex
+ {\bgroup
+ \let\ascii\empty
+ \def\docommand##1%
+ {\edef\ascii{\ascii
+ \ifx\nexthandledtoken\space
+ \letterhash20%
+ \else\ifx\nexthandledtoken\blankspace
+ \letterhash20%
+ \else
+ ##1%
+ \fi\fi}}%
+ \expanded{\handletokens#2}\with\docommand
+ \letgvalue{@@pdf@@scn@@#1}\ascii
+ \egroup}
+
+\def\doPDFregistersomespotcolor#1#2#3#4#5#6#7% name fractions names p's space domain function
+ {\bgroup
+ \let\spotpops\empty
+ \ifcase#2\or
+ %def\PDFspotcolornames{/Separation /#1}%
+ \edef\PDFspotcolornames{/Separation /\executeifdefined{@@pdf@@scn@@#1}{#1}}%
+ \def\PDFspotcolordomain{0.0 1.0}%
+ \else
+ \dorecurse{#2}{\edef\spotpops{\spotpops pop }}%
+ \let\PDFspotcolornames \empty
+ \let\PDFspotcolordomain\empty
+ \def\dospotcolorcommand##1%
+ {\edef\PDFspotcolornames {\PDFspotcolornames/\executeifdefined{@@pdf@@scn@@##1}{##1}\space}%
+ \edef\PDFspotcolordomain{\PDFspotcolordomain 0.0 1.0\space}}%
+ \processcommacommand[#3]\dospotcolorcommand
+ \edef\PDFspotcolornames{/DeviceN [\PDFspotcolornames]}%
+ \fi
+ \immediate \pdfobj stream attr
+ {/FunctionType 4 /Domain [\PDFspotcolordomain] /Range [#6]}{{\spotpops#7}}%
+ \immediate \pdfobj
+ {[\PDFspotcolornames\space /Device#5 \PDFobjref\pdflastobj]}%
+ \dosetobjectreference{PDFCS}{#1}{\the\pdflastobj}%
+ \appendtoPDFdocumentcolorspaces{/#1 \PDFobjref\pdflastobj}%
+ \egroup}
+
+%D New and very experimental.
+
+% \def\doPDFregistersomeindexcolor#1#2#3#4#5#6#7% name fractions names p's space domain function
+% {\bgroup
+% \let\spotpops\empty
+% \dorecurse{#2}{\edef\spotpops{\spotpops exch pop\space}}%
+% \let\PDFspotcolornames \empty
+% \let\PDFspotcolordomain\empty
+% \def\docommand##1%
+% {\edef\PDFspotcolornames{\PDFspotcolornames/\executeifdefined{@@pdf@@scn@@##1}{##1}\space}%
+% \edef\PDFspotcolordomain{\PDFspotcolordomain 0.0 1.0\space}}%
+% \processcommacommand[#3,None]\docommand
+% \let\PDFcolorindexvector\empty
+% \def\docommand##1%
+% {\scratchdimen##1\points
+% \scratchdimen\recurselevel\scratchdimen
+% \scratchcounter\scratchdimen
+% \divide\scratchcounter \maxcard
+% \edef\PDFcolorindexvector{\PDFcolorindexvector\uchexnumbers\scratchcounter}}%
+% \dostepwiserecurse\zerocount{255}\plusone
+% {\rawprocesscommacommand[#4,1]\docommand
+% \xdef\PDFcolorindexvector{\PDFcolorindexvector\space}}%
+% \immediate \pdfobj stream attr
+% {/FunctionType 4 /Domain [\PDFspotcolordomain] /Range [#6]}{{\spotpops#7}}%
+% \immediate \pdfobj
+% {[/Indexed
+% [/DeviceN [\PDFspotcolornames] /Device#5 \PDFobjref\pdflastobj] %
+% 255 <\PDFcolorindexvector>]}%
+% \dosetobjectreference{PDFIX}{#1}{\the\pdflastobj}%
+% \appendtoPDFdocumentcolorspaces{/#1_INDEXED \PDFobjref\pdflastobj}%
+% \egroup}
+
+% we reverse the index; an alternative is to negate the graphic itself (\start/stop negative)
+
+\def\doPDFregistersomeindexcolor#1#2#3#4#5#6#7% name fractions names p's space domain function
+ {\bgroup
+ \let\spotpops\empty
+ \dorecurse{#2}{\edef\spotpops{\spotpops exch pop\space}}%
+ \let\PDFspotcolornames \empty
+ \let\PDFspotcolordomain\empty
+ \def\docommand##1%
+ {%\edef\PDFspotcolornames {\PDFspotcolornames/##1\space}%
+ \edef\PDFspotcolornames{\PDFspotcolornames/\executeifdefined{@@pdf@@scn@@##1}{##1}\space}%
+ \edef\PDFspotcolordomain{\PDFspotcolordomain 0.0 1.0\space}}%
+ \processcommacommand[#3,None]\docommand
+ \let\PDFcolorindexvector\empty
+ \def\docommand##1%
+ {\scratchdimen##1\points
+ \scratchdimen\recurselevel\scratchdimen
+ \scratchcounter\scratchdimen
+ \divide\scratchcounter \maxcard
+ \edef\PDFcolorindexvector{\PDFcolorindexvector\uchexnumbers\scratchcounter}}%
+ %\dostepwiserecurse\zerocount{255}\plusone
+ \dostepwiserecurse{255}\zerocount\minusone % we need to negate
+ {\rawprocesscommacommand[#4,1]\docommand
+ \xdef\PDFcolorindexvector{\PDFcolorindexvector\space}}%
+ \immediate \pdfobj stream attr
+ {/FunctionType 4 /Domain [\PDFspotcolordomain] /Range [#6]}{{\spotpops#7}}%
+ \immediate \pdfobj
+ {[/Indexed
+ [/DeviceN [\PDFspotcolornames] /Device#5 \the\pdflastobj\space0 R] %
+ 255 <\PDFcolorindexvector>]}%
+ \dosetobjectreference{PDFIX}{#1}{\the\pdflastobj}%
+ \appendtoPDFdocumentcolorspaces{/#1_INDEXED \the\pdflastobj\space0 R}%
+ \egroup}
+
+%D \macros
+%D {dostarttransparency,dostoptransparency}
+%D
+%D For transparency, we need to implement a couple of
+%D auxiliary macros. If needed, we will generalize them later.
+
+\definespecial\dostarttransparency{\doPDFstarttransparency}
+\definespecial\dostoptransparency {\doPDFstoptransparency}
+
+\PDFtransparencysupportedtrue
+
+\def\@@PDT{@PDT@}
+
+\ifx\PDFcurrenttransparency\undefined
+ \newcount\PDFcurrenttransparency \PDFcurrenttransparency=0 % -1
+\fi
+
+\def\assignPDFtransparency#1#2%
+ {\edef\PDFtransparencyidentifier{/Tr#1}%
+ \edef\PDFtransparencyreference{\PDFobjref{#2}}}
+
+\def\presetPDFtransparency#1#2%
+ {\initializePDFtransparency
+ \executeifdefined{\@@PDT#1:#2}{\dopresetPDFtransparency{#1}{#2}}}
+
+\def\dopresetPDFtransparency#1#2%
+ {\global\advance\PDFcurrenttransparency \plusone
+ \immediate\pdfobj{\PDFtransparancydictionary{#1}{#2}{}}%
+ \edef\PDFtransparencyidentifier{/Tr\the\PDFcurrenttransparency}%
+ \edef\PDFtransparencyreference {\PDFobjref\pdflastobj}%
+ \setxvalue{\@@PDT#1:#2}%
+ {\noexpand\assignPDFtransparency{\the\PDFcurrenttransparency}{\the\pdflastobj}}%
+ \appendtoPDFdocumentextgstates
+ {\PDFtransparencyidentifier\space
+ \PDFtransparencyreference\space}}
+
+\def\initializePDFtransparency
+ {\immediate\pdfobj{\PDFtransparancydictionary{1}{1}{/AIS false}}%
+ \xdef\PDFtransparencyresetidentifier{/Tr0}%
+ \xdef\PDFtransparencyresetreference{\PDFobjref\pdflastobj}%
+ \setxvalue{\@@PDT0:0}%
+ {\noexpand\assignPDFtransparency{0}{\the\pdflastobj}}%
+ \appendtoPDFdocumentextgstates
+ {\PDFtransparencyresetidentifier\space
+ \PDFtransparencyresetreference\space}%
+ \global\let\initializePDFtransparency\relax}
+
+%D \macros
+%D {dostartclipping,dostopclipping}
+%D
+%D Clipping in \PDFTEX\ is rather trivial. We can even hook
+%D in \METAPOST\ without problems.
+
+\definespecial\dostartclipping#1#2#3%
+ {\PointsToBigPoints{#2}\width
+ \PointsToBigPoints{#3}\height
+ \grabMPclippath{#1}{1}\width\height
+ {0 0 m \width\space 0 l \width \height l 0 \height l}%
+ \pdfliteral % PDFcode ?
+ {q 0 w \MPclippath\space W n}}
+
+\definespecial\dostopclipping
+ {\pdfliteral{Q n}} % PDFcode
+
+%D \macros
+%D {dosetupinteraction}
+%D
+%D Nothing special is needed to enable \PDF\ commands and
+%D interaction. We stick with a message.
+
+\definespecial\dosetupinteraction
+ {\showmessage\m!interactions{21}{pdftex}}
+
+%D \macros
+%D {doresetgotowhereever,
+%D dostartthisisrealpage,dostartthisislocation,
+%D dostartgotorealpage,dostartgotolocation,dostartgotoJS}
+%D
+%D The interactions macros are the core of this module. We
+%D support both page destinations and named ones. We don't
+%D need the \type{\stop}||alternatives. We also don't need
+%D to set the special that sets the real page number.
+
+\definespecial\doresetgotowhereever {\doPDFresetgotowhereever}
+\definespecial\dostartthisislocation{\doPDFstartthisislocation}
+
+%D When going to a location, we obey the time and space saving
+%D boolean \type{\ifusepagedestination}. Named destinations are
+%D stripped and made robust. This all happens in the macros
+%D called for.
+
+\definespecial\dostartgotolocation{\doPDFstartgotolocation}
+\definespecial\dostartgotorealpage{\doPDFstartgotorealpage}
+\definespecial\dostartgotoJS {\doPDFstartgotoJS}
+
+\let\PDFpagexyzspec\empty % pdftex does not accept spec
+
+%D \macros
+%D {doflushJSpreamble}
+%D
+%D It does not make sense to duplicate common \JAVASCRIPT\
+%D functions, and therefore they can be predefined and must be
+%D output separately. Currently this special is not shared
+%D with the \ACROBAT\ one, simply because \DISTILLER\ does not
+%D yet support something \type{\pdfnames}.
+
+% \oneJSpreamblefalse % buggy in acrobat
+
+\definespecial\doflushJSpreamble#1%
+ {\bgroup
+ \let\compositeJScode\empty
+ \def\docommand##1%
+ {\edef\sanitizedJScode{\getJSpreamble{##1}}%
+ \@EA\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode
+ \immediate\pdfobj {<< /S /JavaScript /JS (\sanitizedJScode) >>}%
+ \edef\compositeJScode
+ {\compositeJScode\space (##1) \PDFobjref\pdflastobj}}%
+ \processcommalist[#1]\docommand
+ \immediate\pdfobj{<< /Names [ \compositeJScode ] >>}%
+ \pdfnames{/JavaScript \PDFobjref\pdflastobj}%
+ \egroup}
+
+%D \macros
+%D {dostarthide,dostophide}
+%D
+%D Hiding parts of the document for printing is not yet
+%D supported by \PDF\ and therefore \PDFTEX.
+
+\definespecial\dostarthide{}
+\definespecial\dostophide {}
+
+%D \macros
+%D {dosetupscreen}
+%D
+%D Setting of the screen boundingbox involves some
+%D calculations. Here we also take care of (non) full screen
+%D startup. The dimensions are rounded. Because \PDFTEX\ and
+%D \ACROBAT\ handle setting the page dimensions in a
+%D different way, we do not share this special.
+
+\definespecial\dosetupscreen {\doPDFsetupscreen \pdfpageheight}
+
+\definespecial\dosetupartbox {\doPDFsetupartbox \pdfpageheight}
+\definespecial\dosetupcropbox {\doPDFsetupcropbox \pdfpageheight}
+\definespecial\dosetupbleedbox{\doPDFsetupbleedbox\pdfpageheight}
+\definespecial\dosetuptrimbox {\doPDFsetuptrimbox \pdfpageheight}
+
+%D \macros
+%D {dostartexecutecommand}
+%D
+%D \PDF\ viewers enable us to navigate using menus and shortcut
+%D keys. These navigational tools can also be accessed by using
+%D annotations. The next special takes care of inserting them.
+
+\definespecial\dostartexecutecommand{\doPDFstartexecutecommand}
+
+%D \macros
+%D {dosetupidentity}
+%D
+%D Documents can be tagged with an application accessible title
+%D and subtitle, the authorname, a date, the creator, keywords
+%D etc. For the moment \PDFTEX\ only supports the first three
+%D of these.
+
+\definespecial\dosetupidentity{\doPDFsetupidentity}
+
+%D \macros
+%D {dostartrunprogam}
+%D
+%D We can run a program form within a document, although this
+%D feature is rather weak, due to path problems and buggy
+%D argument passing.
+
+\definespecial\dostartrunprogram{\doPDFstartrunprogram}
+
+%D \macros
+%D {dostartgotoprofile, dostopgotoprofile,
+%D dobeginofprofile, doendofprofile}
+%D
+%D \CONTEXT\ user profiles and version control fall back on
+%D \PDF\ article threads. Unfortunately one cannot influence
+%D the view yet in an (for me) acceptable way.
+
+\definespecial\dostartgotoprofile{\doPDFstartgotoprofile}
+
+%D Some day, I'll reimplement threading in a useful way.
+%D Currently the viewers handle threads rather diffuse.
+
+\ifnum\pdftexversion>13
+
+\definespecial\dobeginofprofile#1#2#3#4%
+ {\setPDFdestination{#1}%
+ \doifsomething\PDFdestination
+ {\pdfthread
+ width #2 height #3
+ attr {/Title (\PDFdestination)} % can be omitted
+ name {\PDFdestination}}}
+
+\definespecial\doendofprofile%
+ {}
+
+\fi
+
+%D \macros
+%D {doinsertbookmark}
+%D
+%D In \PDF\ bookmarks are the building blocks of a viewer
+%D provided sort of table of contents. \TEX\ has to provide
+%D the entry as well as the number of child entries. Strings
+%D need to be sanatized as good as possible to suit the default
+%D encoding. In \CONTEXT\ users can overrule this string by
+%D supplying an alternative one. Look at the macro called for
+%D to see how funny these bookmarks are defined.
+
+\definespecial\doinsertbookmark{\doPDFinsertbookmark}
+
+%D \macros
+%D {dostartobject,dostopobject,doinsertobject}
+%D
+%D Due to \PDF's object oriented character, we can include and
+%D reuse objects. These can be compared with \TEX's boxes. The
+%D \TEX\ counterpart is defined in the module \type{spec-dvi}.
+%D We don't use the dimensions here.
+%D
+%D The next solution is not that beautiful. Because objects are
+%D containers for whatever kind of content, graphics can be
+%D part of this content, and a graphic object can be part of
+%D the more general type. In practice this means that an ximage
+%D would be embedded in an xform, which in itself is not that
+%D big a problem, apart from a few bytes overhead. However, for
+%D reasons unknown to me alternative images must be pure
+%D ximages |<|indeed, somehow one cannot use a vector graphic
+%D as alternative|>| that are not embedded into forms, so this
+%D is why the object handler treats them different. This
+%D implies knowledge of the calling routines, especially the
+%D \type{FIG} trigger, that signals that we just embedded an
+%D image. Alternatively I could have introduced a dual object
+%D system, but the overhead in duplicate specials is currently
+%D not what we want. I'd rather implement a more mature
+%D object support system from scratch.
+
+\let\currentPDFresources\empty
+\let\PDFimageattributes \empty
+\let\PDFfigurereference \empty
+\let\PDFimagereference \empty
+
+\ifnum\pdftexversion>13
+
+ \definespecial\dostartobject#1#2#3#4#5%
+ {\bgroup
+ \setbox\nextbox\vbox\bgroup
+ \def\dodostopobject
+ {\egroup
+ \ifx\PDFimagereference\empty
+ % We also flush page resources, since shared
+ % resources end up there; otherwise transparencies
+ % won't work in xforms; some day I will optimize
+ % this.
+ \the\everyPDFxform
+ \finalizeobjectbox\nextbox
+ \immediate\pdfxform
+ resources {\currentPDFresources\the\pdfpageresources}%
+ \nextbox
+ \global\let\currentPDFresources\empty
+ \dosetobjectreference{#1}{#2}{\the\pdflastxform}%
+ \else
+ \dosetobjectreference{#1}{#2}{-\PDFimagereference}%
+ \global\let\PDFimagereference\empty
+ \fi}}
+
+ \definespecial\dostopobject
+ {\dodostopobject
+ \egroup}
+
+ \definespecial\doresetobjects
+ {\global\let\PDFimagereference\empty}
+
+ \definespecial\doinsertobject#1#2%
+ {\bgroup
+ \doifobjectreferencefoundelse{#1}{#2}
+ {\dogetobjectreference{#1}{#2}\PDFobjectreference
+ \ifnum\PDFobjectreference<0
+ \@EA\@EA\@EA\pdfrefximage\@EA\gobbleoneargument\PDFobjectreference
+ \else
+ \pdfrefxform\PDFobjectreference
+ \fi}%
+ {}%
+ \egroup}
+
+\else
+
+ \definespecial\dostartobject#1#2#3#4#5%
+ {\bgroup
+ \setbox\nextbox\vbox\bgroup
+ \def\dodostopobject
+ {\egroup
+ \the\everyPDFxform
+ \pdfform\nextbox
+ \dosetobjectreference{#1}{#2}{\the\pdflastform}}}
+
+ \definespecial\dostopobject
+ {\dodostopobject
+ \egroup}
+
+ \definespecial\doinsertobject#1#2%
+ {\bgroup
+ \dogetobjectreference{#1}{#2}\PDFobjectreference
+ \pdfrefform\PDFobjectreference
+ \egroup}
+
+\fi
+
+\appendtoksonce
+ \collectPDFresources
+ \global\let\currentPDFresources\collectedPDFresources
+\to \everyPDFxform
+
+%D \macros
+%D {dosetpagetransition}
+%D
+%D Page transitions only make sence in presentations. They are
+%D passed as raw \PDF\ code to the page object. Take a look
+%D at the implementation to get an impression of the rubish
+%D passed on.
+
+\definespecial\dosetpagetransition{\doPDFsetpagetransition}
+
+%D The expansion is needed because else the \type{\pdfpageattr}
+%D token list flushes an unexpanded \type{\csname}. The
+%D \type{\global} is needed because the assignment can take
+%D place deeply buried (for instance in the \type{\shipout}
+%D box.
+
+%D \macros
+%D {doinsertcomment, doflushcomments}
+%D
+%D Text annotation, or comments, are provided too:
+
+\definespecial\doinsertcomment{\doPDFinsertcomment}
+\definespecial\doflushcomments{\doPDFflushcomments}
+
+%D \macros
+%D {dopresetlinefield,dopresettextfield,
+%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield,
+%D dopresetpushfield,dopresetcheckfield,
+%D dopresetradiofield,dopresetradiorecord}
+%D
+%D \PDF\ offers extensive field support. The next bunch of
+%D definitions map the specials.
+
+\definespecial\dopresetlinefield {\doFDFpresetlinefield}
+\definespecial\dopresettextfield {\doFDFpresettextfield}
+\definespecial\dopresetchoicefield{\doFDFpresetchoicefield}
+\definespecial\dopresetpopupfield {\doFDFpresetpopupfield}
+\definespecial\dopresetcombofield {\doFDFpresetcombofield}
+\definespecial\dopresetpushfield {\doFDFpresetpushfield}
+\definespecial\dopresetcheckfield {\doFDFpresetcheckfield}
+\definespecial\dopresetradiofield {\doFDFpresetradiofield}
+\definespecial\dopresetradiorecord{\doFDFpresetradiorecord}
+
+%D \macros
+%D {dodefinefieldset,dogetfieldset,doiffieldset}
+%D
+%D Field sets, needed for reset and submit handling, are
+%D taken care of by:
+
+\definespecial\dodefinefieldset{\doFDFdefinefieldset}
+\definespecial\dogetfieldset {\doFDFgetfieldset}
+\definespecial\doiffieldset {\doFDFiffieldset}
+
+%D \macros
+%D {doregistercalculationset}
+%D
+%D The calculation order is defined using:
+
+\definespecial\doregistercalculationset{\doFDFregistercalculationset}
+
+%D \macros
+%D {doPDFdestination}
+%D
+%D Finally we implement some low level macros to deal with
+%D flushing \PDF\ code. First we handle the named destinations.
+
+\def\doPDFdestination#1%
+ {\pdfdest name {#1}\PDFpageviewkey}
+
+%D \macros
+%D {doPDFaction,doPDFannotation,ifsharePDFactions}
+%D
+%D Next we handle annotations. All link annotations are
+%D implemented using the action dictionary. This enables us to
+%D use multiple actions. The second macro is for instance
+%D used for movie inclusion.
+
+\newif\ifsharePDFactions \sharePDFactionstrue
+
+% hm, due to some stupid optimization this feature has been
+% disabled for some time, watch out \lastPDFaction is to be
+% persistent
+
+\ifnum\pdftexversion>13
+
+ \def\doPDFaction#1#2#3%
+ {\xdef\lastPDFcontent{#3}%
+ \ifcollectreferenceactions
+ \global\let\lastPDFaction\lastPDFcontent
+ \else
+ \ifsharePDFactions
+ \ifcase\similarreference\relax
+ \xdef\lastPDFaction{<<\lastPDFcontent>>}%
+ \or
+ \immediate\pdfobj{<<\lastPDFcontent>>}%
+ \xdef\lastPDFaction{\PDFobjref\pdflastobj}%
+ \else
+ % leave \lastPDFaction untouched
+ \fi
+ \else
+ \xdef\lastPDFaction{<<\lastPDFcontent>>}%
+ \fi
+ \pdfannot
+ width #1 height #2 depth \zeropoint
+ {/Subtype /Link
+ /Border [0 0 0]
+ \ifhighlighthyperlinks \else /H /N \fi
+ /A \lastPDFaction}%
+ \fi}
+
+\else
+
+ \def\doPDFaction#1#2#3%
+ {\ifcollectreferenceactions
+ \xdef\lastPDFaction{#3}%
+ \else
+ \ifsharePDFactions
+ \ifcase\similarreference\relax
+ \xdef\lastPDFaction{<<#3>>}%
+ \or
+ \immediate\pdfobj{<<#3>>}%
+ \xdef\lastPDFaction{\PDFobjref\pdflastobj}%
+ \else
+ % leave \lastPDFaction untouched
+ \fi
+ \else
+ \xdef\lastPDFaction{<<#3>>}%
+ \fi
+ \pdfannotlink % could be \pdfannot if not the - problem was there
+ width #1 height #2 depth \zeropoint
+ user {/Subtype /Link
+ /Border [0 0 0]
+ \ifhighlighthyperlinks \else /H /N \fi
+ /A \lastPDFaction}%
+ \pdfendlink
+ \fi}
+
+\fi
+
+% pdftex and viewers give problems with this one (printing forms)
+%
+%\def\doPDFannotation#1#2#3%
+% {\pdfannot width #1sp height -#2sp depth \zeropoint{#3}}
+%
+% This is corrected in version 14. When this version is wide
+% spread, this will be cleaned up.
+
+\ifnum\pdftexversion>13
+
+ \def\doPDFannotation#1#2#3%
+ {\pdfannot width #1 height #2 depth \zeropoint{#3}}
+
+\else
+
+ \def\doPDFannotation#1#2#3%
+ {\hbox{\raise#2\hbox{\pdfannot width #1 height #2 depth \zeropoint{#3}}}}
+
+\fi
+
+%D \macros
+%D {doPDFannotationobject,doPDFactionobject}
+%D
+%D For field support we need annotation objects. Although in
+%D many cases we can do without indirect references (and use
+%D the last annotation object number directly), we take the
+%D save route.
+
+\def\doPDFannotationobject#1#2#3#4#5%
+ {\doPDFannotation{#3}{#4}{#5}%
+ \dosetobjectreference{#1}{#2}{\the\pdflastannot}}
+
+\def\doPDFactionobject#1#2#3#4#5%
+ {\doPDFaction{#3}{#4}{#5}%
+ \dosetobjectreference{#1}{#2}{\the\pdflastannot}}
+
+%D \macros
+%D {doPDFaddtocatalog,doPDFaddtoinfo,
+%D doPDFpageattribute,doPDFpagesattribute}
+%D
+%D Next some simple ones. Watch the global directive and the
+%D expansion in the page attribute macro.
+
+\def\doPDFaddtocatalog
+ {\pdfcatalog}
+
+\def\doPDFaddtoinfo
+ {\pdfinfo}
+
+\def\doPDFpageattribute#1%
+ {\expanded{\global\pdfpageattr{#1\the\pdfpageattr}}}
+
+\def\doPDFpageresource#1%
+ {\expanded{\global\pdfpageresources{#1\the\pdfpageresources}}}
+
+\def\doPDFpagesattribute#1%
+ {\expanded{\global\pdfpagesattr{#1\the\pdfpagesattr}}}
+
+\def\doPDFresetpageattributes
+ {\global\pdfpageattr\emptytoks}
+
+\def\doPDFresetpageresources
+ {\global\pdfpageresources\emptytoks}
+
+%D \macros
+%D {doPDFbookmark}
+%D
+%D Well, isn't the next one ugly? Thanks to the \PDF\
+%D standard.
+
+\def\doPDFbookmark#1#2#3#4#5%
+ {\doPDFgetpagereference{#4}\PDFobjectreference
+ \pdfoutline
+ user {<</S /GoTo /D [\PDFobjectreference\space\PDFpageviewwrd]>>}%
+ \ifcase#2 \else count \ifcase#5-\fi#2 \fi
+ {\ifPDFunicode<#3>\else#3\fi}}
+
+%D \macros
+%D {doPDFdictionaryobject,doPDFarrayobject}
+%D
+%D Where \PDFTEX\ has only one object primitive, optionally a
+%D stream one, \ACROBAT\ has several operators.
+
+\def\doPDFdictionaryobject#1#2#3%
+ {\flushatshipout
+ {\immediate\pdfobj{<< #3 >>}%
+ \dosetobjectreference{#1}{#2}{\the\pdflastobj}}}
+
+\def\doPDFarrayobject#1#2#3%
+ {\flushatshipout
+ {\immediate\pdfobj{[ #3 ]}%
+ \dosetobjectreference{#1}{#2}{\the\pdflastobj}}}
+
+% tricky .. too many xforms now
+%
+% \def\doreservePDFobject#1#2%
+% {\pdfobj reserveobjnum{}%
+% \driverreferenced\dosetobjectreference{#1}{#2}{\the\pdflastobj}}
+%
+% \def\doPDFreserveddictionaryobject#1#2#3%
+% {\doPDFgetobjectnumber{#1}{#2}\PDFobjectnumber
+% \immediate\pdfobj useobjnum \PDFobjectnumber {<< #3 >>}}
+%
+% \def\doPDFreservedarrayobject#1#2#3%
+% {\doPDFgetobjectnumber{#1}{#2}\PDFobjectnumber
+% \immediate\pdfobj useobjnum \PDFobjectnumber {[ #3 ]}}
+
+% \doreservePDFobject{FDF}{docuextgstates}
+% \doreservePDFobject{FDF}{colorspaces}
+% \doreservePDFobject{FDF}{docushades}
+
+%D \macros
+%D {defaultobjectreference,doPDFgetobjectreference}
+%D
+%D Because in \PDFTEX\ we have to construct the object
+%D references \type{N 0 R}, we can default to the non existing
+%D zero object number.
+
+\def\defaultobjectreference#1#2%
+ {0}
+
+\def\doPDFgetobjectreference#1#2#3%
+ {\dogetobjectreference{#1}{#2}#3%
+ \edef#3{\ifx#3\empty null\else\PDFobjref{#3}\fi}}
+
+\def\doPDFgetobjectnumber#1#2#3%
+ {\dogetobjectreference{#1}{#2}#3%
+ \edef#3{\ifx#3\empty 0\else#3\fi}}
+
+% \def\doPDFgetobjectpage #1#2#3{..}
+% \def\doPDFgetobjectpagereference#1#2#3{..}
+
+\ifx\pdfpageref\undefined
+
+ \def\doPDFgetpagereference % number macro
+ {\installprogram{texutil --filter \jobname}%
+ \gdef\doPDFgetpagereference##1{\doPDFgetobjectreference{PDFP}{\number##1}}% {##2}
+ \doPDFgetpagereference}
+
+\else
+
+ \def\doPDFgetpagereference#1#2% number macro
+ {\edef#2{\ifnum#1>\zerocount\PDFobjref{\pdfpageref#1}\else null\fi}}
+
+\fi
+
+%D \macros
+%D {initializePDFnegative,initializePDFoverprint}
+%D
+%D Here follow some rather obscure macros. They will only
+%D come into action when one wants negated output.
+
+%D Todo: move code to fdf module
+
+\def\initializePDFnegative
+ {\immediate\pdfobj stream attr {/FunctionType 4 /Range [0 1] /Domain [0 1]} {{1 exch sub}}%
+ \immediate\pdfobj{<</Type /ExtGState /TR \PDFobjref\pdflastobj>>}%
+ \appendtoPDFdocumentextgstates{/GSnegative \PDFobjref\pdflastobj}%
+ \immediate\pdfobj{<</Type /ExtGState /TR /Identity>>}%
+ \appendtoPDFdocumentextgstates{/GSpositive \PDFobjref\pdflastobj}%
+ \global\let\initializePDFnegative\relax}
+
+\def\initializePDFoverprint
+ {\immediate\pdfobj{<</Type /ExtGState /OP false /OPM 0>>}% /op defaults to /OP
+ \appendtoPDFdocumentextgstates{/GSknockout \PDFobjref\pdflastobj}%
+ \immediate\pdfobj{<</Type /ExtGState /OP true /OPM 1>>}% /op defaults to /OP
+ \edef\PDFobjectreferenceB{\the\pdflastobj}%
+ \appendtoPDFdocumentextgstates{/GSoverprint \PDFobjref\pdflastobj}%
+ \global\let\initializePDFoverprint\relax}
+
+%D File embedding. Storing the stream identifier is needed
+%D to get access to the number. When typeset, the user can
+%D feed this number to \type {pdftosrc} and filter the
+%D file from the \PDF\ file.
+
+\let\PDFlaststreamobject \s!unknown
+%def\PDFlaststreamreference{0 0 R}
+
+\def\doPDFfilestreamobject#1#2#3#4%
+ {\immediate\pdfobj stream file{#4}%
+ \edef\PDFlaststreamobject{\the\pdflastobj}%
+ \dosetobjectreference{PDFFS}{#2}{\PDFlaststreamobject}%
+ \doPDFdictionaryobject{#1}{#2}{/Type /Filespec /F (#3) /EF <</F \PDFobjref\PDFlaststreamobject>>}}
+
+\def\doPDFgetfilestreamreference#1#2%
+ {\doPDFgetobjectreference{PDFFS}{#1}#2}
+
+\def\doPDFfilestreamidentifier#1%
+ {\doifsomething{#1}
+ {\doPDFgetfilestreamreference{#1}\PDFobjectreference
+ \@EA\beforesplitstring\PDFobjectreference\at{ }\to\PDFlaststreamobject
+ \PDFlaststreamobject}}
+
+% %D We can set \METAPOST\ prologues to~1:
+
+\def\MPprologues{1}
+
+%D Experimental:
+
+\definespecial\dostartfonteffect{\doPDFstartfonteffect}
+\definespecial\dostopfonteffect {\doPDFstopfonteffect}
+
+%D Some MP stuff:
+
+\let\handleMPfshow\dohandleMPfshow % default anyway
+
+\ifnum\pdftexversion<14
+
+ \def\setMPPDFobject#1#2% resources boxnumber
+ {\def\getMPPDFobject{\box#2}}
+
+\else
+
+ \def\setMPPDFobject#1#2% resources boxnumber
+ {\the\everyPDFxform
+ \finalizeobjectbox{#2}%
+ \immediate\pdfxform resources{#1}#2%
+ \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}}
+
+\fi
+
+\let\getMPPDFobject\relax
+
+\definespecial\doinsertMPfile#1%
+ {\doiffileelse{./#1}{\includeMPasPDF{./#1}}{\message{[MP #1]}}}
+
+%D Now we can finish this module.
+
+\stopspecials
+
+\protect \endinput