diff options
author | Karl Berry <karl@freefriends.org> | 2018-09-24 20:23:18 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-09-24 20:23:18 +0000 |
commit | a495fe970496337011c0698a03476ce888a26105 (patch) | |
tree | 592b35bc873870f28ec4883e3ba0fdd6a4d68119 /Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx | |
parent | 68966bb4bfd52e8d9d91b9fd5e6ff36d3d74a57e (diff) |
l3 (24sep18)
git-svn-id: svn://tug.org/texlive/trunk@48749 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx | 443 |
1 files changed, 427 insertions, 16 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx index d46578027d6..4a91ce531b4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2018-08-23} +% \date{Released 2018-09-24} % % \maketitle % @@ -458,6 +458,79 @@ % given. % \end{function} % +% \section{PDF Features} +% +% A range of PDF features are exposed by \pdfTeX{} and \LuaTeX{} in direct PDF +% output mode, and the vast majority of these are also controllable using +% the \texttt{(x)dvipdfmx} driver (as DVI instructions are converted directly +% to PDF). Some of these functions are also available for cases where PDFs +% are generated by \texttt{dvips}: this depends on being able to pass +% information through correctly. +% +% \subsection{PDF Objects} +% +% Objects are used to provide a range of data structures in a PDF. At the +% driver level, different PDF object types are declared separately. Objects +% are only \emph{written} to the PDF when referenced. +% +% \begin{function}{\driver_pdf_object_new:nn} +% \begin{syntax} +% \cs{driver_pdf_object_new:n} \Arg{name} \Arg{type} +% \end{syntax} +% Declares \meta{name} as a PDF object. The \texttt{type} should be one of +% |array| or |dict|, |fstream| or |stream|. +% \end{function} +% +% \begin{function}[EXP]{\driver_pdf_object_ref:n} +% \begin{syntax} +% \cs{driver_pdf_object_ref:n} \Arg{object} +% \end{syntax} +% Inserts the appropriate information to reference the \meta{object} +% in for example page resource allocation. +% \end{function} +% +% \begin{function}{\driver_pdf_object_write:nn} +% \begin{syntax} +% \cs{driver_pdf_object_write:nn} \Arg{name} \Arg{data} +% \end{syntax} +% Writes the \meta{data} as content of the \meta{object}. Depending on the +% \meta{type} declared for the object, the format required for the +% \meta{data} will vary +% \begin{itemize} +% \item[\texttt{array}] A space-separated list of values +% \item[\texttt{dict}] Key--value pairs in the form +% \texttt{/\meta{key} \meta{value}} +% \item[\texttt{fstream}] Two brace groups: \meta{content} and +% \meta{file name} +% \item[\texttt{stream}] Two brace groups: \meta{content} and +% \meta{additional attributes} +% \end{itemize} +% \end{function} +% +% \subsection{PDF structure} +% +% \begin{function}{\driver_pdf_compresslevel:n} +% \begin{syntax} +% \cs{driver_pdf_compresslevel:n} \Arg{level} +% \end{syntax} +% Sets the degree of compression used for PDF files: the \meta{level} should +% be in the range $0$ to $9$ (higher is more compression). Typically, either +% compression is disables ($0$) or maximised ($9$). When used with +% \texttt{(x)dvipdfmx}, this setting may only be applied globally: it should +% be set only once. +% \end{function} +% +% \begin{function}{\driver_pdf_objects_enable:, \driver_pdf_objects_disable:} +% \begin{syntax} +% \cs{driver_pdf_objects_disable:} +% \end{syntax} +% Enables or disables the creation of PDF objects. These objects are used to +% reduce the size of PDFs, and typically are enabled as standard. When used +% with \texttt{(x)dvipdfmx}, object creation can be disabled but not +% re-enabled, and this setting may only be applied globally: it should +% be set only once. +% \end{function} +% % \end{documentation} % % \begin{implementation} @@ -481,23 +554,23 @@ %<*package> \ProvidesExplFile %<*dvipdfmx> - {l3dvidpfmx.def}{2018-08-23}{} + {l3dvidpfmx.def}{2018-09-24}{} {L3 Experimental driver: dvipdfmx} %</dvipdfmx> %<*dvips> - {l3dvips.def}{2018-08-23}{} + {l3dvips.def}{2018-09-24}{} {L3 Experimental driver: dvips} %</dvips> %<*dvisvgm> - {l3dvisvgm.def}{2018-08-23}{} + {l3dvisvgm.def}{2018-09-24}{} {L3 Experimental driver: dvisvgm} %</dvisvgm> %<*pdfmode> - {l3pdfmode.def}{2018-08-23}{} + {l3pdfmode.def}{2018-09-24}{} {L3 Experimental driver: PDF mode} %</pdfmode> %<*xdvipdfmx> - {l3xdvidpfmx.def}{2018-08-23}{} + {l3xdvidpfmx.def}{2018-09-24}{} {L3 Experimental driver: xdvipdfmx} %</xdvipdfmx> %</package> @@ -605,7 +678,7 @@ { rgb~ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} } } \cs_new_protected:Npn \driver_color_spot:nn #1#2 - { \@@_color_select:n { \c_space_tl #1 } } + { \@@_color_select:n { #1 } } \cs_new_protected:Npn \@@_color_select:n #1 { \@@_literal:n { color~push~ #1 } @@ -904,7 +977,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Images} +% \subsubsection{Images} % % \begin{macro}{\@@_image_getbb_eps:n} % Simply use the generic function. @@ -922,7 +995,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Drawing} +% \subsubsection{Drawing} % % \begin{macro}{\@@_draw_literal:n, \@@_draw_literal:x} % The same as literal PostScript: same arguments about positioning apply @@ -1322,6 +1395,113 @@ % \end{macrocode} % \end{macro} % +% \subsubsection{PDF Features} +% +% \begin{variable}{\g_@@_pdf_object_int, \g_@@_pdf_object_prop} +% For tracking objects to allow finalisation. +% \begin{macrocode} +\int_new:N \g_@@_pdf_object_int +\prop_new:N \g_@@_pdf_object_prop +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\driver_pdf_object_new:nn} +% \begin{macro}[EXP]{\driver_pdf_object_ref:n} +% Tracking objects is similar to \texttt{dvipdfmx}. +% \begin{macrocode} +\cs_new_protected:Npn \driver_pdf_object_new:nn #1#2 + { + \int_gincr:N \g_@@_pdf_object_int + \int_const:cn + { g_@@_pdf_object_ \tl_to_str:n {#1} _int } + { \g_@@_pdf_object_int } + \prop_gput:Nnn \g_@@_pdf_object_prop {#1} {#2} + } +\cs_new:Npn \driver_pdf_object_ref:n #1 + { { l3obj \int_use:c { g_@@_pdf_object_ \tl_to_str:n {#1} _int } } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\driver_pdf_object_write:nn} +% \begin{macro} +% { +% \@@_pdf_object_write_array:nn , +% \@@_pdf_object_write_dict:nn , +% \@@_pdf_object_write_stream:nn +% } +% \begin{macro}{\@@_pdf_object_write_stream:nnn} +% This is where we choose the actual type: some work to get things +% right. +% \begin{macrocode} +\cs_new_protected:Npn \driver_pdf_object_write:nn #1#2 + { + \@@_literal_postscript:x + { + mark ~ /_objdef ~ \driver_pdf_object_ref:n {#1} ~ + /type + \str_case_e:nn + { \prop_item:Nn \g_@@_pdf_object_prop {#1} } + { + { array } { /array } + { dict } { /dict } + { fstream } { /stream } + { stream } { /stream } + } + /OBJ ~ pdfmark + } + \use:c + { @@_pdf_object_write_ \prop_item:Nn \g_@@_pdf_object_prop {#1} :nn } + {#1} {#2} + } +\cs_new_protected:Npn \@@_pdf_object_write_array:nn #1#2 + { + \@@_literal_postscript:x + { + mark ~ \driver_pdf_object_ref:n {#1} ~ + [ ~ \exp_not:n {#2} ~ ] ~ /PUTINTERVAL ~ pdfmark + } + } +\cs_new_protected:Npn \@@_pdf_object_write_dict:nn #1#2 + { + \@@_literal_postscript:x + { + mark ~ \driver_pdf_object_ref:n {#1} ~ + << ~ \exp_not:n {#2} ~ >> ~ /PUT ~ pdfmark + } + } +\cs_new_protected:Npn \@@_pdf_object_write_stream:nn #1#2 + { + \exp_args:Nx + \@@_pdf_object_write_stream:nnn + { \driver_pdf_object_ref:n {#1} } + #2 + } +\cs_new_protected:Npn \@@_pdf_object_write_stream:nnn #1#2#3 + { + \@@_literal_postscript:n + { + [nobreak] ~ + mark ~ #1 ~ ( #3 ) ~ /PUT ~ pdfmark ~ + mark ~ #1 ~ << #2 >> ~ /PUT ~ pdfmark + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\driver_pdf_compresslevel:n} +% \begin{macro}{\driver_pdf_objects_enable:, \driver_pdf_objects_disable:} +% These are all no-ops. +% \begin{macrocode} +\cs_new_protected:Npn \driver_pdf_compresslevel:n #1 { } +\cs_new_protected:Npn \driver_pdf_objects_enable: { } +\cs_new_protected:Npn \driver_pdf_objects_disable: { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macrocode} %</dvips> % \end{macrocode} @@ -1483,7 +1663,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Images} +% \subsubsection{Images} % % \begin{variable}{\l_@@_image_attr_tl} % In PDF mode, additional attributes of an image (such as page number) are @@ -1594,6 +1774,117 @@ % \end{macrocode} % \end{macro} % +% \subsubsection{PDF Objects} +% +% \begin{variable}{\g_@@_pdf_object_prop} +% For tracking objects to allow finalisation. +% \begin{macrocode} +\prop_new:N \g_@@_pdf_object_prop +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\driver_pdf_object_new:nn} +% \begin{macro}[EXP]{\driver_pdf_object_ref:n} +% Declaring objects means reserving at the PDF level plus starting +% tracking. +% \begin{macrocode} +\group_begin: + \cs_set_protected:Npn \@@_tmp:w #1#2 + { + \cs_new_protected:Npx \driver_pdf_object_new:nn ##1##2 + { + #1 reserveobjnum ~ + \int_const:cn + { g_@@_pdf_object_ \exp_not:N \tl_to_str:n {##1} _int } + {#2} + \prop_gput:Nnn \exp_not:N \g_@@_pdf_object_prop {##1} {##2} + } + } + \cs_if_exist:NTF \tex_pdfextension:D + { + \@@_tmp:w + { \tex_pdfextension:D obj ~ } + { \tex_pdffeedback:D lastobj \scan_stop: } + } + { \@@_tmp:w { \tex_pdfobj:D } { \tex_pdflastobj:D } } +\group_end: +\cs_new:Npn \driver_pdf_object_ref:n #1 + { \int_use:c { g_@@_pdf_object_ \tl_to_str:n {#1} _int } ~ 0 ~ R } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\driver_pdf_object_write:nn} +% \begin{macro}[EXP]{\@@_exp_not_i:nn, \@@_exp_not_ii:nn} +% Writing the data needs a little information about the structure of the +% object. +% \begin{macrocode} +\group_begin: + \cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new_protected:Npn \driver_pdf_object_write:nn ##1##2 + { + \tex_immediate:D #1 useobjnum ~ + \int_use:c + { g_@@_pdf_object_ \tl_to_str:n {##1} _int } + \str_case_e:nn + { \prop_item:Nn \g_@@_pdf_object_prop {##1} } + { + { array } { { [ ~ \exp_not:n {##2} ~ ] } } + { dict } { { << ~ \exp_not:n {##2} ~ >> } } + { fstream } + { + stream ~ attr ~ { \@@_exp_not_i:nn ##2 } ~ + file ~ { \@@_exp_not_ii:nn ##2 } + } + { stream } + { + stream ~ attr ~ { \@@_exp_not_i:nn ##2 } ~ + { \@@_exp_not_ii:nn ##2 } + } + } + } + } + \cs_if_exist:NTF \tex_pdfextension:D + { \@@_tmp:w { \tex_pdfextension:D obj ~ } } + { \@@_tmp:w { \tex_pdfobj:D } } +\group_end: +\cs_new:Npn \@@_exp_not_i:nn #1#2 { \exp_not:n {#1} } +\cs_new:Npn \@@_exp_not_ii:nn #1#2 { \exp_not:n {#2} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{PDF Structure} +% +% \begin{macro}{\driver_pdf_compresslevel:n} +% \begin{macro}{\driver_pdf_objects_enable:, \driver_pdf_objects_disable:} +% \begin{macro}{\@@_pdf_objectlevel:n} +% Simply pass data to the engine. +% \begin{macrocode} +\cs_new_protected:Npx \driver_pdf_compresslevel:n #1 + { + \cs_if_exist:NTF \tex_pdfcompresslevel:D + { \tex_pdfcompresslevel:D } + { \tex_pdfvariable:D compresslevel } + \exp_not:N \int_value:w \exp_not:N \int_eval:n {#1} \scan_stop: + } +\cs_new_protected:Npn \driver_pdf_objects_enable: + { \@@_pdf_objectlevel:n { 2 } } +\cs_new_protected:Npn \driver_pdf_objects_disable: + { \@@_pdf_objectlevel:n { 0 } } +\cs_new_protected:Npx \@@_pdf_objectlevel:n #1 + { + \cs_if_exist:NTF \tex_pdfobjcompresslevel:D + { \tex_pdfobjcompresslevel:D } + { \tex_pdfvariable:D objcompresslevel } + #1 \scan_stop: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macrocode} %</pdfmode> % \end{macrocode} @@ -1704,7 +1995,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Images} +% \subsubsection{Images} % % \begin{macro} % { @@ -1840,6 +2131,104 @@ % \end{macro} % \end{macro} % +% \subsubsection{PDF Objects} +% +% \begin{variable}{\g_@@_pdf_object_int, \g_@@_pdf_object_prop} +% For tracking objects to allow finalisation. +% \begin{macrocode} +\int_new:N \g_@@_pdf_object_int +\prop_new:N \g_@@_pdf_object_prop +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\driver_pdf_object_new:nn} +% \begin{macro}[EXP]{\driver_pdf_object_ref:n} +% Objects are tracked at the macro level, but we don't have to do anything +% at this stage. +% \begin{macrocode} +\cs_new_protected:Npn \driver_pdf_object_new:nn #1#2 + { + \int_gincr:N \g_@@_pdf_object_int + \int_const:cn + { g_@@_pdf_object_ \tl_to_str:n {#1} _int } + { \g_@@_pdf_object_int } + \prop_gput:Nnn \g_@@_pdf_object_prop {#1} {#2} + } +\cs_new:Npn \driver_pdf_object_ref:n #1 + { @l3obj \int_use:c { g_@@_pdf_object_ \tl_to_str:n {#1} _int } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\driver_pdf_object_write:nn} +% \begin{macro}{\@@_pdf_object_write:nnn} +% \begin{macro} +% { +% \@@_pdf_object_write_array:nn , +% \@@_pdf_object_write_dict:nn , +% \@@_pdf_object_write_fstream:nn , +% \@@_pdf_object_write_stream:nn +% } +% \begin{macro}{\@@_pdf_object_write_stream:nnnn} +% This is where we choose the actual type. +% \begin{macrocode} +\cs_new_protected:Npn \driver_pdf_object_write:nn #1#2 + { + \exp_args:Nx \@@_pdf_object_write:nnn + { \prop_item:Nn \g_@@_pdf_object_prop {#1} } {#1} {#2} + } +\cs_new_protected:Npn \@@_pdf_object_write:nnn #1#2#3 + { \use:c { @@_pdf_object_write_ #1 :nn } {#2} {#3} } +\cs_new_protected:Npn \@@_pdf_object_write_array:nn #1#2 + { + \@@_literal:x + { + pdf:obj ~ \driver_pdf_object_ref:n {#1} ~ + [ ~ \exp_not:n {#2} ~ ] + } + } +\cs_new_protected:Npn \@@_pdf_object_write_dict:nn #1#2 + { + \@@_literal:x + { + pdf:obj ~ \driver_pdf_object_ref:n {#1} ~ + << ~ \exp_not:n {#2} ~ >> + } + } +\cs_new_protected:Npn \@@_pdf_object_write_fstream:nn #1#2 + { \@@_pdf_object_write_stream:nnnn { f } {#1} #2 } +\cs_new_protected:Npn \@@_pdf_object_write_stream:nn #1#2 + { \@@_pdf_object_write_stream:nnnn { } {#1} #2 } +\cs_new_protected:Npn \@@_pdf_object_write_stream:nnnn #1#2#3#4 + { + \@@_literal:x + { + pdf: #1 stream ~ \driver_pdf_object_ref:n {#2} ~ + ( \exp_not:n {#4} ) ~ << \exp_not:n {#3} >> + + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{PDF Structure} +% +% \begin{macro}{\driver_pdf_compresslevel:n} +% \begin{macro}{\driver_pdf_objects_enable:, \driver_pdf_objects_disable:} +% Pass data to the driver: these are a one-shot. +% \begin{macrocode} +\cs_new_protected:Npn \driver_pdf_compresslevel:n #1 + { \@@_literal:x { dvipdfmx:config~z~ \int_eval:n {#1} } } +\cs_new_protected:Npn \driver_pdf_objects_enable: { } +\cs_new_protected:Npn \driver_pdf_objects_disable: + { \@@_literal:n { dvipdfmx:config~C~0x40 } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macrocode} %</dvipdfmx|xdvipdfmx> % \end{macrocode} @@ -1850,7 +2239,7 @@ %<*xdvipdfmx> % \end{macrocode} % -% \subsection{Images} +% \subsubsection{Images} % % \begin{macro} % {\@@_image_getbb_jpg:n, \@@_image_getbb_pdf:n, \@@_image_getbb_png:n} @@ -1955,7 +2344,7 @@ %<*dvipdfmx|pdfmode|xdvipdfmx> % \end{macrocode} % -% \subsection{Drawing} +% \subsubsection{Drawing} % % \begin{macro}{\@@_draw_literal:n, \@@_draw_literal:x} % Pass data through using a dedicated interface. @@ -2416,7 +2805,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Driver-specific auxiliaries} +% \subsubsection{Driver-specific auxiliaries} % % \begin{macro}{\@@_scope_begin:n, \@@_scope_begin:x} % In SVG transformations, clips and so on are attached directly to scopes so @@ -2556,7 +2945,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Images} +% \subsubsection{Images} % % \begin{macro}{\@@_image_getbb_png:n, \@@_image_getbb_jpg:n} % These can be included by extracting the bounding box data. @@ -2592,7 +2981,29 @@ % \end{macro} % \end{macro} % -% \subsection{Drawing} +% \subsubsection{PDF Features} +% +% \begin{macro}{\driver_pdf_object_new:n} +% \begin{macro}[EXP]{\driver_pdf_object_ref:n} +% \begin{macro}{\driver_pdf_ojbect_write:nn} +% \begin{macro}{\driver_pdf_compresslevel:n} +% \begin{macro}{\driver_pdf_objects_enable:, \driver_pdf_objects_disable:} +% These are all no-ops. +% \begin{macrocode} +\cs_new_protected:Npn \driver_pdf_object_new:n #1 { } +\cs_new:Npn \driver_pdf_object_ref:n #1 { } +\cs_new_protected:Npn \driver_pdf_object_write:nn #1#2 { } +\cs_new_protected:Npn \driver_pdf_compresslevel:n #1 { } +\cs_new_protected:Npn \driver_pdf_objects_enable: { } +\cs_new_protected:Npn \driver_pdf_objects_disable: { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Drawing} % % \begin{macro}{\@@_draw_literal:n, \@@_draw_literal:x} % The same as the more general literal call. |