%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