summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-07-23 17:15:00 +0000
committerKarl Berry <karl@freefriends.org>2012-07-23 17:15:00 +0000
commit134349701bddf7cbbacf6030c6b9f9838aff96fa (patch)
treeec1140c46e1c0347a671a6fa3cf8af5a79e95f93 /Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
parentf7855c12c18bb97b7b9e49ab685ee558d8c0b47b (diff)
l3kernel 3990 (17jul12)
git-svn-id: svn://tug.org/texlive/trunk@27108 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.dtx303
1 files changed, 180 insertions, 123 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
index 2729cad13ca..817a616897f 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
@@ -36,7 +36,7 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3drivers.dtx 3158 2012-01-09 00:47:42Z bruno $
+\GetIdInfo$Id: l3drivers.dtx 3986 2012-07-15 19:23:51Z joseph $
{L3 Experimental drivers}
%</driver|package>
%<*driver>
@@ -89,9 +89,9 @@
%
% \section{Box clipping}
%
-% \begin{function}[added = 2011-11-11]{\driver_box_use_clip:N}
+% \begin{function}[added = 2011-11-11]{\__driver_box_use_clip:N}
% \begin{syntax}
-% \cs{driver_box_use_clip:N} \meta{box}
+% \cs{__driver_box_use_clip:N} \meta{box}
% \end{syntax}
% Inserts the content of the \meta{box} at the current insertion point
% such that any material outside of the bounding box will not be displayed
@@ -101,32 +101,32 @@
%
% \section{Box rotation and scaling}
%
-% \begin{function}[added = 2011-09-01]
-% {\driver_box_rotate_begin:, \driver_box_rotate_end:}
+% \begin{function}[added = 2011-09-01, updated = 2012-05-18]
+% {\__driver_box_rotate_begin:, \__driver_box_rotate_end:}
% \begin{syntax}
-% \cs{driver_box_rotate_begin:}
-% \cs{box_use:N} \cs{l_box_internal_box}
-% \cs{driver_box_rotate_end:}
+% \cs{__driver_box_rotate_begin:}
+% \cs{box_use:N} \cs{l__box_internal_box}
+% \cs{__driver_box_rotate_end:}
% \end{syntax}
% Rotates the \meta{box material} anti-clockwise around the current
% insertion point. The angle of rotation (in degrees counter-clockwise)
% and the sine and cosine of this angle should be stored in
-% \cs{l_box_angle_fp}, \cs{l_box_sin_fp} and \cs{l_box_cos_fp},
+% \cs{l__box_angle_fp}, \cs{l__box_sin_fp} and \cs{l__box_cos_fp},
% respectively. Typically, the box material inserted between the beginning
-% and end markers will be stored in \cs{l_box_internal_box}: this fact is
+% and end markers will be stored in \cs{l__box_internal_box}: this fact is
% required by some drivers to obtain the correct output.
% \end{function}
%
-% \begin{function}[added = 2011-09-02]
-% {\driver_box_scale_begin:, \driver_box_scale_end:}
+% \begin{function}[added = 2011-09-02, updated = 2012-05-18]
+% {\__driver_box_scale_begin:, \__driver_box_scale_end:}
% \begin{syntax}
-% \cs{driver_box_scale_begin:}
+% \cs{__driver_box_scale_begin:}
% \meta{box material}
-% \cs{driver_box_scale_end:}
+% \cs{__driver_box_scale_end:}
% \end{syntax}
% Scales the \meta{box material} (which should be either a \cs{box_use:N}
% or \cs{hbox:n} construct). The \meta{box material} is scaled by the values
-% stored in \cs{l_box_scale_x_fp} and \cs{l_box_scale_y_fp} in the
+% stored in \cs{l__box_scale_x_fp} and \cs{l__box_scale_y_fp} in the
% horizontal and vertical directions, respectively. This function is
% also reused when resizing boxes: at a driver level, only scalings are
% supported and so the higher-level code must convert the absolute sizes
@@ -135,9 +135,10 @@
%
% \section{Colour support}
%
-% \begin{function}[added = 2011-09-03]{\driver_color_ensure_current:}
+% \begin{function}[added = 2011-09-03, updated = 2012-05-18]
+% {\__driver_color_ensure_current:}
% \begin{syntax}
-% \cs{driver_color_ensure_current:}
+% \cs{__driver_color_ensure_current:}
% \end{syntax}
% Ensures that the colour used to typeset material is that which was
% set when the material was placed in a box. This function is therefore
@@ -154,6 +155,7 @@
%
% \begin{macrocode}
%<*initex|package>
+%<@@=driver>
% \end{macrocode}
%
% \begin{macrocode}
@@ -171,7 +173,7 @@
{l3pdfmode.def}{\ExplFileDate}{\ExplFileVersion}
{L3~Experimental~driver:~xdvipdfmx}
%</xdvipdfmx>
-\package_check_loaded_expl:
+\__expl_package_check:
%</package>
% \end{macrocode}
%
@@ -208,50 +210,62 @@
%
% \subsection{Driver utility functions}
%
-% \begin{macro}{\driver_graphic_state_save:}
-% \begin{macro}{\driver_graphic_state_restore:}
+% \begin{macro}{\@@_graphic_state_save:, \@@_graphic_state_restore:}
% All of the drivers have a stack for saving the graphic state. These
-% have slightly different interfaces. As \texttt{dvips} does not
-% automatically save the current location, this is set up here.
+% have slightly different interfaces. For both \texttt{dvips} and
+% \texttt{xdvipdfmx} this is done using an appropriate special.
% \begin{macrocode}
-\cs_new_protected:Npn \driver_graphic_state_save:
+%<*dvips|xdvipdfmx>
+\cs_new_protected_nopar:Npn \@@_graphic_state_save:
%<*dvips>
{ \tex_special:D { ps:gsave } }
%</dvips>
-%<*pdfmode>
- { \pdftex_pdfsave:D }
-%</pdfmode>
%<*xdvipdfmx>
{ \tex_special:D { pdf:bcontent } }
%</xdvipdfmx>
-\cs_new_protected:Npn \driver_graphic_state_restore:
+\cs_new_protected_nopar:Npn \@@_graphic_state_restore:
%<*dvips>
{ \tex_special:D { ps:grestore } }
%</dvips>
-%<*pdfmode>
- { \pdftex_pdfrestore:D }
-%</pdfmode>
%<*xdvipdfmx>
{ \tex_special:D { pdf:econtent } }
%</xdvipdfmx>
+%</dvips|xdvipdfmx>
+% \end{macrocode}
+% For direct PDF output there is also a need to worry about the version
+% of \pdfTeX{} in use: the \tn{pdfsave} primitive was only introduced
+% in version~1.40.0.
+% \begin{macrocode}
+%<*pdfmode>
+\cs_if_exist:NTF \pdftex_pdfsave:D
+ {
+ \cs_new_eq:NN \@@_graphic_state_save: \pdftex_pdfsave:D
+ \cs_new_eq:NN \@@_graphic_state_restore: \pdftex_pdfrestore:D
+ }
+ {
+ \cs_new_protected_nopar:Npn \@@_graphic_state_save:
+ { \pdftex_pdfliteral:D { q } }
+ \cs_new_protected_nopar:Npn \@@_graphic_state_restore:
+ { \pdftex_pdfliteral:D { Q } }
+ }
+%</pdfmode>
% \end{macrocode}
-% \end{macro}
% \end{macro}
%
-% \begin{macro}{\driver_pdf_literal:n, \driver_pdf_literal_direct:n}
+% \begin{macro}{\@@_pdf_literal:n, \@@_pdf_literal_direct:n}
% Both direct PDF mode and \texttt{xdvipdfmx} make use of direct PDF
% special insertion. These are slightly different in the two cases.
% The |direct| versions do not save the current matrix.
% \begin{macrocode}
%<*pdfmode|xdvipdfmx>
-\cs_new_protected:Npn \driver_pdf_literal:n #1
+\cs_new_protected:Npn \@@_pdf_literal:n #1
%<*pdfmode>
{ \pdftex_pdfliteral:D {#1} }
%</pdfmode>
%<*xdvipdfmx>
{ \tex_special:D { pdf:content~ #1 } }
%</xdvipdfmx>
-\cs_new_protected:Npn \driver_pdf_literal_direct:n #1
+\cs_new_protected:Npn \@@_pdf_literal_direct:n #1
%<*pdfmode>
{ \pdftex_pdfliteral:D direct~{#1} }
%</pdfmode>
@@ -262,12 +276,12 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\driver_ps_literal:n}
+% \begin{macro}{\@@_ps_literal:n}
% The same concept for PostScript: these are \enquote{direct} by default,
% but by keeping the same name life should be a little clearer.
% \begin{macrocode}
%<*dvips>
-\cs_new_protected:Npn \driver_ps_literal:n #1
+\cs_new_protected:Npn \@@_ps_literal:n #1
{ \tex_special:D { ps: #1 } }
%</dvips>
% \end{macrocode}
@@ -275,7 +289,7 @@
%
% \subsection{Box clipping}
%
-% \begin{macro}{\driver_box_use_clip:N}
+% \begin{macro}{\@@_box_use_clip:N}
% The overall logic to clipping a box is the same in all cases. 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
@@ -285,9 +299,9 @@
% as much code as possible and uses the same conversions (and so same
% rounding errors) in all three cases.
% \begin{macrocode}
-\cs_new_protected:Npn \driver_box_use_clip:N #1
+\cs_new_protected:Npn \@@_box_use_clip:N #1
{
- \driver_graphic_state_save:
+ \@@_graphic_state_save:
% \end{macrocode}
% The business end of the code sets up the clip box, using the higher-level
% rectangle operators rather than the lower level direct line drawing. This
@@ -301,21 +315,21 @@
% \TeX{} current positions).
% \begin{macrocode}
%<*dvips>
- \driver_ps_literal:n
+ \@@_ps_literal:n
{
/savedmatrix~matrix~currentmatrix~def~
currentpoint~translate~
Resolution~72~div~VResolution~72~div~scale
}
- \driver_ps_literal:n
+ \@@_ps_literal:n
{
0~
- -\dim_strip_bp:n { \box_dp:N #1 } ~neg~
- \dim_strip_bp:n { \box_wd:N #1 } ~
- \dim_strip_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~neg~
+ \__dim_strip_bp:n { \box_dp:N #1 } ~
+ \__dim_strip_bp:n { \box_wd:N #1 } ~
+ \__dim_strip_bp:n { - \box_ht:N #1 - \box_dp:N #1 } ~
rectclip
}
- \driver_ps_literal:n { savedmatrix~setmatrix }
+ \@@_ps_literal:n { savedmatrix~setmatrix }
%</dvips>
% \end{macrocode}
% The PDF box is easier to define as it is automatically in big points and
@@ -323,12 +337,12 @@
% locations automatically.
% \begin{macrocode}
%<*pdfmode|xdvipdfmx>
- \driver_pdf_literal_direct:n
+ \@@_pdf_literal_direct:n
{
0 ~
- -\dim_strip_bp:n { \box_dp:N #1 } ~
- \dim_strip_bp:n { \box_wd:N #1 } ~
- \dim_strip_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
+ \__dim_strip_bp:n { - \box_dp:N #1 } ~
+ \__dim_strip_bp:n { \box_wd:N #1 } ~
+ \__dim_strip_bp:n { \box_ht:N #1 + \box_dp:N #1 } ~
re~W~n
}
%</pdfmode|xdvipdfmx>
@@ -337,7 +351,7 @@
% and then insert the necessary width.
% \begin{macrocode}
\hbox_overlap_right:n { \box_use:N #1 }
- \driver_graphic_state_restore:
+ \@@_graphic_state_restore:
\skip_horizontal:n { \box_wd:N #1 }
}
% \end{macrocode}
@@ -345,16 +359,7 @@
%
% \subsection{Box rotation and scaling}
%
-% \begin{variable}{\l_driver_internal_fp}
-% Needed for a safe sign inversion in PDF mode.
-% \begin{macrocode}
-%<*pdfmode|xdvipdfmx>
-\fp_new:N \l_driver_internal_fp
-%</pdfmode|xdvipdfmx>
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}{\driver_box_rotate_begin:, \driver_box_rotate_end:}
+% \begin{macro}{\@@_box_rotate_begin:, \@@_box_rotate_end:}
% The driver for \texttt{dvips} works with a simple rotation angle.
% In PDF mode, an affine matrix is used instead. The transformation for
% \texttt{xdvipdfmx} can be done either way: to have some code sharing,
@@ -362,137 +367,189 @@
% shared in this way). For the \texttt{dvips}, that odd-looking
% |currentpoint| at the beginning is used to put this data onto the
% stack for |neg exch neg exch translate| to pick up.
+%
+% In both cases, some rounding code is included to limit the floating
+% point values to five decimal places. There is no point using any more
+% as \TeX{}'s dimensions are of that precision, and the extra figures
+% will simply bloat the PDF and make values harder to trace. In the
+% case where the sine and cosine are used, 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.
% \begin{macrocode}
-\cs_new_protected:Npn \driver_box_rotate_begin:
+\cs_new_protected_nopar:Npn \@@_box_rotate_begin:
{
- \driver_graphic_state_save:
+ \@@_graphic_state_save:
%<*dvips>
- \driver_ps_literal:n
+ \@@_ps_literal:n
{
currentpoint~
currentpoint~translate~
- \fp_use:N \l_box_angle_fp \c_space_tl neg~rotate~
+ \fp_compare:nTnTF \l__box_angle_fp = \c_zero_fp
+ { 0 }
+ { \fp_eval:n { round ( - \l__box_angle_fp , 5 ) } }
+ ~rotate~
neg~exch~neg~exch~translate
}
%</dvips>
%<*pdfmode|xdvipdfmx>
- \box_set_wd:Nn \l_box_internal_box \c_zero_dim
- \fp_set_eq:NN \l_driver_internal_fp \l_box_sin_fp
- \fp_neg:N \l_driver_internal_fp
-%<*pdfmode>
- \pdftex_pdfsetmatrix:D
-%</pdfmode>
-%<*xdvipdfmx>
- \driver_pdf_literal_direct:n
-%</xdvipdfmx>
+ \box_set_wd:Nn \l__box_internal_box \c_zero_dim
+ \fp_set:Nn \l__box_cos_fp
{
- \fp_use:N \l_box_cos_fp \c_space_tl
- \fp_use:N \l_box_sin_fp \c_space_tl
- \fp_use:N \l_driver_internal_fp \c_space_tl
- \fp_use:N \l_box_cos_fp
-%<*xdvipdfmx>
- \c_space_tl 0~0~cm
-%</xdvipdfmx>
+ \fp_compare:nNnTF \l__box_cos_fp = \c_zero_fp
+ { 0 }
+ { round ( \l__box_cos_fp , 5 ) }
+ }
+ \fp_set:Nn \l__box_sin_fp { round ( \l__box_sin_fp , 5 ) }
+ \@@_pdf_matrix:n
+ {
+ \fp_use:N \l__box_cos_fp \c_space_tl
+ \fp_compare:nNnTF \l__box_sin_fp = \c_zero_fp
+ { 0~0 }
+ {
+ \fp_use:N \l__box_sin_fp
+ \c_space_tl
+ \fp_eval:n { -\l__box_sin_fp }
+ }
+ \c_space_tl
+ \fp_use:N \l__box_cos_fp
}
%</pdfmode|xdvipdfmx>
}
% \end{macrocode}
-% The end of a rotation means tidying up the output grouping.
+% The end of a rotation means tidying up the output grouping.
% \begin{macrocode}
-\cs_new_eq:NN \driver_box_rotate_end: \driver_graphic_state_restore:
+\cs_new_eq:NN \@@_box_rotate_end: \@@_graphic_state_restore:
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\driver_box_scale_begin:, \driver_box_scale_end:}
+% \begin{macro}{\@@_box_scale_begin:, \@@_box_scale_end:}
% Scaling is not dissimilar to rotation, but the calculations are somewhat
% less complex.
% \begin{macrocode}
-\cs_new_protected:Npn \driver_box_scale_begin:
+\cs_new_protected_nopar:Npn \@@_box_scale_begin:
{
- \driver_graphic_state_save:
+ \fp_set:Nn \l__box_scale_x_fp { round ( \l__box_scale_x_fp , 5 ) }
+ \fp_set:Nn \l__box_scale_y_fp { round ( \l__box_scale_y_fp , 5 ) }
+ \@@_graphic_state_save:
%<*dvips>
- \driver_ps_literal:n
+ \@@_ps_literal:n
{
currentpoint~
currentpoint~translate~
- \fp_use:N \l_box_scale_x_fp \c_space_tl
- \fp_use:N \l_box_scale_y_fp \c_space_tl scale~
+ \fp_use:N \l__box_scale_x_fp \c_space_tl
+ \fp_use:N \l__box_scale_y_fp \c_space_tl scale~
neg~exch~neg~exch~translate
}
%</dvips>
%<*pdfmode|xdvipdfmx>
-%<*pdfmode>
- \pdftex_pdfsetmatrix:D
-%</pdfmode>
-%<*xdvipdfmx>
- \driver_pdf_literal_direct:n
-%</xdvipdfmx>
+ \@@_pdf_matrix:n
{
- \fp_use:N \l_box_scale_x_fp \c_space_tl
+ \fp_use:N \l__box_scale_x_fp \c_space_tl
0~0~
- \fp_use:N \l_box_scale_y_fp
-%<*xdvipdfmx>
- \c_space_tl 0~0~cm
-%</xdvipdfmx>
+ \fp_use:N \l__box_scale_y_fp
}
%</pdfmode|xdvipdfmx>
}
-\cs_new_eq:NN \driver_box_scale_end: \driver_graphic_state_restore:
+\cs_new_eq:NN \@@_box_scale_end: \@@_graphic_state_restore:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_pdf_matrix:n}
+% Here the appropriate function is set up to insert an affine matrix
+% into the PDF. With a new enough \pdfTeX{} (version~1.40.0 or later)
+% there is a primitive for this, which only needs the rotation/scaling/skew
+% part. With an older \pdfTeX{} or with \texttt{xdvipdfmx} the matrix
+% also has to include a translation part: that is always zero and so is
+% built in here.
+% \begin{macrocode}
+%<*pdfmode>
+\cs_if_exist:NTF \pdftex_pdfsetmatrix:D
+ {
+ \cs_new_protected:Npn \@@_pdf_matrix:n #1
+ { \pdftex_pdfsetmatrix:D {#1} }
+ }
+ {
+ \cs_new_protected:Npn \@@_pdf_matrix:n #1
+ { \@@_pdf_literal:n { #1 \c_space_tl 0~0~cm } }
+ }
+%</pdfmode>
+%<*xdvipdfmx>
+\cs_new_protected:Npn \@@_pdf_matrix:n #1
+ { \@@_pdf_literal_direct:n { #1 \c_space_tl 0~0~cm } }
+%</xdvipdfmx>
% \end{macrocode}
% \end{macro}
%
% \subsection{Colour support}
%
-% \begin{variable}{\l_driver_current_color_tl}
+% \begin{variable}{\l_@@_current_color_tl}
% The current colour is needed by all of the engines, but the way this
% is stored varies.
% \begin{macrocode}
-\tl_new:N \l_driver_current_color_tl
+\tl_new:N \l_@@_current_color_tl
%<*dvips>
-\tl_set:Nn \l_driver_current_color_tl { Black }
+\tl_set:Nn \l_@@_current_color_tl { Black }
%</dvips>
%<*pdfmode>
-\tl_set:Nn \l_driver_current_color_tl { 0~g~0~G }
+\tl_set:Nn \l_@@_current_color_tl { 0~g~0~G }
%</pdfmode>
%<*xdvipdfmx>
-\tl_set:Nn \l_driver_current_color_tl { gray~0 }
+\tl_set:Nn \l_@@_current_color_tl { gray~0 }
%</xdvipdfmx>
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\l_driver_color_stack_int}
-% \pdfTeX{} and \LuaTeX{} have multiple stacks available, and the colour
-% stack therefore needs a number.
+% \begin{variable}{\l_@@_color_stack_int}
+% \pdfTeX{} (version~1.40.0 or later) and \LuaTeX{} have multiple stacks
+% available, and the colour stack therefore needs a number.
% \begin{macrocode}
%<*pdfmode>
-\int_new:N \l_driver_color_stack_int
+\int_new:N \l_@@_color_stack_int
%</pdfmode>
% \end{macrocode}
% \end{variable}
%
-% \begin{macro}{\driver_color_ensure_current:}
-% \begin{macro}[aux]{\driver_color_reset:}
+% \begin{macro}{\@@_color_ensure_current:}
+% \begin{macro}[aux]{\@@_color_reset:}
% Setting the current colour depends on the nature of the colour stack
% available. In all cases there is a need to reset the colour after
% the current group.
% \begin{macrocode}
-\cs_new_protected:Npn \driver_color_ensure_current:
- {
%<*dvips|xdvipdfmx>
- \tex_special:D { color~push~\l_driver_current_color_tl }
-%</dvips|xdvipdfmx>
-%<*pdfmode>
- \pdftex_pdfcolorstack:D \l_driver_color_stack_int push
- { \l_driver_current_color_tl }
-%</pdfmode>
- \group_insert_after:N \driver_color_reset:
+\cs_new_protected_nopar:Npn \@@_color_ensure_current:
+ {
+ \tex_special:D { color~push~\l_@@_current_color_tl }
+ \group_insert_after:N \@@_color_reset:
}
-\cs_new_protected:Npn \driver_color_reset:
-%<*dvips|xdvipdfmx>
+\cs_new_protected_nopar:Npn \@@_color_reset:
{ \tex_special:D { color~pop } }
%</dvips|xdvipdfmx>
+% \end{macrocode}
+% Once again there is a version switch for \pdfTeX{}, as the
+% \tn{pdfcolorstack} primitive was introduced in version~1.40.0.
+% \begin{macrocode}
%<*pdfmode>
- { \pdftex_pdfcolorstack:D \l_driver_color_stack_int pop }
+\cs_if_exist:NTF \pdftex_pdfcolorstack:D
+ {
+ \cs_new_protected_nopar:Npn \@@_color_ensure_current:
+ {
+ \pdftex_pdfcolorstack:D \l_@@_color_stack_int push
+ { \l_@@_current_color_tl }
+ \group_insert_after:N \@@_color_reset:
+ }
+ \cs_new_protected_nopar:Npn \@@_color_reset:
+ { \pdftex_pdfcolorstack:D \l_@@_color_stack_int pop }
+ }
+ {
+ \cs_new_protected_nopar:Npn \@@_color_ensure_current:
+ {
+ \@@_pdf_literal:n { \l_@@_current_color_tl }
+ \group_insert_after:N \@@_color_reset:
+ }
+ \cs_new_protected_nopar:Npn \@@_color_reset:
+ { \@@_pdf_literal:n { \l_@@_current_color_tl } }
+ }
%</pdfmode>
% \end{macrocode}
% \end{macro}