summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx267
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}