diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx | 303 |
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} |