%D \module
%D   [       file=spec-pdf,
%D        version=1997.09.20,
%D          title=\CONTEXT\ Special Macros,
%D       subtitle=Adobe \ACROBAT\ version 2.1,
%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 licen-en.pdf for 
%C details. 

% funny things: mail to yeny: "please geen auto-crlf in special"

\unprotect

%D This driver is build on top of the general \PDF\ macros,
%D as defined in \type{spec-fdf}, so we inherit that one. 

\startspecials[pdf][fdf]

%D \macros
%D   {dosetupinteraction,
%D    doPDFsetopenaction,doPDFsetcloseaction}
%D
%D Instead of a prolog, we can put the code in the file
%D ourselve.
%D
%D \starttypen
%D \definespecial\dosetupinteraction%
%D   {\special
%D      {\@@insertpostscriptretain
%D         /pdfmark where
%D           {pop}
%D           {userdict /pdfmark /cleartomark load put}
%D         ifelse}}
%D \stoptypen
%D
%D We decided to use a prolog file. The following code has to
%D be put somewhere, e.g.\ in the startup directory of
%D \DISTILLER. To overcome problems, we always embed the fonts,
%D but copyrights force us always to make subsets.
%D
%D \starttypen
%D /currentdistillerparams where
%D   { pop } { userdict /currentdistillerparams { 1 dict } put } ifelse
%D
%D /setdistillerparams     where
%D   { pop } { userdict /setdistillerparams { pop } put } ifelse
%D
%D << /AntiAliasColorImages   true
%D    /AntiAliasGrayImages    true
%D    /AntiAliasMonoImages    true
%D    /ConvertCMYKImagesToRGB true
%D    /MaxSubsetPct           99
%D    /EmbedAllFonts          true
%D    /SubSetFonts            true >> setdistillerparams
%D \stoptypen
%D
%D Beware, this is the PostScript Level 2 way of doing things.

\definespecial\dosetupinteraction%
  {\showmessage{\m!interactions}{21}{acrobat}}

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

%D \macros
%D   {dostartthisislocation}
%D
%D We share a lot of macros with the \PDFTEX\ driver. First
%D the one that handles named destinations.

\definespecial\dostartthisislocation {\doPDFstartthisislocation}

%D \macros
%D   {doresetgotowhereever,
%D    dostartgotolocation,dostartgotorealpage,dostartgotoJS,
%D    dostartexecutecommand,dostartrunprogram,dostartgotoprofile}
%D
%D The next specials are responsible for handling references.
%D Each goto handler can handle multiple references.

\definespecial\doresetgotowhereever {\doPDFresetgotowhereever}
\definespecial\dostartgotolocation  {\doPDFstartgotolocation}
\definespecial\dostartgotorealpage  {\doPDFstartgotorealpage}
\definespecial\dostartgotoJS        {\doPDFstartgotoJS}
\definespecial\dostartexecutecommand{\doPDFstartexecutecommand}
\definespecial\dostartrunprogram    {\doPDFstartrunprogram}
\definespecial\dostartgotoprofile   {\doPDFstartgotoprofile}

%D \macros
%D   {doflushJSpreamble}
%D
%D Thanks to the fact that \DISTILLER\ cannot handle multiple
%D names entries in the document catalog, for the moment we
%D have to misuse the page attributes. Beware, the preambles
%D must be packed.

\definespecial\doflushJSpreamble#1% 
  {\bgroup
   \ifoneJSpreamble
     \edef\sanitizedJScode{\getJSpreamble{#1}}%
     \expandafter\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode
     \special % nota bene, the page starts at 1
       {\@@insertpostscriptretain
          [ /_objdef{JS:#1} /type /dict /OBJ pdfmark
          [ {JS:#1} << /S /JavaScript /JS (\sanitizedJScode) >> /PUT pdfmark
          [ {Page1} << /AA << /O {JS:#1} >> >> /PUT pdfmark}%
   \else % temporary message
     \writestatus{\m!specials}{Acrobat workaround needed: please pack JS preambles}%
   \fi
   \egroup}

%D \macros
%D   {dostarthide,dostophide}
%D
%D Hopefully some day hiding navigational things when
%D printing \PDF\ files will be supported properly.

\definespecial\dostarthide%
  {\special
     {\@@insertpostscriptretain
        [ /DataSource (false \iftrue\string{\else}\fi)
          /PS
        pdfmark}}

\definespecial\dostophide%
  {\special
     {\@@insertpostscriptretain
        [ /DataSource (\iffalse{\else\string}\fi if)
          /PS
        pdfmark}}

%D \macros
%D   {dosetupscreen,
%D    dosetupidentity}
%D
%D We can set up the page dimensions, full screen start up 
%D mode and identify the file with:

\definespecial\dosetupscreen{\doPDFsetupscreen\printpapierhoogte}

\definespecial\dosetupidentity#1#2#3#4#5%
  {\bgroup
   \enablePDFdocencoding
   \special
     {\@@insertpostscriptretain
        [ /Title (#1)
          /Subject (#2)
          /Author (#3)
          /Creator (#4)
          /ModificationDate (#5)
          /DOCINFO
        pdfmark}%
   \egroup}

%D \macros
%D   {dobeginofprofile,doendofprofile}
%D
%D Profile support is still far from perfect. This is
%D especially due to the fact that the specification of
%D threads are sort of fuzzy and depend on the viewer.

\definespecial\dobeginofprofile#1#2#3#4% label width height page
  {\bgroup
   \setPDFdestination{#1}%
   \doifsomething{\PDFdestination}
     {\ScaledPointsToBigPoints{#2}\width
      \ScaledPointsToBigPoints{#3}\height
      \special
        {\@@insertpostscriptretain
           [ /Title (\PDFdestination)
             /Rect [0 0 \width\space\height]
             /ARTICLE
           pdfmark}}%
   \egroup}

\definespecial\doendofprofile%
  {}

%D Apart from movies, graphic inclusion is handled in the
%D \POSTSCRIPT\ drivers. We just link the movie annotation
%D handled to the file inclusion system.

\def\setcurrentmovie{\xdef\currentmovie}

\definefileinsertion{yy}{mov}{\doPDFinsertmov}
\definefileinsertion{tr}{mov}{\doPDFinsertmov}

%D \macros
%D   {dostartobject,dostopobject,
%D    doinsertobject}
%D
%D Objects, those nice reusable pieces of text and graphics,
%D are handled by three specials:

\definespecial\dostartobject#1#2#3#4#5%
  {\bgroup
   \setbox\nextbox=\hbox\bgroup
     \bgroup
     \ScaledPointsToBigPoints{#3}\width
     \ScaledPointsToBigPoints{#4}\height
     \ScaledPointsToBigPoints{#5}\depth
     \dosetobjectreference{#1}{#2}{#1::#2}%
     \special
       {\@@insertpostscriptretain
          [ /BBox [0 -\depth\space \width\space \height]
            /_objdef {#1::#2}
            /BP
          pdfmark}%
     \egroup}

\definespecial\dostopobject%
  {\special
      {\@@insertpostscriptretain
         [ /EP
         pdfmark}%
   \egroup
   \smashbox\nextbox
   \flushatshipout{\box\nextbox}%
   \egroup}

\definespecial\doinsertobject#1#2%
  {\hbox
     {\dogetobjectreference{#1}{#2}\PDFobjectreference
      \ifx\PDFobjectreference\empty \else
        \special
          {\@@insertpostscriptretain
             [ {\PDFobjectreference}
               /SP
             pdfmark}%
      \fi}}

%D \macros
%D   {doinsertbookmark}
%D
%D Although personally I never use bookmarks, \CONTEXT\ does
%D support them, due to user requests.

\definespecial\doinsertbookmark {\doPDFinsertbookmark}

%D \macros
%D   {dosetpagetransition}
%D
%D Page transitions, again a user wish, is taken care of by:

\definespecial\dosetpagetransition{\doPDFsetpagetransition}

%D \macros 
%D   {doinsertcomment}
%D
%D I never needed (and used) one until now, but here is the 
%D text annotation special:

\definespecial\doinsertcomment{\doPDFinsertcomment}

%D \macros
%D   {dopresetlinefield,dopresettextfield,
%D    dopresetchoicefield,dopresetpopupfield,dopresetcombofield,
%D    dopresetpushfield,dopresetcheckfield,
%D    dopresetradiofield,dopresetradiorecord}
%D
%D There is nothing enervating to the next few mappings.

\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, used in resetting and submitting, are handled
%D by:

\definespecial\dodefinefieldset{\doFDFdefinefieldset}
\definespecial\dogetfieldset   {\doFDFgetfieldset}
\definespecial\doiffieldset    {\doFDFiffieldset}

%D \macros
%D   {doPDFdestination}
%D
%D Last we implement the low level pdfmark macros. The
%D definitions are rather verbose. First the destination
%D macro.

\def\doPDFdestination name #1%
  {\special
     {\@@insertpostscriptretain
        [ /Dest /#1\space
          \PDFpageview
          /DEST
        pdfmark}}

%D \macros
%D   {doPDFaction,doPDFannotation,doPDFannotationobject,
%D    ifsharePDFactions}
%D
%D We have three alternative annotation macros. The first
%D handles the goto ones, the second takes care of for instance
%D movies and the third is used in fields.

\newcount\nofPDFsimilar

\newif\ifsharePDFactions \sharePDFactionstrue

% \def\doPDFaction width #1 height #2 action #3%
%   {\bgroup
%    \ScaledPointsToBigPoints{#1}\width
%    \ScaledPointsToBigPoints{#2}\height
%    \ifnum\similarreference=1
%      %\ifsharePDFactions
%      %  \global\advance\nofPDFsimilar by 1
%      %  \special
%      %    {\@@insertpostscriptretain
%      %       [ /_objdef {PDF::sim:\the\nofPDFsimilar} /type /dict /OBJ pdfmark
%      %       [ {PDF::sim:\the\nofPDFsimilar} << #3 >> /PUT pdfmark}%
%      %  \xdef\lastFDFaction{{PDF::sim:\the\nofPDFsimilar}}%
%      %\else
%         \xdef\lastFDFaction{<<#3>>}%
%      %\fi
%    \fi
%    \special
%      {\@@insertpostscriptretain
%         [ \ifcase\similarreference
%             /Action <<#3>>
%           \else
%             /Action \lastFDFaction\space
%           \fi
%           /Rect [0 0 \width\space \height]
%           /Border [0 0 0]
%           /Subtype /Link
%           /ANN 
%         pdfmark}%
%    \egroup}

\def\doPDFaction width #1 height #2 action #3%
  {\bgroup
   \ScaledPointsToBigPoints{#1}\width
   \ScaledPointsToBigPoints{#2}\height
   \ifcase\similarreference\relax
     \xdef\lastPDFaction{<<#3>>}%
   \or
     %\ifsharePDFactions
     %  \global\advance\nofPDFsimilar by 1
     %  \special
     %    {\@@insertpostscriptretain
     %       [ /_objdef {PDF::sim:\the\nofPDFsimilar} /type /dict /OBJ pdfmark
     %       [ {PDF::sim:\the\nofPDFsimilar} << #3 >> /PUT pdfmark}%
     %  \xdef\lastPDFaction{{PDF::sim:\the\nofPDFsimilar}}%
     %\else
        \xdef\lastPDFaction{<<#3>>}%
     %\fi
   \fi
   \ifcollectreferenceactions \else
     \special
       {\@@insertpostscriptretain
          [ /Action \lastPDFaction\space
            /Rect [0 0 \width\space \height]
            /Border [0 0 0]
            /Subtype /Link
            /ANN 
          pdfmark}%
   \fi
   \egroup}

\def\doPDFannotation width #1 height #2 data #3%
  {\bgroup
   \ScaledPointsToBigPoints{#1}\width
   \ScaledPointsToBigPoints{#2}\height
   \special
     {\@@insertpostscriptretain
        [ /Rect [0 0 \width\space \height] #3
          /ANN
        pdfmark}%
   \egroup}

\let\doPDFtextannotation=\doPDFannotation

\def\doPDFannotationobject class #1 name #2 width #3 height #4 data #5%
  {\bgroup
   \ScaledPointsToBigPoints{#3}\width
   \ScaledPointsToBigPoints{#4}\height
   \special
     {\@@insertpostscriptretain
        [ /_objdef {#1::#2}
          /Rect [0 0 \width\space \height] #5
          /ANN
        pdfmark}%
   \egroup
   \dosetobjectreference{#1}{#2}{#1::#2}}

%D \macros 
%D   {doPDFdictionaryobject,doPDFarrayobject}
%D 
%D These two macros are used to build low level objects.  

\def\doPDFdictionaryobject class #1 name #2 data #3%
  {\special
     {\@@insertpostscriptretain
        [ /_objdef {#1::#2} /type /dict /OBJ pdfmark
        [ {#1::#2} << #3 >> /PUT pdfmark}%
   \dosetobjectreference{#1}{#2}{#1::#2}}

\def\doPDFarrayobject class #1 name #2 data #3%
  {\special
     {\@@insertpostscriptretain
        [ /_objdef {#1::#2} /type /array /OBJ pdfmark
        [ {#1::#2} 0 [#3] /PUTINTERVAL pdfmark}%
   \dosetobjectreference{#1}{#2}{#1::#2}}

%D \macros 
%D   {doPDFaddtocatalog,doPDFpageattribute,doPDFpagesattribute}
%D 
%D Next come our housekeeping macros. 

\def\doPDFaddtocatalog#1%
  {\special
     {\@@insertpostscriptretain
        [ {Catalog} << #1 >>
          /PUT
        pdfmark}}

\def\doPDFpageattribute#1%
  {\special
     {\@@insertpostscriptretain
        [ {ThisPage} #1
          /PUT
        pdfmark}}

\def\doPDFpagesattribute#1%
  {\special
     {\@@insertpostscriptretain
        [ #1
          /PAGES
        pdfmark}}

\let\doPDFresetpageattributes=\relax

%D \macros 
%D   {doPDFbookmark}
%D
%D This is how we force bookmarks entries in the file.  

\def\doPDFbookmark level #1 n #2 text #3 page #4 open #5%
  {\special
     {\@@insertpostscriptretain
        [ /Page #4\space
          \ifcase#2 \else/Count \ifcase#5-\fi#2 \fi
          \PDFpageview
          /Title (#3)
          /OUT
        pdfmark}}

%D \macros 
%D   {defaultobjectreference,doPDFgetobjectreference}
%D
%D The object references are \type{{named}}, that is, no hard
%D coded numbers are needed (opposite to \PDFTEX).

\def\defaultobjectreference#1#2{#1::#2}

\def\doPDFgetobjectreference#1#2#3%
  {\dogetobjectreference{#1}{#2}#3%
   \ifx#3\empty\else\edef#3{{#3}}\fi}
   %\edef#3{\ifx#3\empty null\else{#3}\fi}}

%D Done.

\stopspecials

\protect

\endinput
