%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. 

%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

%D We default to 300 dots per inch image resolution. 

\ifx\pdfimageresolution\undefined 
  \newcount\pdfimageresolution
\fi

\pdfimageresolution=300

% %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 \starttypen
%D \usespecials[tpd]
%D \stoptypen
%D
%D we get ourselves full \PDF\ output.

%D For some internal testing we need to know the output 
%D suffix. 

\def\jobsuffix{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. 

\appendtoks \pdfoutput=0 \to \everyresetspecials

\pdfoutput       =1 % we reset that one with \everyresetspecials
\pdfcompresslevel=9 % apart from debugging, no reason for value 0

%D Just in case we mimmick specials, we have to make sure no
%D default specials end up in the process.

\let\defaultspecial=\gobbleoneargument

\appendtoks \let\defaultspecial\normalspecial \to \everyresetspecials

\let\PDFcode\pdfliteral

%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   {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#1#2#3#4#5#6#7#8#9%
  {\bgroup
   \dodoinsertfile{tpd}{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}%
   \egroup}

%D The number of pages in (for instance an \PDF) insert 
%D file, can be asked for using: 

\definespecial\dogetnofinsertpages#1% global ! 
  {\global\let#1\PDFimagenofpages}

%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}#1#2#3#4#5#6#7#8#9%
  {\hbox
     {\convertMPcolors{#1}%
      \scratchdimen=#3pt \PointsToReal{.01\scratchdimen}\xscale
      \scratchdimen=#4pt \PointsToReal{.01\scratchdimen}\yscale
      \convertMPtoPDF{#1}\xscale\yscale}}

%D The old, \TEX\ base \PDF\ insertion macro:
%D 
%D \starttypen
%D \def\dotpdinsertpdf#1#2#3#4#5#6#7#8#9%
%D   {\beforesplitstring#1\at.\to\filename
%D    \scratchdimen=#3pt \PointsToReal{.01\scratchdimen}\xscale
%D    \scratchdimen=#4pt \PointsToReal{.01\scratchdimen}\yscale
%D    \convertPDFtoPDF{\filename.pdf}\xscale\yscale{#5sp}{#6sp}{#7sp}{#8sp}}
%D \stoptypen
%D 
%D superseded by the next macros. 

\definefileinsertion{tpd}{pdf}{\handlepdfimage}
\definefileinsertion{tpd}{png}{\handlepdfimage}
\definefileinsertion{tpd}{jpg}{\handlepdfimage}
%definefileinsertion{tpd}{tif}{\handlepdfimage} % unstable 

%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%
  {\doiffileelse{#1}
     {\edef\filesuffix{#1}%
      \doloop
        {\@EA\aftersplitstring\filesuffix\at.\to\temp
         \ifx\temp\empty
           \exitloop
         \else
           \let\filesuffix\temp
           % a temporary hack
           \doif{\filesuffix}{PDF}{\pdfimageresolution=72}%
           \doif{\filesuffix}{pdf}{\pdfimageresolution=72}%
           % because pdfTeX scales back 
         \fi}}
      {\let\filesuffix\s!unknown}%
   \doiffileinsertionsupportedelse{\filesuffix}}

\ifx\pdflastximagepages\undefined \chardef\pdflastximagepages=1 \fi

\ifnum\pdftexversion>13

\def\checkpdfimagepagenumber#1%
  {\let\pdfimagepagenumber\empty
   \getfromcommacommand[#1][1]%
   \doifnumberelse{\commalistelement}
     {\ifcase\commalistelement\else
        \edef\pdfimagepagenumber{page \commalistelement}%
        \message{(pdf image page \pdfimagepagenumber)}% 
      \fi}
     {}}

\def\handlepdfimage#1#2#3#4#5#6#7#8#9%
  {\bgroup
   \doifvalidpdfimagefileelse{#1}
     {\checkpdfimagepagenumber{#9}%
      \immediate\pdfximage
        \ifcase#7 \else \!!width  #7sp\fi
        \ifcase#8 \else \!!height #8sp\fi
        \pdfimagepagenumber
        {#1}%
      \xdef\PDFimagereference{\the\pdflastximage}%
      \xdef\PDFimagenofpages{\the\pdflastximagepages}%
      \pdfrefximage\pdflastximage}
     {\framed[\c!breedte=#7sp,\c!hoogte=#8sp]{#1}}%
   \egroup}

\else

\def\handlepdfimage#1#2#3#4#5#6#7#8#9%
  {\bgroup
   \doifvalidpdfimagefileelse{#1}
     {\pdfimage
        \ifcase#7 \else \!!width  #7sp\fi
        \ifcase#8 \else \!!height #8sp\fi
        {#1}}%
     {\framed[\c!breedte=#7sp,\c!hoogte=#8sp]{#1}}%
   \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}

%D \macros 
%D   {doinsertsoundtrack}
%D
%D We use numbers instead of labels to keep track of sounds. 

\definespecial\doinsertsoundtrack{\doPDFinsertsoundtrack}

%D \macros 
%D   {measureTPDfiguresizetrue}
%D
%D Because \PDFTEX\ measures the figure itself, we can use 
%D this feature to bypass the normal prescan. Watch the 
%D double check on the suffix. Else \PDFTEX\ would choke. 

\newif\ifmeasureTPDfiguresize \measureTPDfiguresizetrue 

%D For the moment we don't test for alternatives that
%D themselves have alternatives, especially cylcic
%D dependencies. 

\ifnum\pdftexversion>13

\def\checkpdfimageattributes%
  {\ifx\PDFfigurereference\empty
     \global\let\pdfimageattributes\empty
   \else
     \immediate\pdfobj%
       {[ << /Image \PDFfigurereference\space0 R
             /DefaultForPrinting true >> ]}%
     \xdef\pdfimageattributes%
       {attr {/Alternates \the\pdflastobj\space0 R}}%
   \fi}

\def\dogetTPDfiguresize#1#2#3#4#5#6#7%
  {\ifmeasureTPDfiguresize
     #4=\!!zeropoint
     #5=\!!zeropoint
     \doifvalidpdfimagefileelse{#2}
       {\ifvoid\foundexternalfigure
          \donetrue
        \else\ifx\PDFfigurereference\empty
          \donetrue
        \else
          \doifinstringelse{\filesuffix}{\c!png,\c!jpg}\donetrue\donefalse
        \fi\fi}
       {\donefalse}%
     \ifdone
       \checkpdfimagepagenumber{#3}%
       \checkpdfimageattributes
       \global\setbox\foundexternalfigure=\vbox
         {\immediate\pdfximage \pdfimageattributes \pdfimagepagenumber{#2}%
          \xdef\PDFimagereference{\the\pdflastximage}%
          \xdef\PDFimagenofpages{\the\pdflastximagepages}%
          \pdfrefximage\pdflastximage}%
       #6=\wd\foundexternalfigure
       #7=\ht\foundexternalfigure
       \global\let\PDFfigurereference\empty
       \global\let\PDFimageattributes\empty
     \else
       #6=\!!zeropoint
       #7=\!!zeropoint
     \fi
  \else
    #1{#2}{#3}{#4}{#5}{#6}{#7}% \normaldogetfiguresize...
  \fi}

\else

\def\dogetTPDfiguresize#1#2#3#4#5#6#7%
  {\ifmeasureTPDfiguresize
     #4=\!!zeropoint
     #5=\!!zeropoint
     \doifvalidpdfimagefileelse{#2}
       {\global\setbox\foundexternalfigure=\vbox{\pdfimage{#2}}%
        #6=\wd\foundexternalfigure
        #7=\ht\foundexternalfigure}
       {#6=\!!zeropoint
        #7=\!!zeropoint}%
  \else
    #1{#2}{#3}{#4}{#5}{#6}{#7}% \normaldogetfiguresize...
  \fi}

\fi

\let\normaldogetfiguresizepdf=\dogetfiguresizepdf
\let\normaldogetfiguresizepng=\dogetfiguresizepng
\let\normaldogetfiguresizetif=\dogetfiguresizetif
\let\normaldogetfiguresizejpg=\dogetfiguresizejpg

\def\dogetfiguresizepdf{\dogetTPDfiguresize\normaldogetfiguresizepdf}
\def\dogetfiguresizepng{\dogetTPDfiguresize\normaldogetfiguresizepng}
\def\dogetfiguresizetif{\dogetTPDfiguresize\normaldogetfiguresizetif}
\def\dogetfiguresizejpg{\dogetTPDfiguresize\normaldogetfiguresizejpg}

%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
%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\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}       

%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%
  {\ScaledPointsToBigPoints{#2}\width
   \ScaledPointsToBigPoints{#3}\height
   \grabMPclippath{#1}{1}{\width}{\height}
     {0 0 m \width\space 0 l \width \height l 0 \height l}% 
   \pdfliteral
     {q 0 w \MPclippath\space W n}}

\definespecial\dostopclipping%
  {\pdfliteral{Q}}

%D \macros
%D   {dosetupinteraction,
%D    dosetupopenaction,dosetupcloseaction}
%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}}

\definespecial\dosetupopenaction {\doPDFsetupopenaction}
\definespecial\dosetupcloseaction{\doPDFsetupcloseaction}

%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}

%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\docommando##1%
     {\edef\sanitizedJScode{\getJSpreamble{##1}}%
      \@EA\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode
      \immediate\pdfobj {<< /S /JavaScript /JS (\sanitizedJScode) >>}%
      \edef\compositeJScode%
        {\compositeJScode\space (##1) \the\pdflastobj\space 0 R}}%
   \processcommalist[#1]\docommando
   \immediate\pdfobj{<< /Names [ \compositeJScode ] >>}%
   \pdfnames{/JavaScript \the\pdflastobj\space 0 R}%
   \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}

%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#1#2#3#4#5%
  {\bgroup
   \enablePDFdocencoding
   \pdfinfo
     {%Producer (pdfTeX) % already there 
      /Title (#1)
      /Subject (#2)
      /Author (#3)
      /Creator (#4)}%
   \egroup}

%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 #2sp height #3sp 
        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
          \immediate\pdfxform resources {\currentPDFresources}\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\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
        \pdfform\nextbox
        \dosetobjectreference{#1}{#2}{\the\pdflastform}}}
 
  \definespecial\dostopobject%
    {\dodostopobject
     \egroup}

  \definespecial\doinsertobject#1#2% 
    {\bgroup
     \dogetobjectreference{#1}{#2}\PDFobjectreference
     \pdfrefform\PDFobjectreference
     \egroup}

\fi

%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}
%D
%D Text annotation, or comments, are provided too:

\definespecial\doinsertcomment{\doPDFinsertcomment}

%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   {dosetposition, dosetpositionwdh}
%D
%D Opposite to its \DVI\ counterpart, the \PDFTEX\ backend 
%D can provide positional information directly. Since 
%D \CONTEXT\ only uses relative positions, the origin is of 
%D less importance. 

\def\doTPDsetposition#1#2#3%
  {\bgroup
   \edef\doTPDsetposition%
     {\writeutilitycommand
        {#1 %
         {#2}%
         {\noexpand\realfolio}%
         {\noexpand\number\pdflastxpos}%
         {\noexpand\number\pdflastypos}%
         #3}}%
   \pdfsavepos
   \doTPDsetposition
   \egroup}

\definespecial\dosetposition#1%
  {\doTPDsetposition{\pxypos}{#1}{}}

\definespecial\dosetpositionwhd#1#2#3#4%
  {\doTPDsetposition{\pxywhdpos}{#1}{{#2}{#3}{#4}}}

%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 name #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

\ifnum\pdftexversion>13 

  \def\doPDFaction width #1 height #2 action #3%
    {\ifcase\similarreference\relax
       \xdef\lastPDFaction{<<#3>>}%
     \or
       \ifsharePDFactions
         \immediate\pdfobj{<<#3>>}%
         \xdef\lastPDFaction{\the\pdflastobj\space0 R}%
       \else
         \xdef\lastPDFaction{<<#3>>}%
       \fi
     \fi
     \ifcollectreferenceactions \else
       \pdfannot
         width #1sp height #2sp depth 0sp
           {/Subtype /Link 
            /Border [0 0 0] 
            \ifhighlighthyperlinks \else /H /N \fi
            /A \lastPDFaction}%
     \fi}

\else

  \def\doPDFaction width #1 height #2 action #3%
    {\ifcase\similarreference\relax
       \xdef\lastPDFaction{<<#3>>}%
     \or
       \ifsharePDFactions
         \immediate\pdfobj{<<#3>>}%
         \xdef\lastPDFaction{\the\pdflastobj\space0 R}%
       \else
         \xdef\lastPDFaction{<<#3>>}%
       \fi
     \fi
     \ifcollectreferenceactions \else
       \pdfannotlink % could be \pdfannot if not the - problem was there
         width #1sp height #2sp depth 0sp
         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 width #1 height #2 data #3%
%  {\pdfannot width #1sp height -#2sp depth 0sp {#3}}
%
% This is corrected in version 14. When this version is wide
% spread, this will be cleaned up.

\ifnum\pdftexversion>13

  \def\doPDFannotation width #1 height #2 data #3%
    {\pdfannot width #1sp height #2sp depth 0sp {#3}}

\else

  \def\doPDFannotation width #1 height #2 data #3%
    {\hbox{\raise#2sp\hbox{\pdfannot width #1sp height #2sp depth 0sp {#3}}}}

\fi

%D \macros 
%D   {doPDFannotationobject} 
%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 class #1 name #2 width #3 height #4 data #5%
%  {\pdfannot width #3sp height -#4sp depth 0sp {#5}%
%   \dosetobjectreference{#1}{#2}{\the\pdflastannot}}

\def\doPDFannotationobject class #1 name #2 width #3 height #4 data #5%
  {\doPDFannotation width #3 height #4 data {#5}%
   \dosetobjectreference{#1}{#2}{\the\pdflastannot}}

%D \macros 
%D   {doPDFaddtocatalog,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\doPDFpageattribute#1%
  {\expanded{\global\pdfpageattr{#1\the\pdfpageattr}}}

\def\doPDFpagesattribute#1%
  {\expanded{\global\pdfpagesattr{#1\the\pdfpagesattr}}}

\def\doPDFresetattributes%
  {\global\pdfpageattr{}}

\appendtoks\doPDFresetattributes\to\everyaftershipout

%D \macros 
%D   {doPDFbookmark} 
%D
%D Well, isn't the next one ugly? Thanks to the \PDF\ 
%D standard. 

% obsolete cq. buggy in pdfTeX
%
% \def\doPDFbookmark level #1 n #2 text #3 page #4 open #5%
%   {\pdfoutline
%      goto page #4\space
%      \ifcase#2 \else count \ifcase#5-\fi#2 \fi
%      {#3}}

\def\doPDFbookmark level #1 n #2 text #3 page #4 open #5%
  {\pdfoutline
     user {<</S /GoTo /D [#4\PDFpageviewwrd]>>}%
     \ifcase#2 \else count \ifcase#5-\fi#2 \fi
     {#3}}

%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 class #1 name #2 data #3%
  {\flushatshipout
     {\immediate\pdfobj{<< #3 >>}\dosetobjectreference{#1}{#2}{\the\pdflastobj}}}

\def\doPDFarrayobject class #1 name #2 data #3%
  {\flushatshipout
     {\immediate\pdfobj{[ #3 ]}\dosetobjectreference{#1}{#2}{\the\pdflastobj}}}

%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#3\space0 R\fi}}

%D \macros
%D   {initializePDFnegative}
%D 
%D Here follow some rather obscure macros. They will only 
%D come into action when one wants negated output. 

\let\PDFextgstates\empty

\def\initializePDFnegative%
  {\bgroup
   \pdfcompresslevel=0
   \immediate\pdfobj attr {/FunctionType 4 /Range [0 1] /Domain [0 1]} stream {{1 exch sub}} 
   \immediate\pdfobj{<</Type /ExtGState /TR \the\pdflastobj\space0 R>>}
   \xdef\PDFextgstates{\PDFextgstates/GSnegative \the\pdflastobj\space0 R}
   \immediate\pdfobj{<</Type /ExtGState /TR /Identity>>}
   \xdef\PDFextgstates{\PDFextgstates/GSpositive \the\pdflastobj\space0 R}
   \global\let\initializePDFnegative\relax
   \egroup
   \expanded{\pdfpageresources{/ExtGState <<\PDFextgstates>>}}}
 
%D Now we can finish this module. 

\stopspecials

\protect

\endinput
