diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx | 267 |
1 files changed, 163 insertions, 104 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx index 94f7d3ccd03..9584a9aa624 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx @@ -45,7 +45,7 @@ % }^^A % } % -% \date{Released 2017/04/01} +% \date{Released 2017/05/13} % % \maketitle % @@ -64,8 +64,8 @@ % \item \texttt{dvipdfmx}: The \texttt{dvipdfmx} program, which works in % conjugation with \pdfTeX{} or \LuaTeX{} in DVI mode. % \item \texttt{dvisvgm}: The \texttt{dvisvgm} program, which works in -% conjugation with \pdfTeX{} or \LuaTeX{} in DVI mode to create SVG -% output. +% conjugation with \pdfTeX{} or \LuaTeX{} when run in DVI mode as well +% as with (u)p\TeX{} and \XeTeX{}. % \item \texttt{xdvipdfmx}: The driver used by \XeTeX{}. % \end{itemize} % @@ -551,6 +551,93 @@ % \end{macrocode} % \end{macro} % +% \subsubsection{Box operations} +% +% \begin{macro}{\@@_box_use_clip:N} +% The general method is to save the current location, define a clipping path +% equivalent to the bounding box, then insert the content at the current +% position and in a zero width box. The \enquote{real} width is then made up +% using a horizontal skip before tidying up. There are other approaches that +% can be taken (for example using XForm objects), but the logic here shares +% as much code as possible and uses the same conversions (and so same +% rounding errors) in all cases. +% \begin{macrocode} +\cs_new_protected:Npn \@@_box_use_clip:N #1 + { + \@@_scope_begin: + \@@_literal:n + { + 0~ + \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~ + \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~ + \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~ + re~W~n + } + \hbox_overlap_right:n { \box_use:N #1 } + \@@_scope_end: + \skip_horizontal:n { \box_wd:N #1 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_box_use_rotate:Nn} +% \begin{variable}{\l_@@_cos_fp, \l_@@_sin_fp} +% Rotations are set using an affine transformation matrix which therefore +% requires sine/cosine values not the angle itself. We store the rounded +% values to avoid rounding twice. There are also a couple of comparisons to +% ensure that |-0| is not written to the output, as this avoids any issues +% with problematic display programs. Note that numbers are compared to~$0$ +% after rounding. +% \begin{macrocode} +\cs_new_protected:Npn \@@_box_use_rotate:Nn #1#2 + { + \@@_scope_begin: + \box_set_wd:Nn #1 \c_zero_dim + \fp_set:Nn \l_@@_cos_fp { round ( cosd ( #2 ) , 5 ) } + \fp_compare:nNnT \l_@@_cos_fp = \c_zero_fp + { \fp_zero:N \l_@@_cos_fp } + \fp_set:Nn \l_@@_sin_fp { round ( sind ( #2 ) , 5 ) } + \@@_matrix:n + { + \fp_use:N \l_@@_cos_fp \c_space_tl + \fp_compare:nNnTF \l_@@_sin_fp = \c_zero_fp + { 0~0 } + { + \fp_use:N \l_@@_sin_fp + \c_space_tl + \fp_eval:n { -\l_@@_sin_fp } + } + \c_space_tl + \fp_use:N \l_@@_cos_fp + } + \box_use:N #1 + \@@_scope_end: + } +\fp_new:N \l_@@_cos_fp +\fp_new:N \l_@@_sin_fp +% \end{macrocode} +% \end{variable} +% \end{macro} +% +% \begin{macro}{\@@_box_use_scale:Nnn} +% The same idea as for rotation but without the complexity of signs and +% cosines. +% \begin{macrocode} +\cs_new_protected:Npn \@@_box_use_scale:Nnn #1#2#3 + { + \@@_scope_begin: + \@@_matrix:n + { + \fp_eval:n { round ( #2 , 5 ) } ~ + 0~0~ + \fp_eval:n { round ( #3 , 5 ) } + } + \hbox_overlap_right:n { \box_use:N #1 } + \@@_scope_end: + } +% \end{macrocode} +% \end{macro} +% % \subsubsection{Color} % % \begin{variable}{\l_@@_current_color_tl} @@ -623,7 +710,9 @@ % % \begin{macro}[int]{\@@_literal:n} % Equivalent to \texttt{pdf:content} but favored as the link to -% the \pdfTeX{} primitive approach is clearer. +% the \pdfTeX{} primitive approach is clearer. Some higher-level operations +% use |\tex_special:D| directly: see the later comments on where this is +% useful. % \begin{macrocode} \cs_new_protected:Npn \@@_literal:n #1 { \tex_special:D { pdf:literal~ #1 } } @@ -631,22 +720,80 @@ % \end{macro} % % \begin{macro}[int]{\@@_scope_begin:, \@@_scope_end:} -% Scoping is done using direct PDF operations here. +% Scoping is done using the driver-specific specials. % \begin{macrocode} \cs_new_protected:Npn \@@_scope_begin: - { \@@_literal:n { q } } + { \tex_special:D { x:gsave } } \cs_new_protected:Npn \@@_scope_end: - { \@@_literal:n { Q } } + { \tex_special:D { x:grestore } } % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_matrix:n} -% With \texttt{(x)dvipdfmx} the matrix has to include a translation -% part: that is always zero and so is built in here so that the same -% internal interface works for all PDF-related drivers. +% \subsubsection{Box operations} +% +% \begin{macro}{\@@_box_use_clip:N} +% The code here is idential to that for \texttt{pdfmode}: unlike rotation and +% scaling, there is no higher-level support in the driver for clipping. % \begin{macrocode} -\cs_new_protected:Npn \@@_matrix:n #1 - { \@@_literal:n { #1 \c_space_tl 0~0~cm } } +\cs_new_protected:Npn \@@_box_use_clip:N #1 + { + \@@_scope_begin: + \@@_literal:n + { + 0~ + \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~ + \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~ + \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~ + re~W~n + } + \hbox_overlap_right:n { \box_use:N #1 } + \@@_scope_end: + \skip_horizontal:n { \box_wd:N #1 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_box_use_rotate:Nn} +% Rotating in \texttt{(x)}dvipdmfx can be implemented using either PDF or +% driver-specific code. The former approach however is not \enquote{aware} +% of the content of boxes: this means that any links embded will not be +% adjusted by the rotation. As such, the driver-native approach is prefered: +% the code therefore is similar (though not identical) to the \texttt{dvips} +% version (notice the rotation angle here is positive). As for +% \texttt{dvips}, zero rotation is written as |0| not |-0|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_box_use_rotate:Nn #1#2 + { + \@@_scope_begin: + \tex_special:D + { + x:rotate~ + \fp_compare:nNnTF {#2} = \c_zero_fp + { 0 } + { \fp_eval:n { round ( #2 , 5 ) } } + } + \box_use:N #1 + \@@_scope_end: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_box_use_scale:Nnn} +% Much the same idea for scaling: use the higher-level driver operation to allow +% for box content. +% \begin{macrocode} +\cs_new_protected:Npn \@@_box_use_scale:Nnn #1#2#3 + { + \@@_scope_begin: + \tex_special:D + { + x:scale~ + \fp_eval:n { round ( #2 , 5 ) } ~ + \fp_eval:n { round ( #3 , 5 ) } + } + \hbox_overlap_right:n { \box_use:N #1 } + \@@_scope_end: + } % \end{macrocode} % \end{macro} % @@ -724,103 +871,15 @@ %</xdvipdfmx> % \end{macrocode} % -% \subsection{Common code for PDF production} +% \subsection{Drawing commands: \texttt{pdfmode} and \texttt{(x)dvipdfmx}} % -% As all of the drivers which understand PDF-targeted specials act in much -% the same way there is a lot of shared code. Rather than try to DocStrip it -% interspersed with the above, we collect all of it here. +% Both \texttt{pdfmode} and \texttt{(x)dvipdfmx} directly produce PDF output +% and undertand a shared set of specials for drawing commands. % % \begin{macrocode} %<*dvipdfmx|pdfmode|xdvipdfmx> % \end{macrocode} % -% \subsubsection{Box operations} -% -% \begin{macro}{\@@_box_use_clip:N} -% The general method is to save the current location, define a clipping path -% equivalent to the bounding box, then insert the content at the current -% position and in a zero width box. The \enquote{real} width is then made up -% using a horizontal skip before tidying up. There are other approaches that -% can be taken (for example using XForm objects), but the logic here shares -% as much code as possible and uses the same conversions (and so same -% rounding errors) in all cases. -% \begin{macrocode} -\cs_new_protected:Npn \@@_box_use_clip:N #1 - { - \@@_scope_begin: - \@@_literal:n - { - 0~ - \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~ - \dim_to_decimal_in_bp:n { \box_wd:N #1 } ~ - \dim_to_decimal_in_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~ - re~W~n - } - \hbox_overlap_right:n { \box_use:N #1 } - \@@_scope_end: - \skip_horizontal:n { \box_wd:N #1 } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[int]{\@@_box_use_rotate:Nn} -% \begin{variable}{\l_@@_cos_fp, \l_@@_sin_fp} -% Rotations are set using an affine transformation matrix which therefore -% requires sine/cosine values not the angle itself. We store the rounded -% values to avoid rounding twice. There are also a couple of comparisons to -% ensure that |-0| is not written to the output, as this avoids any issues -% with problematic display programs. Note that numbers are compared to~$0$ -% after rounding. -% \begin{macrocode} -\cs_new_protected:Npn \@@_box_use_rotate:Nn #1#2 - { - \@@_scope_begin: - \box_set_wd:Nn #1 \c_zero_dim - \fp_set:Nn \l_@@_cos_fp { round ( cosd ( #2 ) , 5 ) } - \fp_compare:nNnT \l_@@_cos_fp = \c_zero_fp - { \fp_zero:N \l_@@_cos_fp } - \fp_set:Nn \l_@@_sin_fp { round ( sind ( #2 ) , 5 ) } - \@@_matrix:n - { - \fp_use:N \l_@@_cos_fp \c_space_tl - \fp_compare:nNnTF \l_@@_sin_fp = \c_zero_fp - { 0~0 } - { - \fp_use:N \l_@@_sin_fp - \c_space_tl - \fp_eval:n { -\l_@@_sin_fp } - } - \c_space_tl - \fp_use:N \l_@@_cos_fp - } - \box_use:N #1 - \@@_scope_end: - } -\fp_new:N \l_@@_cos_fp -\fp_new:N \l_@@_sin_fp -% \end{macrocode} -% \end{variable} -% \end{macro} -% -% \begin{macro}{\@@_box_use_scale:Nnn} -% The same idea as for rotation but without the complexity of signs and -% cosines. -% \begin{macrocode} -\cs_new_protected:Npn \@@_box_use_scale:Nnn #1#2#3 - { - \@@_scope_begin: - \@@_matrix:n - { - \fp_eval:n { round ( #2 , 5 ) } ~ - 0~0~ - \fp_eval:n { round ( #3 , 5 ) } - } - \hbox_overlap_right:n { \box_use:N #1 } - \@@_scope_end: - } -% \end{macrocode} -% \end{macro} -% % \subsection{Drawing} % % \begin{macro}[aux]{\@@_draw_literal:n, \@@_draw_literal:x} |