%D \module
%D   [       file=spec-dpx,
%D        version=2005.08.12,
%D          title=\CONTEXT\ Special Macros,
%D       subtitle=DVIPDFMx support,
%D         author=Jin-Hwan Cho,
%D           date=\currentdate,
%D      copyright={Jin-Hwan Cho \& Hans Hagen}]
%C
%C DVIPDFMx is an eXtended version of the DVIPDFM, a DVI to PDF
%C translator, still under construction by Jin-Hwan Cho and
%C Shunsaku Hirata.
%C
%C It supports multi-byte character encodings and large character
%C sets for East Asian languages by CID-keyed font technology,
%C and many features including PDF encryption, PDF bookmarks and
%C annotations with Chinese, Japanese, Korean characters, etc.
%C
%C DVIPDFMx (and information) can be downloaded from:
%C
%C   http://project.ktug.or.kr/dvipdfmx/

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

\startspecials[dpx][reset,fdf]

%D 1. Modified codes from \type{spec-dpm}

%D \macros
%D   {jobsuffix}
%D
%D Because no intermediate output format is used, we set the
%D jobsuffix to \PDF.

\setjobsuffix{pdf}

%D Map files (experimental)

\definespecial\doloadmapfile#1#2%
  {\flushatshipout{\special{pdf:mapfile +#2}}}

%D DVIPDFMx supports the special command \type{pdf: literal ...}
%D since the version \type{dvipdfmx-20021028}.
%D
%D 1. \type{pdf: literal #1} puts the given PDF commands \#1
%D    after changing the text matrix with \type{"1 0 0 1 x y cm"}
%D    to set the current DVI position $(x,y)$ to the origin.
%D
%D 2. \type{pdf: literal reverse #1} puts the given PDF commands \#1
%D    after changing the text matrix with \type{"1 0 0 1 -x -y cm"}.
%D
%D 3. \type{pdf: literal direct #1} puts directly the given PDF
%D    commands \#1 without changing the text matrix.
%D
%D Since the version \type{dvipdfmx-20050812}, the role of the special
%D command \type{pdf:literal} is changed so that
%D
%D 1. \type{pdf:literal #1} puts the given PDF commands \#1
%D    after changing the text matrix with \type{"1 0 0 1 x y cm"}
%D    to set the current DVI position $(x,y)$ to the origin. After that
%D    it restores the previous setting by changing the text matrix with
%D    \type{"1 0 0 1 -x -y cm"}.
%D
%D 2. \type{pdf:literal direct #1} puts directly the given PDF commands
%D    \type {#1} without changing the text matrix.
%D
%D Literal \PDF\ inclusion is implemented as:

\def\PDFcode       #1{\special{pdf:literal #1}}
\def\PDFcontentcode#1{\special{pdf:content #1}}
\def\PDFdirectcode #1{\special{pdf:literal direct #1}}

%D \type{\dosetuppaper} in \type{spec-dpm} did not work properly
%D because DVIPDFM did not permit changing the page size.
%D
%D However, DVIPDFMx permits different page size in each page
%D since the version \type{dvipdfmx-20021028}.
%D
%D \macros
%D   {dosetuppaper}
%D
%D A simple one.

\let\PDFpagexyzspec\relax \def\PDFpagexyzspec{@xpos @ypos 0} % untested

\definespecial\dosetuppaper#1#2#3%
  {\bgroup
   \scratchdimen#2\edef\width {\the\scratchdimen\space}%
   \scratchdimen#3\edef\height{\the\scratchdimen\space}%
   \special{pdf:pagesize width \width height \height}%
   \egroup}

%D \macros
%D   {doinsertfile}
%D
%D Only \METAPOST, \BMP\ \JPG\ \PNG\ and \PDF\ inclusion are supported.

\definespecial\doinsertfile
  {\dofileinsertion{dpx}\@@DriverImageType}

%D Even though DVIPDFM supports \METAPOST directly, the funtionality
%D is not good. It conflicts much with \CONTEXT.
%D
%D So, \METAPOST will be treated as the same way as PDFTeX using
%D MPtoPDF in DVIPDFMx since the version \type{dvipdfmx-20021028}.

%D DVIPDFM (and DVIPDFMx too) supports the image files with
%D the extension, \PDF, \JPG, \PNG, \BMP, and \EPS.

% \def\handleepsimage
%   {\PointsToWholeBigPoints\@@DriverImageWidth \width
%    \PointsToWholeBigPoints\@@DriverImageHeight\height
%    \special
%      {PSfile="\@@DriverImageFile"\space
%       llx=\EPSllx\space lly=\EPSlly\space
%       urx=\EPSurx\space ury=\EPSury\space
%       rwi=\width0\space rhi=\height0}}

% \definefileinsertion{dpx}{mps}{\handleepsimage}

\definefileinsertion{dpx}{mps}
  {\hbox
     {\convertMPtoPDF\@@DriverImageFile{1}{1}%
      \global\let\PDFimagereference\empty}}

\def\handlebmpimage
  {\special{pdf: image
     width  \@@DriverImageWidth \space
     height \@@DriverImageHeight\space
     (\@@DriverImageFile)}}

\definefileinsertion{dpx}{pdf}{\handlebmpimage}
\definefileinsertion{dpx}{jpg}{\handlebmpimage}
\definefileinsertion{dpx}{png}{\handlebmpimage}
\definefileinsertion{dpx}{bmp}{\handlebmpimage}

\definefileinsertion{dpx}{mov}{\doPDFinsertmov}
\definefileinsertion{dpx}{avi}{\doPDFinsertmov}

%D \macros
%D  {doinsertsoundtrack}
%D
%D Sounds are supported too.

\definespecial\doinsertsoundtrack{\doPDFinsertsoundtrack}

%D \macros
%D  {doovalbox}

\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 Unfortunately the direct \PDF\ inclusion is not suited
%D for the next macros, which means that we cannot use the
%D \type {\doPDF..} alternatives. Since \CONTEXT\ maintains
%D its own colorstack, we use the \DVIPS\ alternatives.

\definespecial\dostartgraymode     {\doPDFstartgraymode}
\definespecial\dostopgraymode      {\doPDFstopgraymode}
\definespecial\dostartrgbcolormode {\doPDFstartrgbcolormode}
\definespecial\dostartcmykcolormode{\doPDFstartcmykcolormode}
\definespecial\dostartgraycolormode{\doPDFstartgraycolormode}
\definespecial\dostartspotcolormode{\doPDFstartspotcolormode}
\definespecial\dostopcolormode     {\doPDFstopcolormode}

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

\definespecial\dostartrotation #1{\special{pdf:btrans rotate #1}}
\definespecial\dostoprotation    {\special{pdf:etrans}}
\definespecial\dostartscaling#1#2{\special{pdf:btrans xscale #1 yscale #2}}
\definespecial\dostopscaling     {\special{pdf:etrans}}
\definespecial\dostartmirroring  {\special{pdf:btrans xscale -1}}
\definespecial\dostopmirroring   {\special{pdf:etrans}}

%D Negation is not (yet) supported:
\definespecial\dostartnegative    {\doPDFstartnegative}
\definespecial\dostopnegative     {\doPDFstopnegative}
\definespecial\dostartoverprint   {\doPDFstartoverprint}
\definespecial\dostopoverprint    {\doPDFstopoverprint}

\definespecial\dostarttransparency{\doPDFstarttransparency}
\definespecial\dostoptransparency {\doPDFstoptransparency}

\PDFtransparencysupportedtrue

\def\@@PDT{@PDT@}

\ifx\PDFcurrenttransparency\undefined
  \newcount\PDFcurrenttransparency \PDFcurrenttransparency=0 % -1
\fi

\def\assignPDFtransparency#1#2%
  {\def\PDFtransparencyidentifier{/Tr#1}%
   \def\PDFtransparencyreference{@TR:#2}} % todo: \PDFobjref{TR:#2}

\def\presetPDFtransparency#1#2%
  {\initializePDFtransparency
   \executeifdefined{\@@PDT#1:#2}{\dopresetPDFtransparency{#1}{#2}}}

\def\dopresetPDFtransparency#1#2%
  {\global\advance\PDFcurrenttransparency \plusone
   \doPDFreserveDPXobject{TR:\the\PDFcurrenttransparency}{<< >>}% hack
   \special{pdf:\doPDFcheckedDPXobject{TR:\the\PDFcurrenttransparency}\PDFtransparancydictionary{#1}{#2}{}}%
   \edef\PDFtransparencyidentifier{/Tr\the\PDFcurrenttransparency}%
   \edef\PDFtransparencyreference {@TR:\the\PDFcurrenttransparency}%
   \setxvalue{\@@PDT#1:#2}%
     {\noexpand\assignPDFtransparency{\the\PDFcurrenttransparency}{\the\PDFcurrenttransparency}}%
   \appendtoPDFdocumentextgstates
     {\PDFtransparencyidentifier\space
      \PDFtransparencyreference\space}}

\def\initializePDFtransparency
  {\doPDFreserveDPXobject{TR:0}{<< >>}% hack
   \special{pdf:\doPDFcheckedDPXobject{TR:0}\PDFtransparancydictionary{1}{1}{/AIS false}}%
   \xdef\PDFtransparencyresetidentifier{/Tr0}%
   \xdef\PDFtransparencyresetreference{@TR:0}%
   \setxvalue{\@@PDT0:0}%
     {\noexpand\assignPDFtransparency{0}{0}}%
   \appendtoPDFdocumentextgstates
     {\PDFtransparencyresetidentifier\space
      \PDFtransparencyresetreference\space}%
   \global\let\initializePDFtransparency\relax}

%D \macros
%D   {dosetupinteraction,
%D    dosetupopenaction,dosetupcloseaction}

\definespecial\dosetupinteraction
  {\showmessage\m!interactions{21}{DVIPDFMx}}

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

%D \macros
%D   {doresetgotowhereever,
%D    dostartthisisrealpage,dostartthisislocation,
%D    dostartgotorealpage,dostartgotolocation,dostartgotoJS}

\definespecial\doresetgotowhereever {\doPDFresetgotowhereever}
\definespecial\dostartthisislocation{\doPDFstartthisislocation}

\definespecial\dostartgotolocation{\doPDFstartgotolocation}
\definespecial\dostartgotorealpage{\doPDFstartgotorealpage}
\definespecial\dostartgotoJS      {\doPDFstartgotoJS}

%D \macros
%D   {doflushJSpreamble}

\definespecial\doflushJSpreamble#1%
  {\bgroup
   \let\compositeJScode\empty
   \def\docommand##1%
     {\edef\sanitizedJScode{\getJSpreamble{##1}}%
      \@EA\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode
      \special{pdf:object @JS:##1 <</S /JavaScript /JS (\sanitizedJScode)>>}%
      \edef\compositeJScode{\compositeJScode\space (##1) @JS:##1}}%
   \processcommalist[#1]\docommand
   \special{pdf:names /JavaScript [\compositeJScode]}%
   \egroup}

%D \macros
%D   {dostarthide,dostophide}

\definespecial\dostarthide{}
\definespecial\dostophide {}

%D \macros
%D   {dosetupscreen}

\definespecial\dosetupscreen  {\doPDFsetupscreen  \printpaperheight}

\definespecial\dosetupartbox  {\doPDFsetupartbox  \printpaperheight}
\definespecial\dosetupcropbox {\doPDFsetupcropbox \printpaperheight}
\definespecial\dosetupbleedbox{\doPDFsetupbleedbox\printpaperheight}
\definespecial\dosetuptrimbox {\doPDFsetuptrimbox \printpaperheight}

%D \macros
%D   {dostartexecutecommand}

\definespecial\dostartexecutecommand{\doPDFstartexecutecommand}

%D \macros
%D   {dosetupidentity}

\definespecial\dosetupidentity{\doPDFsetupidentity}

%D \macros
%D   {dostartrunprogam}

\definespecial\dostartrunprogram{\doPDFstartrunprogram}

%D \macros
%D   {dostartgotoprofile, dostopgotoprofile,
%D    dobeginofprofile, doendofprofile}

\definespecial\dostartgotoprofile{\doPDFstartgotoprofile}

\definespecial\dobeginofprofile#1#2#3#4%
  {\bgroup
   \setPDFdestination{#1}%
   \scratchdimen#2\edef\width {\the\scratchdimen\space}%
   \scratchdimen#3\edef\height{\the\scratchdimen\space}%
   \doifsomething{\PDFdestination}
     {\special
        {pdf:thread @ART::\PDFdestination\space
             width \width height \height
             <</Title (\PDFdestination)>>}}%
   \egroup}

\definespecial\doendofprofile
  {}

%D \macros
%D  {doinsertbookmark}

\definespecial\doinsertbookmark{\doPDFinsertbookmark}

%D \macros
%D  {dostartobject,dostopobject,doinsertobject}
%D
%D Modified to support the color shading feature since version
%D \type{dvipdfmx-20021128}.

% wd nextbox > #3 ivm offset

% \definespecial\dostartobject#1#2#3#4#5%
%   {\bgroup
%    \dowithnextbox
%      {\dosetobjectreference{#1}{#2}{@#1::#2}%
%       \scratchdimen#3\edef\width {\the\scratchdimen\space}%
%       \scratchdimen#4\edef\height{\the\scratchdimen\space}%
%       \setbox\nextbox\vbox
%         {\special{pdf:bxobj @#1::#2 width \width height \height}%
%          % we need to compensate for the box offset (ugly, sigh)
%          \scratchdimen\nextboxht
%          \advance\scratchdimen\nextboxdp
%          \advance\scratchdimen-#4\relax
%          \nextboxdp\zeropoint
%          \nextboxht\zeropoint
%          \hbox to #3{\hss\lower.5\scratchdimen\box\nextbox\hss}%
%          \ifx\currentPDFresources\empty
%          \else
%            \special{pdf:put @resources <<\currentPDFresources>>}%
%            \global\let\currentPDFresources\empty
%          \fi
%          \special{pdf:exobj}}%
%          \smashbox\nextbox
%          \flushatshipout{\box\nextbox}%
%          \egroup}%
%     \hbox\bgroup}

% \definespecial\dostopobject
%   {\egroup}

\def\doDVIPDFMXstartobject#1#2#3#4#5#6%
  {\bgroup
   \dowithnextbox
     {\ifcase#1\or\dosetobjectreference{#2}{#3}{@#2::#3}\fi
      \scratchdimen#4\edef\width {\the\scratchdimen\space}%
      \scratchdimen#5\edef\height{\the\scratchdimen\space}%
      \setbox\nextbox\vbox
        {\special{pdf:bxobj @#2::#3 width \width height \height}%
         % we need to compensate for the box offset (ugly, sigh)
         \scratchdimen\nextboxht
         \advance\scratchdimen\nextboxdp
         \advance\scratchdimen-#5\relax
         \nextboxdp\zeropoint
         \nextboxht\zeropoint
         \hbox to #4{\hss\lower.5\scratchdimen\box\nextbox\hss}%
         \ifx\currentPDFresources\empty
         \else
           \special{pdf:put @resources <<\currentPDFresources>>}%
           \global\let\currentPDFresources\empty
         \fi
         \special{pdf:exobj}}%
      \finalizeobjectbox\nextbox
      \smashbox\nextbox
      \flushatshipout{\box\nextbox}%
      \egroup}%
    \hbox\bgroup}

\def\doDVIPDFMXstopobject
  {\egroup}

\definespecial\dostartobject#1#2#3#4#5%
  {\doDVIPDFMXstartobject\plusone{#1}{#2}{#3}{#4}{#5}}

\definespecial\dostopobject
  {\doDVIPDFMXstopobject}

\definespecial\doinsertobject#1#2%
  {\hbox
     {\doPDFgetobjectreference{#1}{#2}\PDFobjectreference
      \ifx\PDFobjectreference\empty \else
        \special{pdf:uxobj @#1::#2}%
      \fi}}

%D \macros
%D   {dosetpagetransition}

\definespecial\dosetpagetransition{\doPDFsetpagetransition}

%D \macros
%D   {doinsertcomment, doflushcomments}

\definespecial\doinsertcomment{\doPDFinsertcomment}
\definespecial\doflushcomments{\doPDFflushcomments}

%D \macros
%D   {dopresetlinefield,dopresettextfield,
%D    dopresetchoicefield,dopresetpopupfield,dopresetcombofield,
%D    dopresetpushfield,dopresetcheckfield,
%D    dopresetradiofield,dopresetradiorecord}

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

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

%D \macros
%D   {doregistercalculationset}

\definespecial\doregistercalculationset{\doFDFregistercalculationset}

%D \type{\doPDFdestination} in \type{spec-dpm} had a bug.
%D
%D \macros
%D   {doPDFdestination}

\def\doPDFdestination#1%
  {\special{pdf:names /Dests (#1) [@thispage \PDFpageviewwrd]}}

%D \macros
%D   {doPDFaction,doPDFannotation,ifsharePDFactions}
%D
%D Sharing is not yet supported.

\newif\ifsharePDFactions \sharePDFactionsfalse

\def\dodoPDFaction#1#2#3#4%
  {\ifcollectreferenceactions
     \xdef\lastPDFaction{#4}%
   \else
     \bgroup
    % this is yet untested
    %\ifsharePDFactions
    %  \ifcase\similarreference\relax
    %    \xdef\lastPDFaction{<<#4>>}%
    %  \or
    %    \global\advance\nofPDFsimilar by 1
    %    \special{pdf: object @PDF::sim:\the\nofPDFsimilar\space<<#4>>}%
    %    \xdef\lastPDFaction{@PDF::sim:\the\nofPDFsimilar}%
    %  \else
    %    % leave \lastPDFaction untouched
    %  \fi
    %\else
       \xdef\lastPDFaction{<<#4>>}%
    %\fi
     \scratchdimen#2\edef\width {\the\scratchdimen\space}%
     \scratchdimen#3\edef\height{\the\scratchdimen\space}%
     \special{pdf:ann #1 width \width height \height
       <</Subtype /Link /Border [0 0 0]
         \ifhighlighthyperlinks \else /H /N \fi
         /A \lastPDFaction\space>>}%
     \egroup
   \fi}

\def\doPDFaction#1#2#3%
  {\dodoPDFaction\empty{#1}{#2}{#3}}

%D \type{\doPDFannotation} in \type{spec-dpm} had a bug.
%D
%D \type{\doPDFannotation} conflicts with \type{\doPDFinsertmov},
%D since width and height also defined in \type{\doPDFinsertmov}.

\def\doPDFannotation#1#2#3%
  {\bgroup
   \edef\data{#3}%
   \scratchdimen#1\edef\width {\the\scratchdimen\space}%
   \scratchdimen#2\edef\height{\the\scratchdimen\space}%
   \special{pdf:ann width \width height \height <<\data>>}%
   \egroup}

%D \macros
%D   {doPDFannotationobject,doPDFactionobject}

\def\doPDFannotationobject#1#2#3#4#5%
  {\bgroup
   \scratchdimen#3\edef\width {\the\scratchdimen\space}%
   \scratchdimen#4\edef\height{\the\scratchdimen\space}%
   \special{pdf:ann @#1::#2 width \width height \height <<#5>>}%
   \dosetobjectreference{#1}{#2}{@#1::#2}%
   \egroup}

\def\doPDFactionobject#1#2#3#4#5%
  {\dodoPDFaction{@#1::#2}{#3}{#4}{#5}%
   \dosetobjectreference{#1}{#2}{@#1::#2}}

%D \macros
%D   {doPDFaddtocatalog,doPDFaddtoinfo,
%D    doPDFpageattribute,doPDFpagesattribute}

% we could move much more to spec-fdf

% \ifx\pdfcatalog      \undefined \newtoks\pdfcatalog       \fi
% \ifx\pdfinfo         \undefined \newtoks\pdfinfo          \fi
% \ifx\pdfpageattr     \undefined \newtoks\pdfpageattr      \fi
% \ifx\pdfpageresources\undefined \newtoks\pdfpageresources \fi
% \ifx\pdfpagesattr    \undefined \newtoks\pdfpagesattr     \fi

% \def\doPDFaddtocatalog  #1{\expanded{\global\pdfcatalog      {#1\the\pdfcatalog      }}}
% \def\doPDFaddtoinfo     #1{\expanded{\global\pdfinfo         {#1\the\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}

% \appendtoks
%   \special{pdf: put @catalog <<#1>>}%
%   \special{pdf: docinfo      <<#1>>}%
%   \special{pdf: put @pages   <<#1>>}%
% \to \everylastshipout

% \appendtoks
%   \special{pdf: put @thispage <<#1>>}%
% \to\everyshipout

\def\doPDFaddtocatalog#1%
  {\special{pdf:put @catalog <<#1>>}}

\def\doPDFaddtoinfo#1%
  {\special{pdf:put @docinfo <<#1>>}}

\def\doPDFpageattribute#1%
  {\special{pdf:put @thispage <<#1>>}}

\def\doPDFpagesattribute#1%
  {\special{pdf:put @pages <<#1>>}}

\def\doPDFpageresource#1%
  {\special{pdf:put @resources <<#1>>}}

\let\doPDFresetpageresources \relax
\let\doPDFresetpageattributes\relax

%D \type{\doPDFbookmark} in \type{spec-dpm} had a bug.
%D The openbookmark option \#5 is not supported yet.
%D
%D \macros
%D   {doPDFbookmark}

\def\doPDFbookmark#1#2#3#4#5%
  {\ifcase#1\else
     %\scratchcounter#4\advance\scratchcounter\minusone
     \special{pdf:outline #1 %\ifcase#5 opened\fi
        % <</Title (#3) /A <</S /GoTo /D (page:\the\scratchcounter)>>>>}%
        % <</Title (#3) /A <</S /GoTo /D [@page\number#4\space\PDFpageviewwrd]>> >>}%
          <</Title \ifPDFunicode<#3>\else(#3)\fi\space /A <</S /GoTo /D [@page\number#4\space\PDFpageviewwrd]>> >>}%
   \fi}

%D \macros
%D   {doPDFdictionaryobject,doPDFarrayobject}

% Dvipdfmx can't handle
%
% \special{pdf:put @foo << /Bar @bar >>}
% \special{pdf:put @bar << /Foo @foo >>}
%
% Objects must be defined before they are used.
%
% \special{pdf:obj @foo << >>}
% \special{pdf:obj @bar << >>}
% \special{pdf:put @foo << /Bar @bar >>}
% \special{pdf:put @bar << /Foo @foo >>}
%
% However, this only works for dictionary and array.

\def\doPDFreserveDPXobject#1#2%
  {\ifundefined{r:pdx:d:#1}%
     % we need a \flushatshipoutprep (prepended, normally appended)
     \flushatshipout{\special{pdf:object @#1 #2}}%
     \global\letvalue{r:pdx:d:#1}\empty
   \fi}

\def\doPDFreserveDPXobjectfirst#1#2%
  {\ifundefined{r:pdx:d:#1}%
     \doglobal\prependtoks\special{pdf:object @#1 #2}\to\everyfirstshipout
     \global\letvalue{r:pdx:d:#1}\empty
   \fi}

\def\doPDFcheckedDPXobject#1{\ifundefined{r:pdx:d:#1}object\else put\fi\space @#1\space}

% new, experimental, can save a run, bugged, too many xforms now
%
% \def\doreservePDFobject#1#2%
%   {\dosetobjectreference{#1}{#2}{@#1::#2}}
%
% \def\doPDFreserveddictionaryobject#1#2#3%
%   {\flushatshipout{\special{pdf:object @#1::#2 << #3 >>}}}
%
% \def\doPDFreservedarrayobject#1#2#3%
%   {\flushatshipout{\special{pdf:object @#1::#2 [ #3 ]}}}
%
% \doreservePDFobject{FDF}{docuextgstates}
% \doreservePDFobject{FDF}{colorspaces}
% \doreservePDFobject{FDF}{docushades}

% so this is to be checked

\def\doPDFdictionaryobject#1#2#3%
  {\flushatshipout
     {\special{pdf:\doPDFcheckedDPXobject{#1::#2}<<#3>>}%
      \dosetobjectreference{#1}{#2}{@#1::#2}}}

\def\doPDFarrayobject#1#2#3%
  {\flushatshipout
     {\special{pdf:\doPDFcheckedDPXobject{#1::#2}[#3]}%
      \dosetobjectreference{#1}{#2}{@#1::#2}}}

%D \macros
%D   {defaultobjectreference,doPDFgetobjectreference}

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

%D \type{\doPDFgetobjectreference} in \type{spec-dpm} had a bug.

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

\def\doPDFgetpagereference#1#2%
  {\edef#2{@page#1}}

%D Done.

% %D 2. Modified codes from \type{spec-fdf}
%
% \definespecial\dostartgraphicgroup{\special{pdf: literal direct q}}
% \definespecial\dostopgraphicgroup {\special{pdf: literal direct Q}}

%D 3. Copied codes from \type{spec-tpd}

%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}%
   \PDFcode
     {q 0 w \MPclippath\space W n}}

\definespecial\dostopclipping
  {\PDFcode{Q n}}

%D 4. Modified codes from \type{supp-pdf}

\def\dosetMPsomePDFshade#1#2%
  {\global\advance\currentPDFshade \plusone
   \special{pdf:object @ftn:Sh:\currentPDFshade\space
       <</FunctionType 2
        /Domain [\gMPs1 \gMPs2]
        /C0 [\MPshadeA]
        /C1 [\MPshadeB]
        /N \gMPs3>>}%
   \special{pdf:object @obj:Sh:\currentPDFshade\space
      <</ShadingType #1
        /ColorSpace /\MPresolvedspace
        /Function @ftn:Sh:\currentPDFshade\space
        /Coords [\MPshadeC]
        /Extend [true true]>>}%
   \appendtoPDFdocumentshades{/Sh\the\currentPDFshade\space @obj:Sh:\currentPDFshade}%
   \setxvalue{\@@MPSK#2}{\noexpand\dohandleMPshade{\the\currentPDFshade}}}

\def\handleMPfigurespecial#1#2#3#4#5#6#7% toto : combine with ext fig
  {\doiffileelse{#7}
     {\vbox to \zeropoint
        {\vss
         \hbox to \zeropoint
           {\special{pdf:btrans matrix #1 #2 #3 #4 #5 #6}%
            \rlap{\special{pdf:image width 1bp height 1bp (#7)}}
      \special{pdf:etrans}\hss}}}
     {\message{[unknown figure #7]}}}

%D 5. Modified codes from \type{supp-pdf}

\let\handleMPfshow\dohandleMPfshow

\newcounter\MPPDFcounter

\newcounter\MPPDFobjectcounter

\def\setMPPDFobject#1#2% resources boxnumber
  {\doglobal\increment\MPPDFobjectcounter
   \xdef\getMPPDFobject
     {\vbox to \the\ht#2%
        {\vss
         \hbox to \the\wd#2%
           {%\scratchdimen\wd#2\scratchdimen.5\scratchdimen\hskip-\the\scratchdimen
            \special{pdf:uxobj @MPPDF::\MPPDFobjectcounter}}}}%
   \expanded{\doDVIPDFMXstartobject\zerocount{MPPDF}\MPPDFobjectcounter{\the\wd#2}{\the\ht#2}{\the\dp#2}}%
   \finalizeobjectbox#2%
   \box#2%
   \doDVIPDFMXstopobject}

\let\getMPPDFobject\gobbletwoarguments

\definespecial\doinsertMPfile#1%
  {\doiffileelse{./#1}{\includeMPasPDF{./#1}}{\message{[MP #1]}}}

%D Experimental (untested):

\definespecial\dostartfonteffect#1#2#3%
  {\ifdim#2>\zeropoint
     \PointsToBigPoints{#2}\ascii
     \PDFdirectcode{\ascii\space w}%
   \fi
   \ifdim#3\points=\onepoint\else
     \scratchdimen#3\points
     \PDFdirectcode{\withoutpt{\the\scratchdimen}\space Tc}%
   \fi
   \PDFdirectcode{\purenumber#1 Tr}}

\definespecial\dostopfonteffect
  {\PDFdirectcode{1 w 0 Tc 0 Tr}}

%D 6. Modified codes from \type{core-obj}
%D
%D In the viewpoint of TeX, the special command \type{pdf:uxobj @obj}
%D generates a box with zero point width and zero point height so that
%D it must be careful to place the box at the reference point.

\def\dogetobject#1#2#3#4#5#6#7% don't change this, should work for dvi & pdf
  {\initializepaper
   \forgetall
   \dontshowcomposition
   \setbox\scratchbox\vbox
     {\doinsertobject{#1}{#2}}%
   \setbox\scratchbox#3%
     {\vbox to #5\scaledpoint
        {\ifdim\ht\scratchbox>#5\scaledpoint
           \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
         \else\ifdim\wd\scratchbox>#4\scaledpoint
           \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
         \else
	   %\vss\box\scratchbox
           \vss\hbox to #4\scaledpoint{\box\scratchbox\hss}%
         \fi\fi}}%
   \box\scratchbox
   \elabelgroup}

\stopspecials

\endinput
