%D \module
%D   [       file=back-pdf,
%D        version=2009.04.15,
%D          title=\CONTEXT\ Backend Macros,
%D       subtitle=\PDF,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt Backend Macros / PDF}

%registerctxluafile{lpdf-aux}{1.001} % common helpers
\registerctxluafile{lpdf-ini}{1.001}
\registerctxluafile{lpdf-nod}{1.001}
\registerctxluafile{lpdf-col}{1.000}
\registerctxluafile{lpdf-xmp}{1.001}
\registerctxluafile{lpdf-ano}{1.001}
\registerctxluafile{lpdf-mis}{1.001}
\registerctxluafile{lpdf-ren}{1.001}
\registerctxluafile{lpdf-grp}{1.001}
\registerctxluafile{lpdf-wid}{1.001}
\registerctxluafile{lpdf-fld}{1.001}
\registerctxluafile{lpdf-mov}{1.001}
\registerctxluafile{lpdf-u3d}{1.001}
\registerctxluafile{lpdf-swf}{1.001}
\registerctxluafile{lpdf-tag}{1.001}
\registerctxluafile{lpdf-fmt}{1.001}
\registerctxluafile{lpdf-epd}{1.001}
\registerctxluafile{lpdf-epa}{1.001}

\registerctxluafile{back-pdf}{1.001} % some code will move to lpdf-*

\unprotect

%D We will minimize the number of calls to \PDF\ specific primitives
%D and delegate all management and injection of code to the backend.
%D
%D Here we initialize some internal quantities. We also protect them.

\pdfoutput  \plusone    \let\pdfoutput \undefined \newcount\pdfoutput  \pdfoutput  \plusone

%D These are already set:

\pdfhorigin 1 true in   \let\pdfhorigin\undefined \newdimen\pdfhorigin \pdfhorigin 1 true in
\pdfvorigin \pdfhorigin \let\pdfvorigin\undefined \newdimen\pdfvorigin \pdfvorigin \pdfhorigin

%D These too and most of them will be protected as well:

\pdfminorversion        \plusseven
\pdfgentounicode        \plusone    \let\pdfgentounicode       \undefined \newcount\pdfgentounicode
\pdfinclusioncopyfonts  \plusone    \let\pdfinclusioncopyfonts \undefined \newcount\pdfinclusioncopyfonts
\pdfinclusionerrorlevel \zerocount  \let\pdfinclusionerrorlevel\undefined \newcount\pdfinclusionerrorlevel
\pdfdecimaldigits       \plusten    \let\pdfdecimaldigits      \undefined \newcount\pdfdecimaldigits
\pdfimageresolution     300
\pdfpkresolution        600

%D Let's block these (we could share a dummy:

\let\pdfcatalog      \relax  \newtoks\pdfcatalog
\let\pdfinfo         \relax  \newtoks\pdfinfo
\let\pdfnames        \relax  \newtoks\pdfnames
\let\pdfpageresources\relax  \newtoks\pdfpageresources
\let\pdfpageattr     \relax  \newtoks\pdfpageattr
\let\pdfpagesattr    \relax  \newtoks\pdfpagesattr

%D This one can be consulted by users although the suffix is also
%D a system mode.

\back_job_set_suffix{pdf}

%D PDF/X (maybe combine the two lua calls)

\setupbackend
  [xmpfile=]

\appendtoks
    \doifsomething{\backendparameter{xmpfile}}
      {\clf_setxmpfile{\backendparameter{xmpfile}}}%
\to \everysetupbackend

% \doifsomething{\backendparameter\c!format} .. at the lua end

\appendtoks
    \clf_setformat
         format  {\backendparameter\c!format}%
         level   {\backendparameter\c!level}%
         option  {\backendparameter\c!option}%
         profile {\backendparameter\c!profile}%
         intent  {\backendparameter\c!intent}%
         file    {\backendparameter\c!file}%
    \relax
\to \everysetupbackend

%D For the moment we keep these.

\newtoks \pdfbackendeveryximage
\newtoks \pdfbackendeveryxform

%D These are the only official methods to add stuff to the resources.

\unexpanded\def\pdfbackendsetcatalog       #1#2{\clf_lpdf_addtocatalog        {#1}{#2}}
\unexpanded\def\pdfbackendsetinfo          #1#2{\clf_lpdf_addtoinfo           {#1}{#2}}
\unexpanded\def\pdfbackendsetname          #1#2{\clf_lpdf_addtonames          {#1}{#2}}

\unexpanded\def\pdfbackendsetpageattribute #1#2{\clf_lpdf_addtopageattributes  {#1}{#2}}
\unexpanded\def\pdfbackendsetpagesattribute#1#2{\clf_lpdf_addtopagesattributes {#1}{#2}}
\unexpanded\def\pdfbackendsetpageresource  #1#2{\clf_lpdf_addtopageresources   {#1}{#2}}

\unexpanded\def\pdfbackendsetextgstate     #1#2{\clf_lpdf_adddocumentextgstate {#1}{#2}}
\unexpanded\def\pdfbackendsetcolorspace    #1#2{\clf_lpdf_adddocumentcolorspace{#1}{#2}}
\unexpanded\def\pdfbackendsetpattern       #1#2{\clf_lpdf_adddocumentpattern   {#1}{#2}}
\unexpanded\def\pdfbackendsetshade         #1#2{\clf_lpdf_adddocumentshade     {#1}{#2}}

           \def\pdfbackendcurrentresources     {\clf_lpdf_collectedresources}
           \def\pdfcolor                     #1{\clf_lpdf_color\numexpr\thecolorattribute{#1}\relax}
           \let\PDFcolor\pdfcolor

%D An example of usage is:

\appendtoks % this will be moved to lua
    \pdfbackendsetinfo{ConTeXt.Version}{\contextversion}%
    \pdfbackendsetinfo{ConTeXt.Time}   {\number\normalyear.\twodigits\normalmonth.\twodigits\normalday\space \twodigits\currenthour:\twodigits\currentminute}%
    \pdfbackendsetinfo{ConTeXt.Jobname}{\jobname}%
    \pdfbackendsetinfo{ConTeXt.Url}    {www.pragma-ade.com}%
    \pdfbackendsetinfo{ConTeXt.Support}{contextgarden.net}%
\to \everylastbackendshipout

%D Transformations. Some day we will use primitives (once they're fixed).

% todo: inject at the lua end cq. deal with #5 and #6 too

% % % rotation % % %

% \unexpanded\def\dostartrotation#1% grouped
%   {\forcecolorhack
%    \pdfsave
%    \pdfsetmatrix{\clf_pdfrotation#1}}

% \unexpanded\def\dostoprotation
%   {\pdfrestore
%    \forcecolorhack}

\unexpanded\def\dostartrotation#1%
  {\forcecolorhack
   \clf_pdfstartrotation#1\relax}

\unexpanded\def\dostoprotation
  {\clf_pdfstoprotation}

% % % scaling % % %

% \unexpanded\def\dostartscaling#1#2% the test is needed because acrobat is bugged!
%   {\forcecolorhack % maybe use signal instead
%    \pdfsave
%    \pdfsetmatrix
%      {\ifdim#1\points=\zeropoint.0001\else#1\fi\space 0 0
%       \ifdim#2\points=\zeropoint.0001\else#2\fi\space}}% 0 0

% \unexpanded\def\dostopscaling
%   {\pdfrestore
%    \forcecolorhack}

\unexpanded\def\dostartscaling#1#2%
  {\forcecolorhack
   \clf_pdfstartscaling sx #1 sy #2\relax}

\unexpanded\def\dostopscaling
  {\clf_pdfstopscaling}

% % % mirroring % % %

% \unexpanded\def\dostartmirroring
%   {\forcecolorhack
%    \pdfsave
%    \pdfsetmatrix{-1 0 0 1}} % 0 0

% \unexpanded\def\dostopmirroring
%   {\pdfrestore
%    \forcecolorhack}

\unexpanded\def\dostartmirroring
  {\clf_pdfstartmirroring}

\unexpanded\def\dostopmirroring
  {\clf_pdfstopmirroring}

% % % transform % % %

% \unexpanded\def\dotransformnextbox#1#2#3#4#5#6% sx rx ry sy tx ty (will change) / basepoints !
%   {\dowithnextbox{\dodotransformnextbox{#5}{#6}{#1 #2 #3 #4}}}

% \unexpanded\def\dodotransformnextbox#1#2#3%
%   {\hbox
%      {\kern#1\onebasepoint
%       \raise#2\onebasepoint\hbox
%         {\pdfsave
%          \pdfsetmatrix{#3}% 0 0 (no #5 #6 yet)
%          \box\nextbox
%          \pdfrestore
%          }}}

% \unexpanded\def\dotransformnextbox#1#2#3#4#5#6% sx rx ry sy tx ty (will change) / basepoints !
%   {% fixing ht/dp/wd should happen elsewhere
%    \dowithnextbox{\dodotransformnextbox{#1}{#2}{#3}{#4}{#5}{#6}}}

% \unexpanded\def\dodotransformnextbox#1#2#3#4#5#6%
%   {\hbox
%      {\kern #5\onebasepoint
%       \raise#6\onebasepoint
%       \hbox
%         {\clf_pdfstartmatrix sx #1 rx #2 ry #3 sy #4\relax
%          \box\nextbox
%          \clf_pdfstopmatrix}}}

\unexpanded\def\dotransformnextbox#1#2#3#4#5#6% sx rx ry sy tx ty (will change) / basepoints !
  {\dowithnextbox{\dodotransformnextbox{#1}{#2}{#3}{#4}{#5}{#6}}}

\unexpanded\def\dodotransformnextbox#1#2#3#4#5#6%
  {\hbox
     {\kern #5\onebasepoint
      \raise#6\onebasepoint
      \hbox
        {\clf_pdfstartmatrix sx #1 rx #2 ry #3 sy #4\relax
         \box\nextbox
         \clf_pdfstopmatrix}}}

% somehow the shift is not happening .. bug in luatex?
%
% \unexpanded\def\dodotransformnextbox#1#2#3#4#5#6%
%   {\ctxcommand{pdftransformbox(\number\nextbox,#1,#2,#3,#4,\number\dimexpr#5\onebasepoint,\number\dimexpr#6\onebasepoint)}%
%    \box\nextbox}
%
% \startluacode
%     function commands.pdftransformbox(box,sx,rx,ry,sy,tx,ty)
%         if sx == 1 and rx == 0 and ry == 0 and sy == 1 then
%             if tx == 0 and ty == 0 then
%                 local b = nodes.hpack(nodes.concat {
%                     nodes.pool.kern(tx),
%                     nodes.takebox(box),
%                 })
%                 b.shift = -ty
%                 tex.setbox(box,b)
%             else
%                 -- no need to transform
%             end
%         else
%             local b = nodes.hpack(nodes.concat {
%                 nodes.pool.kern(tx),
%                 nodes.pool.pdfsave(),
%                 nodes.pool.pdfsetmatrix(sx,rx,ry,sy),
%                 nodes.takebox(box),
%                 nodes.pool.pdfsetmatrix(-sx,-rx,-ry,-sy),
%                 nodes.pool.pdfrestore(),
%             })
%             b.shift = -ty
%             tex.setbox(box,b)
%         end
%     end
% \stopluacode

% % % clipping % % %

\unexpanded\def\dostartclipping#1#2#3% we can move this to lua and only set a box here
  {\PointsToBigPoints{#2}\width
   \PointsToBigPoints{#3}\height
   \meta_grab_clip_path{#1}\width\height{%
     0            0             m %
     \width\space 0             l %
     \width\space \height\space l %
     0            \height\space l%
   }%
   \pdfliteral{q 0 w \MPclippath\space W n}}

\unexpanded\def\dostopclipping
  {\pdfliteral{Q}}

%D The following will move to the backend \LUA\ code:

%appendtoks \ctxlua{backends.codeinjections.finalizepage    ()}\to \everybackendshipout       % is immediate
%appendtoks \ctxlua{backends.codeinjections.finalizedocument()}\to \everylastbackendshipout   % is immediate

%D Temporary hack, will be removed or improved or default.

%def\TransparencyHack{\ctxlua{backends.codeinjections.addtransparencygroup()}}
\def\TransparencyHack{\setupcolors[\c!pagecolormodel=\v!auto]}

%D \macros
%D  {dostartobject,dostopobject,doinsertobject}

%D This will change:

\newbox\objectbox

\unexpanded\def\dostartobject#1#2#3#4#5% needs to be \unexpanded
  {\bgroup
   \setbox\objectbox\vbox\bgroup
   \def\back_object_stop{\egroup\back_object_register{#1}{#2}}}

\unexpanded\def\dostopobject % needs to be \unexpanded
  {\back_object_stop
   \egroup}

\let\back_object_stop\relax

% attr {/Group << /S /Transparency /I false /K true >>}

\def\back_object_register#1#2%
  {\the\pdfbackendeveryxform
   \finalizeobjectbox\objectbox
   \immediate\pdfxform resources {\pdfbackendcurrentresources}\objectbox
   \dosetobjectreference{#1}{#2}\pdflastxform}

\let\m_back_object_reference\empty

\unexpanded\def\doinsertobject#1#2%
  {\begingroup
   \doifelseobjectreferencefound{#1}{#2}
     {\dogetobjectreference{#1}{#2}\m_back_object_reference
      \pdfrefxform\m_back_object_reference}%
     \donothing
   \endgroup}

\let\lastpredefinedsymbol\empty % some day we can do more at the lua end

\unexpanded\def\predefinesymbol[#1]%
  {\begingroup
   \xdef\lastpredefinedsymbol{#1}%
   \settightobject{SYM}{#1}\hbox{\symbol[#1]}% to be checked ... maybe only fitting
   \dogetobjectreference{SYM}{#1}\m_back_object_reference
   \clf_registerbackendsymbol{#1}\m_back_object_reference\relax
   \endgroup}

% for the moment here

%D \macros
%D  {back_ovalbox}
%D
%D Drawing frames with round corners is inherited from the
%D main module.
%D
%D For drawing ovals we use quite raw \PDF\ code. The next
%D implementation does not differ that much from the one
%D implemented in the \POSTSCRIPT\ driver. This code is
%D somewhat obsolete as we now have metapost embedded.

% \def\back_oval_calculate#1#2#3%
%   {\PointsToBigPoints{\dimexpr#2+#3\relax}#1}

\unexpanded\def\back_ovalbox#1#2#3#4#5#6#7#8%
  {\forcecolorhack
   \bgroup
%    \scratchdimen#4%
%    \divide\scratchdimen\plustwo
%    \back_oval_calculate\xmin  \zeropoint\scratchdimen
%    \back_oval_calculate\xmax  {#1}{-\scratchdimen}%
%    \back_oval_calculate\ymax  {#2}{-\scratchdimen}%
%    \back_oval_calculate\ymin  {-#3}\scratchdimen
%    \advance\scratchdimen by #5%
%    \back_oval_calculate\xxmin \zeropoint\scratchdimen
%    \back_oval_calculate\xxmax {#1}{-\scratchdimen}%
%    \back_oval_calculate\yymax {#2}{-\scratchdimen}%
%    \back_oval_calculate\yymin {-#3}\scratchdimen
%    \back_oval_calculate\stroke{#4}\zeropoint
%    \back_oval_calculate\radius{#5}\zeropoint
   %
   \PointsToBigPoints{#4}                       \stroke
   \PointsToBigPoints{#5}                       \radius
   \scratchdimen\dimexpr#4/\plustwo\relax
   \PointsToBigPoints             \scratchdimen \xmin
   \PointsToBigPoints{\dimexpr #1-\scratchdimen}\xmax
   \PointsToBigPoints{\dimexpr #2-\scratchdimen}\ymax
   \PointsToBigPoints{\dimexpr-#3+\scratchdimen}\ymin
   \advance\scratchdimen by #5\relax
   \PointsToBigPoints             \scratchdimen \xxmin
   \PointsToBigPoints{\dimexpr #1-\scratchdimen}\xxmax
   \PointsToBigPoints{\dimexpr #2-\scratchdimen}\yymax
   \PointsToBigPoints{\dimexpr-#3+\scratchdimen}\yymin
   %
   \edef\dostroke{\number#6}%
   \edef\dofill{\number#7}%
   \edef\mode{\number#8}%
   % no \ifcase, else \relax in pdfcode
   \setbox\scratchbox\hbox
     {\ifnum\dostroke\dofill>\zerocount
        \pdfliteral
          {q
           \stroke\space               w
           \ifcase\mode\space
             \xxmin\space \ymin \space m
             \xxmax\space \ymin \space l
             \xmax \space \ymin \space \xmax \space \yymin\space y
             \xmax \space \yymax\space l
             \xmax \space \ymax \space \xxmax\space \ymax \space y
             \xxmin\space \ymax \space l
             \xmin \space \ymax \space \xmin \space \yymax\space y
             \xmin \space \yymin\space l
             \xmin \space \ymin \space \xxmin\space \ymin \space y
             h
           \or % 1
             \xxmin\space \ymin \space m
             \xxmax\space \ymin \space l
             \xmax \space \ymin \space \xmax \space \yymin\space y
             \xmax \space \ymax \space l
             \xmin \space \ymax \space l
             \xmin \space \yymin\space l
             \xmin \space \ymin \space \xxmin\space \ymin \space y
             h
           \or % 2
             \xxmin\space \ymin \space m
             \xmax \space \ymin \space l
             \xmax \space \ymax \space l
             \xxmin\space \ymax \space l
             \xmin \space \ymax \space \xmin \space \yymax\space y
             \xmin \space \yymin\space l
             \xmin \space \ymin \space \xxmin\space \ymin \space y
             h
           \or % 3
             \xmin \space \ymin \space m
             \xmax \space \ymin \space l
             \xmax \space \yymax\space l
             \xmax \space \ymax \space \xxmax\space \ymax \space y
             \xxmin\space \ymax \space l
             \xmin \space \ymax \space \xmin \space \yymax\space y
             \xmin \space \ymin \space l
             h
           \or % 4
             \xmin \space \ymin \space m
             \xxmax\space \ymin \space l
             \xmax \space \ymin \space \xmax \space \yymin\space y
             \xmax \space \yymax\space l
             \xmax \space \ymax \space \xxmax\space \ymax \space y
             \xmin \space \ymax \space l
             \xmin \space \ymin\space l
             h
           \or % 5
             \xmin \space \ymin \space m
             \xmax \space \ymin \space l
             \xmax \space \yymax\space l
             \xmax \space \ymax \space \xxmax\space \ymax \space y
             \xmin \space \ymax \space l
             \xmin \space \ymin \space l
             h
           \or % 6
             \xmin \space \ymin \space m
             \xxmax\space \ymin \space l
             \xmax \space \ymin \space \xmax \space \yymin\space y
             \xmax \space \ymax \space l
             \xmin \space \ymax \space l
             \xmin \space \ymin \space l
             h
           \or
             \xxmin\space \ymin \space m
             \xmax \space \ymin \space l
             \xmax \space \ymax \space l
             \xmin \space \ymax \space l
             \xmin \space \yymin\space l
             \xmin \space \ymin \space \xxmin\space \ymin \space y
             h
           \or
             \xmin \space \ymin \space m
             \xmax \space \ymin \space l
             \xmax \space \ymax \space l
             \xxmin\space \ymax \space l
             \xmin \space \ymax \space \xmin \space \yymax\space y
             \xmin \space \ymin \space l
             h
           \or % 9 top open
             \xmin \space \ymax \space m
             \xmin \space \yymin\space l
             \xmin \space \ymin \space \xxmin\space \ymin \space y
             \xxmax\space \ymin \space l
             \xmax \space \ymin \space \xmax \space \yymin\space y
             \xmax \space \ymax \space l
           \or % 10 right open
             \xmax \space \ymax \space m
             \xxmin\space \ymax \space l
             \xmin \space \ymax \space \xmin \space \yymax\space y
             \xmin \space \yymin\space l
             \xmin \space \ymin \space \xxmin\space \ymin \space y
             \xmax\space  \ymin \space l
           \or % 11 bottom open
             \xmax \space \ymin \space m
             \xmax \space \yymax\space l
             \xmax \space \ymax \space \xxmax \space \ymax\space y
             \xxmin\space \ymax \space l
             \xmin \space \ymax \space \xmin \space \yymax\space y
             \xmin \space \ymin \space l
           \or % 12 left open
             \xmin \space \ymax \space m
             \xxmax\space \ymax \space l
             \xmax \space \ymax \space \xmax \space \yymax\space y
             \xmax \space \yymin\space l
             \xmax \space \ymin \space \xxmax\space \ymin \space y
             \xmin \space \ymin \space l
           \or % 13
             \xmin \space \ymax \space m
             \xxmax\space \ymax \space l
             \xmax \space \ymax \space \xmax \space \yymax\space y
             \xmax\space  \ymin \space l
           \or % 14
             \xmax \space \ymax \space m
             \xmax \space \yymin\space l
             \xmax \space \ymin \space \xxmax\space \ymin \space y
             \xmin \space \ymin \space l
           \or % 15
             \xmax \space \ymin \space m
             \xxmin\space \ymin \space l
             \xmin \space \ymin \space \xmin \space \yymin\space y
             \xmin \space \ymax \space l
           \or % 16
             \xmin \space \ymin \space m
             \xmin \space \yymax\space l
             \xmin \space \ymax \space \xxmin\space \ymax \space y
             \xmax \space \ymax \space l
           \or % 17
             \xxmax\space \ymax \space m
             \xmax \space \ymax \space \xmax \space \yymax\space y
           \or % 18
             \xmax \space \yymin\space m
             \xmax \space \ymin \space \xxmax\space \ymin \space y
           \or % 19
             \xxmin\space \ymin \space m
             \xmin \space \ymin \space \xmin \space \yymin\space y
           \or % 20
             \xmin \space \yymax\space m
             \xmin \space \ymax \space \xxmin\space \ymax \space y
           \or % 21
             \xxmax\space \ymax \space m
             \xmax \space \ymax \space \xmax \space \yymax\space y
             \xmin \space \yymax\space m
             \xmin \space \ymax \space \xxmin\space \ymax \space y
           \or % 22
             \xxmax\space \ymax \space m
             \xmax \space \ymax \space \xmax \space \yymax\space y
             \xmax \space \yymin\space m
             \xmax \space \ymin \space \xxmax\space \ymin \space y
           \or % 23
             \xmax \space \yymin\space m
             \xmax \space \ymin \space \xxmax\space \ymin \space y
             \xxmin\space \ymin \space m
             \xmin \space \ymin \space \xmin \space \yymin\space y
           \or % 24
             \xxmin\space \ymin \space m
             \xmin \space \ymin \space \xmin \space \yymin\space y
             \xmin \space \yymax\space m
             \xmin \space \ymax \space \xxmin\space \ymax \space y
           \or % 25
             \xxmax\space \ymax \space m
             \xmax \space \ymax \space \xmax \space \yymax\space y
             \xmax \space \yymin\space m
             \xmax \space \ymin \space \xxmax\space \ymin \space y
             \xxmin\space \ymin \space m
             \xmin \space \ymin \space \xmin \space \yymin\space y
             \xmin \space \yymax\space m
             \xmin \space \ymax \space \xxmin\space \ymax \space y
           \or % 26
             \xmax \space \yymin\space m
             \xmax \space \ymin \space \xxmax\space \ymin \space y
             \xmin \space \yymax\space m
             \xmin \space \ymax \space \xxmin\space \ymax \space y
           \or % 27
             \xxmax\space \ymax \space m
             \xmax \space \ymax \space \xmax \space \yymax\space y
             \xxmin\space \ymin \space m
             \xmin \space \ymin \space \xmin \space \yymin\space y
           \or % 28
           \fi
           \ifnum\mode>\pluseight\space
                                       S
           \else
             \ifnum\dostroke=\plusone  S \fi
             \ifnum\dofill  =\plusone  f \fi
           \fi
           Q}%
      \fi}%
   \wd\scratchbox#1%
   \ht\scratchbox#2%
   \dp\scratchbox#3%
   \box\scratchbox
   \egroup}

\unexpanded\def\pdfbackendactualtext#1#2% not interfaced
  {\clf_startactualtext{#2}%
   #1%
   \clf_stopactualtext}

\let\pdfactualtext\pdfbackendactualtext

% \starttext
%     text \pdfbackendactualtext{Meier}{Müller} text
% \stoptext

\protect \endinput
