diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx | 570 |
1 files changed, 368 insertions, 202 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx index 242bc86790c..1e830a52e62 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/03/05} +% \date{Released 2018-04-30} % % \maketitle % @@ -61,7 +61,7 @@ % conjugation with \pdfTeX{} or \LuaTeX{} in DVI mode. % \item \texttt{dvisvgm}: The \texttt{dvisvgm} program, which works in % conjugation with \pdfTeX{} or \LuaTeX{} when run in DVI mode as well -% as with (u)p\TeX{} and \XeTeX{}. +% as with (u)\pTeX{} and \XeTeX{}. % \item \texttt{xdvipdfmx}: The driver used by \XeTeX{}. % \end{itemize} % @@ -97,24 +97,28 @@ % % \section{Box rotation and scaling} % -% \begin{function}[added = 2017-12-13]{\driver_box_use_rotate:Nn} +% \begin{function}[added = 2017-12-13, updated = 2018-04-26] +% {\driver_box_use_rotate:Nn} % \begin{syntax} % \cs{driver_box_use_rotate:Nn} \meta{box} \Arg{angle} % \end{syntax} % Inserts the content of the \meta{box} at the current insertion point -% rotated by the \meta{angle} (expressed in degrees). The material is +% rotated by the \meta{angle} (an \meta{fp expression} expressed in degrees). +% The material is % rotated such the the \TeX{} reference point of the box is the center of % rotation and remains the reference point after rotation. It is the % responsibility of the code using this function to adjust the apparent % size of the inserted material. % \end{function} % -% \begin{function}[added = 2017-12-13]{\driver_box_use_scale:Nnn} +% \begin{function}[added = 2017-12-13, updated = 2018-04-26] +% {\driver_box_use_scale:Nnn} % \begin{syntax} % \cs{driver_box_use_scale:Nnn} \meta{box} \Arg{x-scale} \Arg{y-scale} % \end{syntax} % Inserts the content of the \meta{box} at the current insertion point -% scale by the \meta{x-scale} and \meta{y-scale}. The reference point +% scale by the \meta{x-scale} and \meta{y-scale} (both \meta{fp expressions}). +% The reference point % of the material will be unchanged. It is the responsibility of the % code using this function to adjust the apparent size of the inserted % material. @@ -263,7 +267,7 @@ % \meta{path construction} % \cs{driver_draw_stroke:} % \end{syntax} -% Draws a line along the current path, which is also closed by +% Draws a line along the current path, which is also closed in the case of % \cs{driver_draw_closestroke:}. The nature of the line drawn % is influenced by settings for % \begin{itemize} @@ -334,7 +338,7 @@ % Sets the width to be used for stroking to \meta{dimexpr}. % \end{function} % -% \begin{function}{\driver_draw_cap_dash:nn} +% \begin{function}{\driver_draw_dash_pattern:nn} % \begin{syntax} % \cs{driver_draw_dash:nn} \Arg{dash pattern} \Arg{phase} % \end{syntax} @@ -381,10 +385,11 @@ % % \begin{function}{\driver_draw_miterlimit:n} % \begin{syntax} -% \cs{driver_draw_miterlimit:n} \Arg{dimexpr} +% \cs{driver_draw_miterlimit:n} \Arg{factor} % \end{syntax} % Sets the miter limit of lines joined as a miter, as described in the -% PDF and PostScript manuals. +% PDF and PostScript manuals. The \meta{factor} here is an +% \meta{fp expression}. % \end{function} % % \subsection{Color} @@ -476,23 +481,23 @@ %<*package> \ProvidesExplFile %<*dvipdfmx> - {l3dvidpfmx.def}{2017/03/18}{} + {l3dvidpfmx.def}{2018-04-30}{} {L3 Experimental driver: dvipdfmx} %</dvipdfmx> %<*dvips> - {l3dvips.def}{2017/03/18}{} + {l3dvips.def}{2018-04-30}{} {L3 Experimental driver: dvips} %</dvips> %<*dvisvgm> - {l3dvisvgm.def}{2017/03/18}{} + {l3dvisvgm.def}{2018-04-30}{} {L3 Experimental driver: dvisvgm} %</dvisvgm> %<*pdfmode> - {l3pdfmode.def}{2017/03/18}{} + {l3pdfmode.def}{2018-04-30}{} {L3 Experimental driver: PDF mode} %</pdfmode> %<*xdvipdfmx> - {l3xdvidpfmx.def}{2017/03/18}{} + {l3xdvidpfmx.def}{2018-04-30}{} {L3 Experimental driver: xdvipdfmx} %</xdvipdfmx> %</package> @@ -509,6 +514,18 @@ % takes most of the same code. % \end{itemize} % +% \begin{macro}{\@@_literal_x:n, \@@_literal:n, \@@_literal:x} +% The one shared function for all drivers is access to the basic +% \tn{special} primitive: it has slightly odd expansion behaviour +% so a wrapper is provided. +% \begin{macrocode} +\cs_new_eq:NN \@@_literal_x:n \tex_special:D +\cs_new_protected:Npn \@@_literal:n #1 + { \@@_literal_x:n { \exp_not:n {#1} } } +\cs_generate_variant:Nn \@@_literal:n { x } +% \end{macrocode} +% \end{macro} +% % \subsection{Color support} % % Color support is split into two parts: a \enquote{general} concept and @@ -547,7 +564,10 @@ \exp_after:wN \use:n \current@color \c_space_tl 1 } } - { \exp_after:wN \@@_color_pickup:w \current@color \q_stop #1 } + { + \exp_after:wN \@@_color_pickup:w + \current@color \q_stop #1 + } } \cs_new_protected:Npn \@@_color_pickup:w #1 ~ #2 \q_stop #3 { \tl_set:Nn #3 { #1 ~ #2 } } @@ -563,29 +583,40 @@ % \begin{macro}{\driver_color_gray:n} % \begin{macro}{\driver_color_rgb:nnn} % \begin{macro}{\driver_color_spot:nn} -% \begin{macro}{\@@_color_select:n} +% \begin{macro}{\@@_color_select:n, \@@_color_select:x} % \begin{macro}{\@@_color_reset:} % Push the data to the stack. In the case of \texttt{dvips} also reset the % drawing fill color in raw PostScript. % \begin{macrocode} \cs_new_protected:Npn \driver_color_cmyk:nnnn #1#2#3#4 - { \@@_color_select:n { cmyk~ #1 ~ #2 ~ #3 ~ #4 } } + { + \@@_color_select:x + { + cmyk~ + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} + } + } \cs_new_protected:Npn \driver_color_gray:n #1 - { \@@_color_select:n { gray~ #1 } } + { \@@_color_select:x { gray~ \fp_eval:n {#1} } } \cs_new_protected:Npn \driver_color_rgb:nnn #1#2#3 - { \@@_color_select:n { rgb~ #1 ~ #2 ~ #3 } } + { + \@@_color_select:x + { 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 } } \cs_new_protected:Npn \@@_color_select:n #1 { - \tex_special:D { color~push~ #1 } + \@@_literal:n { color~push~ #1 } %<*dvips> - \tex_special:D { ps::/l3fc~{ }~def } + \@@_literal_postscript:n { /l3fc~{ }~def } %</dvips> \group_insert_after:N \@@_color_reset: } +\cs_generate_variant:Nn \@@_color_select:n { x } \cs_new_protected:Npn \@@_color_reset: - { \tex_special:D { color~pop } } + { \@@_literal:n { color~pop } } % \end{macrocode} % \end{macro} % \end{macro} @@ -663,19 +694,45 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}{\driver_color_cmyk:nnnn} -% \begin{macro}{\driver_color_gray:n} -% \begin{macro}{\driver_color_rgb:nnn} +% \begin{macro}{\driver_color_cmyk:nnnn, \@@_color_cmyk:nnnn} +% \begin{macro}{\driver_color_gray:n, @@_color_gray:n} +% \begin{macro}{\driver_color_rgb:nnn, \@@_color_rgb:nnn} % \begin{macro}{\driver_color_spot:nn} -% \begin{macro}{\@@_color_select:n} +% \begin{macro}{\@@_color_select:n, \@@_color_select:x} % \begin{macro}{\@@_color_reset:} % Simply dump the data, but allowing for \LuaTeX{}. % \begin{macrocode} \cs_new_protected:Npn \driver_color_cmyk:nnnn #1#2#3#4 - { \@@_color_select:n { #1 ~ #2 ~ #3 ~ #4 ~ k ~ #1 ~ #2 ~ #3 ~ #4 ~ K } } + { + \use:x + { + \@@_color_cmyk:nnnn + { \fp_eval:n {#1} } + { \fp_eval:n {#2} } + { \fp_eval:n {#3} } + { \fp_eval:n {#4} } + } + } +\cs_new_protected:Npn \@@_color_cmyk:nnnn #1#2#3#4 + { + \@@_color_select:n + { #1 ~ #2 ~ #3 ~ #4 ~ k ~ #1 ~ #2 ~ #3 ~ #4 ~ K } + } \cs_new_protected:Npn \driver_color_gray:n #1 + { \exp_args:Nx \@@_color_gray:n { \fp_eval:n {#1} } } +\cs_new_protected:Npn \@@_color_gray:n #1 { \@@_color_select:n { #1 ~ g ~ #1 ~ G } } \cs_new_protected:Npn \driver_color_rgb:nnn #1#2#3 + { + \use:x + { + \@@_color_rgb:nnn + { \fp_eval:n {#1} } + { \fp_eval:n {#2} } + { \fp_eval:n {#3} } + } + } +\cs_new_protected:Npn \@@_color_rgb:nnn #1#2#3 { \@@_color_select:n { #1 ~ #2 ~ #3 ~ rg ~ #1 ~ #2 ~ #3 ~ RG } } \cs_new_protected:Npn \driver_color_spot:nn #1#2 { \@@_color_select:n { /#1 ~ cs ~ /#1 ~ CS ~ #2 ~ sc ~ #2 ~ SC } } @@ -687,6 +744,7 @@ \exp_not:N \l_@@_color_stack_int push {#1} \group_insert_after:N \exp_not:N \@@_color_reset: } +\cs_generate_variant:Nn \@@_color_select:n { x } \cs_new_protected:Npx \@@_color_reset: { \cs_if_exist:NTF \luatex_pdfextension:D @@ -714,80 +772,83 @@ % % \subsubsection{Basics} % -% \begin{macro}{\@@_literal:n} -% In the case of \texttt{dvips} there is no build-in saving of the current +% \begin{macro}{\@@_literal_postscript:n, \@@_literal_postscript:x} +% Literal PostScript can be included using a few low-level formats. Here, +% we use the form with no positioning: this is overall more convenient as +% a wrapper. Note that this does require that where position is important, +% an appropriate wrapper is included. +% \begin{macrocode} +\cs_new_protected:Npn \@@_literal_postscript:n #1 + { \@@_literal:n { ps:: #1 } } +\cs_generate_variant:Nn \@@_literal_postscript:n { x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_align_currentpoint_begin:, \@@_align_currentpoint_end:} +% In \texttt{dvips} there is no build-in saving of the current % position, and so some additional PostScript is required to set up the % transformation matrix and also to restore it afterwards. Notice the use % of the stack to save the current position \enquote{up front} and to -% move back to it at the end of the process. +% move back to it at the end of the process. Notice that the |[begin]|/^^A +% |[end]| pair here mean that we can use a run of PostScript statements +% in separate lines: not \emph{required} but does make the code and +% output more clear. % \begin{macrocode} -\cs_new_protected:Npn \@@_literal:n #1 +\cs_new_protected:Npn \@@_align_currentpoint_begin: { - \tex_special:D - { - ps: - currentpoint~ - currentpoint~translate~ - #1 ~ - neg~exch~neg~exch~translate - } + \@@_literal:n { ps::[begin] } + \@@_literal_postscript:n { currentpoint } + \@@_literal_postscript:n { currentpoint~translate } + } +\cs_new_protected:Npn \@@_align_currentpoint_end: + { + \@@_literal_postscript:n { neg~exch~neg~exch~translate } + \@@_literal:n { ps::[end] } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_scope_begin:, \@@_scope_end:} -% Scope saving/restoring is done directly with no need to worry about the -% transformation matrix. General scoping is only for the graphics stack so -% the lower-cost |gsave|/|grestore| pair are used. +% Saving/restoring scope for general operations needs to be done with +% \texttt{dvips} positioning (try without to see this!). Thus we need the +% |ps:| version of the special here. As only the graphics state is ever +% altered within this pairing, we use the lower-cost |g|-versions. % \begin{macrocode} \cs_new_protected:Npn \@@_scope_begin: - { \tex_special:D { ps:gsave } } + { \@@_literal:n { ps:gsave } } \cs_new_protected:Npn \@@_scope_end: - { \tex_special:D { ps:grestore } } -% \end{macrocode} -% \end{macro} -% -% \subsection{Driver-specific auxiliaries} -% -% \begin{macro}[EXP]{\@@_absolute_lengths:n} -% The \texttt{dvips} driver scales all absolute dimensions based -% on the output resolution selected and any \TeX{} magnification. Thus -% for any operation involving absolute lengths there is a correction to -% make. This is based on \texttt{normalscale} from \texttt{special.pro} -% but using the stack rather than a definition to save the current matrix. -% \begin{macrocode} -\cs_new:Npn \@@_absolute_lengths:n #1 - { - matrix~currentmatrix~ - Resolution~72~div~VResolution~72~div~scale~ - DVImag~dup~scale~ - #1 ~ - setmatrix - } + { \@@_literal:n { ps:grestore } } % \end{macrocode} % \end{macro} % % \subsubsection{Box operations} % % \begin{macro}{\driver_box_use_clip:N} -% Much the same idea as for the PDF mode version but with a slightly -% different syntax for creating the clip path. To avoid any scaling -% issues we need the absolute length auxiliary here. +% The \texttt{dvips} driver scales all absolute dimensions based on the +% output resolution selected and any \TeX{} magnification. Thus for any +% operation involving absolute lengths there is a correction to make. See +% \texttt{normalscale} from \texttt{special.pro} for the variables, noting +% that here everything is saved on the stack rather than as a separate +% variable. Once all of that is done, the actual clipping is trivial. % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_clip:N #1 { \@@_scope_begin: - \@@_literal:n + \@@_align_currentpoint_begin: + \@@_literal_postscript:n { matrix~currentmatrix } + \@@_literal_postscript:n + { Resolution~72~div~VResolution~72~div~scale } + \@@_literal_postscript:n { DVImag~dup~scale } + \@@_literal_postscript:x { - \@@_absolute_lengths: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 } ~ - rectclip - } + 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 } ~ + rectclip } + \@@_literal_postscript:n { setmatrix } + \@@_align_currentpoint_end: \hbox_overlap_right:n { \box_use:N #1 } \@@_scope_end: \skip_horizontal:n { \box_wd:N #1 } @@ -796,25 +857,31 @@ % \end{macro} % % \begin{macro}{\driver_box_use_rotate:Nn} +% \begin{macro}{\@@_box_use_rotate:Nn} % Rotating using \texttt{dvips} does not require that the box dimensions % are altered and has a very convenient built-in operation. Zero rotation % must be written as |0| not |-0| so there is a quick test. % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_rotate:Nn #1#2 + { \exp_args:NNf \@@_box_use_rotate:Nn #1 { \fp_eval:n {#2} } } +\cs_new_protected:Npn \@@_box_use_rotate:Nn #1#2 { \@@_scope_begin: - \@@_literal:n + \@@_align_currentpoint_begin: + \@@_literal_postscript:x { \fp_compare:nNnTF {#2} = \c_zero_fp { 0 } - { \fp_eval:n { round ( -#2 , 5 ) } } ~ + { \fp_eval:n { round ( -(#2) , 5 ) } } ~ rotate } + \@@_align_currentpoint_end: \box_use:N #1 \@@_scope_end: } % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\driver_box_use_scale:Nnn} % The \texttt{dvips} driver once again has a dedicated operation we can @@ -823,12 +890,14 @@ \cs_new_protected:Npn \driver_box_use_scale:Nnn #1#2#3 { \@@_scope_begin: - \@@_literal:n + \@@_align_currentpoint_begin: + \@@_literal_postscript:x { \fp_eval:n { round ( #2 , 5 ) } ~ \fp_eval:n { round ( #3 , 5 ) } ~ scale } + \@@_align_currentpoint_end: \hbox_overlap_right:n { \box_use:N #1 } \@@_scope_end: } @@ -849,21 +918,17 @@ % sizes here. % \begin{macrocode} \cs_new_protected:Npn \@@_image_include_eps:n #1 - { - \tex_special:D { PSfile = #1 } - } + { \@@_literal:n { PSfile = #1 } } % \end{macrocode} % \end{macro} % % \subsection{Drawing} % % \begin{macro}{\@@_draw_literal:n, \@@_draw_literal:x} -% Literals with no positioning (using |ps:| each one is positioned but -% cut off from everything else, so no good for the stepwise approach needed -% here). +% The same as literal PostScript: same arguments about positioning apply +% her. % \begin{macrocode} -\cs_new_protected:Npn \@@_draw_literal:n #1 - { \tex_special:D { ps:: #1 } } +\cs_new_eq:NN \@@_draw_literal:n \@@_literal_postscript:n \cs_generate_variant:Nn \@@_draw_literal:n { x } % \end{macrocode} % \end{macro} @@ -873,22 +938,25 @@ % continue on to a matching |ps::[end]|: contrast with |ps:|, which positions % but where we can't split material between separate calls. The % |@beginspecial|/|@endspecial| pair are from |special.pro| and correct the -% scale and $y$-axis direction. The reference point at the start of the box -% is saved (as |l3x|/|l3y|) as it is needed when inserting various items. +% scale and $y$-axis direction. The definition of |/l3fc| deals with fill +% color in paths. In contrast to \pkg{pgf}, we don't save the current point: +% discussion with Tom Rokici suggested a better way to handle the necessary +% translations (see \cs{driver_draw_box_use:Nnnnn}). (Note that +% |@beginspecial|/|@endspecial| forms a driver scope.) The |[begin]|/^^A +% |[end]| lines are handled differently from the rest as they are +% conceptually different: not really drawing literals but instructions to +% \texttt{dvips} itself. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_begin: { - \@@_draw_literal:n { [begin] } - \@@_draw_literal:n { save } - \@@_draw_literal:n { /l3x~currentpoint~/l3y~exch~def~def } + \@@_literal:n { ps::[begin] } \@@_draw_literal:n { @beginspecial } \@@_draw_literal:n { /l3fc~{ }~def } } \cs_new_protected:Npn \driver_draw_end: { \@@_draw_literal:n { @endspecial } - \@@_draw_literal:n { restore } - \@@_draw_literal:n { [end] } + \@@_literal:n { ps::[end] } } % \end{macrocode} % \end{macro} @@ -917,12 +985,18 @@ \cs_new_protected:Npn \driver_draw_moveto:nn #1#2 { \@@_draw_literal:x - { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ moveto } + { + \dim_to_decimal_in_bp:n {#1} ~ + \dim_to_decimal_in_bp:n {#2} ~ moveto + } } \cs_new_protected:Npn \driver_draw_lineto:nn #1#2 { \@@_draw_literal:x - { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ lineto } + { + \dim_to_decimal_in_bp:n {#1} ~ + \dim_to_decimal_in_bp:n {#2} ~ lineto + } } \cs_new_protected:Npn \driver_draw_rectangle:nnnn #1#2#3#4 { @@ -984,7 +1058,7 @@ { \@@_draw_literal:n { closepath } } \cs_new_protected:Npn \driver_draw_stroke: { - \@@_draw_literal:n { stroke } + \@@_draw_literal:n { stroke } \bool_if:NT \g_@@_draw_clip_bool { \@@_draw_literal:x @@ -1064,7 +1138,7 @@ % \end{variable} % \end{macro} % -% \begin{macro}{\driver_draw_cap_dash:nn} +% \begin{macro}{\driver_draw_dash_pattern:nn} % \begin{macro}{\@@_draw_dash:n} % \begin{macro}{\driver_draw_linewidth:n} % \begin{macro}{\driver_draw_miterlimit:n} @@ -1076,25 +1150,26 @@ % Converting paths to output is again a case of mapping directly to % PostScript operations. % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_cap_dash:nn #1#2 +\cs_new_protected:Npn \driver_draw_dash_pattern:nn #1#2 { \@@_draw_literal:x { - [ ~ - \clist_map_function:nN {#1} \@@_draw_dash:n + [ + \exp_args:Nf \use:n + { \clist_map_function:nN {#1} \@@_draw_dash:n } ] ~ \dim_to_decimal_in_bp:n {#2} ~ setdash } } \cs_new:Npn \@@_draw_dash:n #1 - { \dim_to_decimal_in_bp:n {#1} ~ } + { ~ \dim_to_decimal_in_bp:n {#1} } \cs_new_protected:Npn \driver_draw_linewidth:n #1 { \@@_draw_literal:x { \dim_to_decimal_in_bp:n {#1} ~ setlinewidth } } \cs_new_protected:Npn \driver_draw_miterlimit:n #1 - { \@@_draw_literal:n { #1 ~ setmiterlimit } } + { \@@_draw_literal:x { \fp_eval:n {#1} ~ setmiterlimit } } \cs_new_protected:Npn \driver_draw_cap_butt: { \@@_draw_literal:n { 0 ~ setlinecap } } \cs_new_protected:Npn \driver_draw_cap_round: @@ -1114,7 +1189,6 @@ % \end{macro} % \end{macro} % -% % \begin{macro} % { % \driver_draw_color_fill_cmyk:nnnn , @@ -1130,31 +1204,57 @@ % \driver_draw_color_fill_rgb:nnn , % \driver_draw_color_stroke_rgb:nnn % } -% \begin{macro}{\@@_draw_color_fill:n, \@@_draw_color_stroke:n} +% \begin{macro} +% { +% \@@_draw_color_fill:n, \@@_draw_color_fill:x, +% \@@_draw_color_stroke:n, \@@_draw_color_stroke:x +% } % For \texttt{dvips}, we can use the standard color stack to deal with % stroke color, but for fills have to switch to raw PostScript. This is % thus not handled by the stack, but the context is very restricted. See % also how fills are implemented. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_color_fill_cmyk:nnnn #1#2#3#4 - { \@@_draw_fill:n { #1 ~ #2 ~ #3 ~ #4 ~ setcmykcolor } } + { + \@@_draw_color_fill:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + setcmykcolor + } + } \cs_new_protected:Npn \driver_draw_color_stroke_cmyk:nnnn #1#2#3#4 - { \@@_draw_stroke:n { cmyk ~ #1 ~ #2 ~ #3 ~ #4 } } + { + \@@_draw_color_stroke:x + { + cmyk ~ + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} + } + } \cs_new_protected:Npn \driver_draw_color_fill_gray:n #1 - { \@@_draw_fill:n { #1 ~ setgray } } + { \@@_draw_color_fill:x { \fp_eval:n {#1} ~ setgray } } \cs_new_protected:Npn \driver_draw_color_stroke_gray:n #1 - { \@@_draw_stroke:n { gray ~ #1 } } + { \@@_draw_color_stroke:x { gray ~ \fp_eval:n {#1} } } \cs_new_protected:Npn \driver_draw_color_fill_rgb:nnn #1#2#3 - { \@@_draw_fill:n { #1 ~ #2 ~ #3 ~ setrgbcolor } } + { + \@@_draw_color_fill:x + { \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ setrgbcolor } + } \cs_new_protected:Npn \driver_draw_color_stroke_rgb:nnn #1#2#3 - { \@@_draw_stroke:n { rgb ~ #1 ~ #2 ~ #3 } } + { + \@@_draw_color_stroke:x + { rgb ~ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} } + } \cs_new_protected:Npn \@@_draw_color_fill:n #1 { \@@_draw_literal:n { /l3fc ~ { #1 } ~ def } } +\cs_generate_variant:Nn \@@_draw_color_fill:n { x } \cs_new_protected:Npn \@@_draw_color_stroke:n #1 { - \tex_special:D { color~push~#1 } + \@@_literal:n { color~push~#1 } \group_insert_after:N \@@_color_reset: } +\cs_generate_variant:Nn \@@_draw_color_stroke:n { x } % \end{macrocode} % \end{macro} % \end{macro} @@ -1169,31 +1269,55 @@ % path available and simply dump the matrix as given. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_cm:nnnn #1#2#3#4 - { \@@_draw_literal:n { [#1 ~ #2 ~ #3 ~ #4 ~ 0 ~ 0 ] ~ concat } } + { + \@@_draw_literal:n + { + [ + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + 0 ~ 0 + ] ~ + concat + } + } % \end{macrocode} % \end{macro} % % \begin{macro}{\driver_draw_box_use:Nnnnn} % Inside a picture |@beginspecial|/|@endspecial| are active, which is % normally a good thing but means that the position and scaling would be off -% if the box was inserted directly. Instead, we need to reverse the effect of -% the (normally desirable) shift/scaling within the box. That requires -% knowing where the reference point for the drawing is: saved as |l3x|/|l3y| -% at the start of the picture. Transformation here is relative to the -% drawing origin so has to be done purely in driver code not using \TeX{} -% offsets. +% if the box was inserted directly. To deal with that, there are a number of +% possible approaches. The implementation here was suggested by Tom Rokici +% (author of \texttt{dvips}). We end the current special placement, then +% set the current point with a literal |[begin]|. As for general +% literals, we then use the stack to store the current point and move to +% it. To insert the required transformation, we have to flip the $y$-axis, +% once before and once after it. Then we get back to the \TeX{} reference +% point to insert our content. The clean up has to happen in the right +% places, hence the |[begin]|/|[end]| pair around |restore|. Finally, +% we can return to \enquote{normal} drawing mode. Notice that the set up +% here is very similar to that in \cs{@@_align_currentpoint_\ldots}, but +% the ordering of saving and restoring is different (intermixed). % \begin{macrocode} \cs_new_protected:Npn \driver_draw_box_use:Nnnnn #1#2#3#4#5 { - \@@_scope_begin: + \@@_draw_literal:n { @endspecial } \@@_draw_literal:n { [end] } + \@@_draw_literal:n { [begin] } + \@@_draw_literal:n { save } + \@@_draw_literal:n { currentpoint } + \@@_draw_literal:n { currentpoint~translate } + \driver_draw_cm:nnnn { 1 } { 0 } { 0 } { -1 } \driver_draw_cm:nnnn {#2} {#3} {#4} {#5} - \@@_draw_literal:n { 72~Resolution~div~72~VResolution~div~neg~scale } - \@@_draw_literal:n { magscale~{1~DVImag~div~dup~scale}~if } - \@@_draw_literal:n { l3x~neg~l3y~neg~translate } + \driver_draw_cm:nnnn { 1 } { 0 } { 0 } { -1 } + \@@_draw_literal:n { neg~exch~neg~exch~translate } + \@@_draw_literal:n { [end] } \hbox_overlap_right:n { \box_use:N #1 } \@@_draw_literal:n { [begin] } - \@@_scope_end: + \@@_draw_literal:n { restore } + \@@_draw_literal:n { [end] } + \@@_draw_literal:n { [begin] } + \@@_draw_literal:n { @beginspecial } } % \end{macrocode} % \end{macro} @@ -1209,27 +1333,28 @@ % \end{macrocode} % % The direct PDF driver covers both \pdfTeX{} and \LuaTeX{}. The latter -% renames/restructures the driver primitives but this can be handled +% renames and restructures the driver primitives but this can be handled % at one level of abstraction. As such, we avoid using two separate drivers % for this material at the cost of some \texttt{x}-type definitions to get % everything expanded up-front. % % \subsubsection{Basics} % -% \begin{macro}{\@@_literal:n} +% \begin{macro}{\@@_literal_pdf:n, \@@_literal_pdf:x} % This is equivalent to \verb|\special{pdf:}| but the engine can % track it. Without the \texttt{direct} keyword everything is kept in % sync: the transformation matrix is set to the current point automatically. % Note that this is still inside the text (\texttt{BT} \dots \texttt{ET} % block). % \begin{macrocode} -\cs_new_protected:Npx \@@_literal:n #1 +\cs_new_protected:Npx \@@_literal_pdf:n #1 { \cs_if_exist:NTF \luatex_pdfextension:D { \luatex_pdfextension:D literal } { \pdftex_pdfliteral:D } - {#1} + { \exp_not:N \exp_not:n {#1} } } +\cs_generate_variant:Nn \@@_literal_pdf:n { x } % \end{macrocode} % \end{macro} % @@ -1251,7 +1376,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_matrix:n} +% \begin{macro}{\@@_matrix:n, \@@_matrix:x} % Here the appropriate function is set up to insert an affine matrix % into the PDF. With \pdfTeX{} and \LuaTeX{} in direct PDF output mode there % is a primitive for this, which only needs the rotation/scaling/skew part. @@ -1261,8 +1386,9 @@ \cs_if_exist:NTF \luatex_pdfextension:D { \luatex_pdfextension:D setmatrix } { \pdftex_pdfsetmatrix:D } - {#1} + { \exp_not:N \exp_not:n {#1} } } +\cs_generate_variant:Nn \@@_matrix:n { x } % \end{macrocode} % \end{macro} % @@ -1280,7 +1406,7 @@ \cs_new_protected:Npn \driver_box_use_clip:N #1 { \@@_scope_begin: - \@@_literal:n + \@@_literal_pdf:x { 0~ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~ @@ -1296,6 +1422,7 @@ % \end{macro} % % \begin{macro}{\driver_box_use_rotate:Nn} +% \begin{macro}{\@@_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 @@ -1305,6 +1432,8 @@ % after rounding. % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_rotate:Nn #1#2 + { \exp_args:NNf \@@_box_use_rotate:Nn #1 { \fp_eval:n {#2} } } +\cs_new_protected:Npn \@@_box_use_rotate:Nn #1#2 { \@@_scope_begin: \box_set_wd:Nn #1 { 0pt } @@ -1312,7 +1441,7 @@ \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 + \@@_matrix:x { \fp_use:N \l_@@_cos_fp \c_space_tl \fp_compare:nNnTF \l_@@_sin_fp = \c_zero_fp @@ -1333,6 +1462,7 @@ % \end{macrocode} % \end{variable} % \end{macro} +% \end{macro} % % \begin{macro}{\driver_box_use_scale:Nnn} % The same idea as for rotation but without the complexity of signs and @@ -1341,7 +1471,7 @@ \cs_new_protected:Npn \driver_box_use_scale:Nnn #1#2#3 { \@@_scope_begin: - \@@_matrix:n + \@@_matrix:x { \fp_eval:n { round ( #2 , 5 ) } ~ 0~0~ @@ -1482,14 +1612,13 @@ % % \subsubsection{Basics} % -% \begin{macro}{\@@_literal:n} +% \begin{macro}{\@@_literal_pdf:n, \@@_literal_pdf:x} % Equivalent to \texttt{pdf:content} but favored as the link to -% the \pdfTeX{} primitive approach is clearer. Some higher-level operations -% use |\tex_special:D| directly: see the later comments on where this is -% useful. +% the \pdfTeX{} primitive approach is clearer. % \begin{macrocode} -\cs_new_protected:Npn \@@_literal:n #1 - { \tex_special:D { pdf:literal~ #1 } } +\cs_new_protected:Npn \@@_literal_pdf:n #1 + { \@@_literal:n { pdf:literal~ #1 } } +\cs_generate_variant:Nn \@@_literal_pdf:n { x } % \end{macrocode} % \end{macro} % @@ -1497,9 +1626,9 @@ % Scoping is done using the driver-specific specials. % \begin{macrocode} \cs_new_protected:Npn \@@_scope_begin: - { \tex_special:D { x:gsave } } + { \@@_literal:n { x:gsave } } \cs_new_protected:Npn \@@_scope_end: - { \tex_special:D { x:grestore } } + { \@@_literal:n { x:grestore } } % \end{macrocode} % \end{macro} % @@ -1512,7 +1641,7 @@ \cs_new_protected:Npn \driver_box_use_clip:N #1 { \@@_scope_begin: - \@@_literal:n + \@@_literal_pdf:x { 0~ \dim_to_decimal_in_bp:n { -\box_dp:N #1 } ~ @@ -1528,18 +1657,21 @@ % \end{macro} % % \begin{macro}{\driver_box_use_rotate:Nn} +% \begin{macro}{\@@_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 embedded links would not be -% adjusted by the rotation. As such, the driver-native approach is prefered: +% adjusted by the rotation. As such, the driver-native approach is preferred: % 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 \driver_box_use_rotate:Nn #1#2 + { \exp_args:NNf \@@_box_use_rotate:Nn #1 { \fp_eval:n {#2} } } +\cs_new_protected:Npn \@@_box_use_rotate:Nn #1#2 { \@@_scope_begin: - \tex_special:D + \@@_literal:x { x:rotate~ \fp_compare:nNnTF {#2} = \c_zero_fp @@ -1551,6 +1683,7 @@ } % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\driver_box_use_scale:Nnn} % Much the same idea for scaling: use the higher-level driver operation to allow @@ -1559,7 +1692,7 @@ \cs_new_protected:Npn \driver_box_use_scale:Nnn #1#2#3 { \@@_scope_begin: - \tex_special:D + \@@_literal:x { x:scale~ \fp_eval:n { round ( #2 , 5 ) } ~ @@ -1622,7 +1755,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_image_include_eps:n #1 { - \tex_special:D { PSfile = #1 } + \@@_literal:n { PSfile = #1 } } \cs_new_protected:Npn \@@_image_include_jpg:n #1 { \@@_image_include_auxi:nn {#1} { image } } @@ -1656,7 +1789,7 @@ { \int_if_exist:cTF { c_@@_image_ #2#1 _int } { - \tex_special:D + \@@_literal:x { pdf:usexobj~@image \int_use:c { c_@@_image_ #2#1 _int } } } { \@@_image_include_auxiii:nn {#2} {#1} {#3} } @@ -1672,7 +1805,7 @@ { \int_gincr:N \g_@@_image_int \int_const:cn { c_@@_image_ #1#2 _int } { \g_@@_image_int } - \tex_special:D + \@@_literal:x { pdf:#3~ @image \int_use:c { c_@@_image_ #1#2 _int } @@ -1827,7 +1960,7 @@ % \begin{macro}{\@@_draw_literal:n, \@@_draw_literal:x} % Pass data through using a dedicated interface. % \begin{macrocode} -\cs_new_eq:NN \@@_draw_literal:n \@@_literal:n +\cs_new_eq:NN \@@_draw_literal:n \@@_literal_pdf:n \cs_generate_variant:Nn \@@_draw_literal:n { x } % \end{macrocode} % \end{macro} @@ -1843,13 +1976,10 @@ % \end{macro} % % \begin{macro}{\driver_draw_scope_begin:, \driver_draw_scope_end:} -% In contrast to a general scope, a drawing scope is always done using -% the PDF operators so is the same for all relevant drivers. +% Use the driver-level scope mechanisms. % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_scope_begin: - { \@@_draw_literal:n { q } } -\cs_new_protected:Npn \driver_draw_scope_end: - { \@@_draw_literal:n { Q } } +\cs_new_eq:NN \driver_draw_scope_begin: \@@_scope_begin: +\cs_new_eq:NN \driver_draw_scope_end: \@@_scope_end: % \end{macrocode} % \end{macro} % @@ -1857,9 +1987,7 @@ % \begin{macro}{\driver_draw_curveto:nnnnnn} % \begin{macro}{\driver_draw_rectangle:nnnn} % Path creation operations all resolve directly to PDF primitive steps, with -% only the need to convert to \texttt{bp}. Notice that \texttt{x}-type -% expansion is included here to ensure that any variable values are -% forced to literals before any possible caching. +% only the need to convert to \texttt{bp}. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_moveto:nn #1#2 { @@ -1947,7 +2075,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\driver_draw_cap_dash:nn} +% \begin{macro}{\driver_draw_dash_pattern:nn} % \begin{macro}{\@@_draw_dash:n} % \begin{macro}{\driver_draw_linewidth:n} % \begin{macro}{\driver_draw_miterlimit:n} @@ -1959,25 +2087,26 @@ % Converting paths to output is again a case of mapping directly to % PDF operations. % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_cap_dash:nn #1#2 +\cs_new_protected:Npn \driver_draw_dash_pattern:nn #1#2 { \@@_draw_literal:x { - [ ~ - \clist_map_function:nN {#1} \@@_draw_dash:n + [ + \exp_args:Nf \use:n + { \clist_map_function:nN {#1} \@@_draw_dash:n } ] ~ \dim_to_decimal_in_bp:n {#2} ~ d } } \cs_new:Npn \@@_draw_dash:n #1 - { \dim_to_decimal_in_bp:n {#1} ~ } + { ~ \dim_to_decimal_in_bp:n {#1} } \cs_new_protected:Npn \driver_draw_linewidth:n #1 { \@@_draw_literal:x { \dim_to_decimal_in_bp:n {#1} ~ w } } \cs_new_protected:Npn \driver_draw_miterlimit:n #1 - { \@@_draw_literal:x { #1 ~ M } } + { \@@_draw_literal:x { \fp_eval:n {#1} ~ M } } \cs_new_protected:Npn \driver_draw_cap_butt: { \@@_draw_literal:n { 0 ~ J } } \cs_new_protected:Npn \driver_draw_cap_round: @@ -2012,33 +2141,56 @@ % \driver_draw_color_fill_rgb:nnn , % \driver_draw_color_stroke_rgb:nnn % } +% \begin{macro}{\@@_color_fill_select:n, \@@_color_fill_select:x} % For the stroke color, all engines here can use the color stack to handle % the setting. However, that is not the case for fill color: the stack in % \texttt{(x)dvipdfmx} only covers one type of color. So we have to use % different approaches for the two sets of engines. % \begin{macrocode} \cs_new_protected:Npn \driver_draw_color_fill_cmyk:nnnn #1#2#3#4 - { \@@_color_fill_select:n { #1 ~ #2 ~ #3 ~ #4 ~ k } } + { + \@@_color_fill_select:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + k + } + } \cs_new_protected:Npn \driver_draw_color_stroke_cmyk:nnnn #1#2#3#4 - { \@@_color_select:n { #1 ~ #2 ~ #3 ~ #4 ~ K } } + { + \@@_color_select:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + k + } + } \cs_new_protected:Npn \driver_draw_color_fill_gray:n #1 - { \@@_color_fill_select:n { #1 ~ g } } + { \@@_color_fill_select:x { \fp_eval:n {#1} ~ g } } \cs_new_protected:Npn \driver_draw_color_stroke_gray:n #1 - { \@@_color_select:n { #1 ~ G } } + { \@@_color_select:x { \fp_eval:n {#1} ~ G } } \cs_new_protected:Npn \driver_draw_color_fill_rgb:nnn #1#2#3 - { \@@_color_fill_select:n { #1 ~ #2 ~ #3 ~ rg } } + { + \@@_color_fill_select:x + { \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ rg } + } \cs_new_protected:Npn \driver_draw_color_stroke_rgb:nnn #1#2#3 - { \@@_color_select:n { #1 ~ #2 ~ #3 ~ RG } } + { + \@@_color_select:x + { \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ RG } + } %<*pdfmode> \cs_new_eq:NN \@@_color_fill_select:n \@@_color_select:n %</pdfmode> %<*dvipdfmx|xdvipdfmx> \cs_new_eq:NN \@@_color_fill_select:n \@@_draw_literal:n %</dvipdfmx|xdvipdfmx> +\cs_generate_variant:Nn \@@_color_fill_select:n { x } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\driver_draw_cm:nnnn} % \begin{macro}{\@@_draw_cm:nnnn} @@ -2053,7 +2205,11 @@ \cs_new_protected:Npn \driver_draw_cm:nnnn #1#2#3#4 { %<*pdfmode> - \@@_matrix:n { #1 ~ #2 ~ #3 ~ #4 } + \@@_matrix:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} + } %</pdfmode> %<*dvipdfmx|xdvipdfmx> \@@_draw_cm_decompose:nnnnN {#1} {#2} {#3} {#4} @@ -2063,20 +2219,20 @@ %<*dvipdfmx|xdvipdfmx> \cs_new_protected:Npn \@@_draw_cm:nnnn #1#2#3#4 { - \tex_special:D + \@@_literal:x { x:rotate~ \fp_compare:nNnTF {#1} = \c_zero_fp { 0 } { \fp_eval:n { round ( -#1 , 5 ) } } } - \tex_special:D + \@@_literal:x { x:scale~ \fp_eval:n { round ( #2 , 5 ) } ~ \fp_eval:n { round ( #3 , 5 ) } } - \tex_special:D + \@@_literal:x { x:rotate~ \fp_compare:nNnTF {#4} = \c_zero_fp @@ -2207,11 +2363,17 @@ \driver_draw_cm:nnnn {#2} {#3} {#4} {#5} %</pdfmode> %<*dvipdfmx|xdvipdfmx> - \tex_special:D { pdf:btrans~matrix~ #2 ~ #3 ~ #4 ~ #5 ~ 0 ~ 0 } + \@@_literal:x + { + pdf:btrans~matrix~ + \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ + \fp_eval:n {#4} ~ \fp_eval:n {#5} ~ + 0 ~ 0 + } %</dvipdfmx|xdvipdfmx> \hbox_overlap_right:n { \box_use:N #1 } %<*dvipdfmx|xdvipdfmx> - \tex_special:D { pdf:etrans } + \@@_literal:n { pdf:etrans } %</dvipdfmx|xdvipdfmx> \@@_scope_end: } @@ -2230,15 +2392,16 @@ % % \subsubsection{Basics} % -% \begin{macro}{\@@_literal:n} +% \begin{macro}{\@@_literal_svg:n, \@@_literal_svg:x} % Unlike the other drivers, the requirements for making SVG files mean % that we can't conveniently transform all operations to the current point. % That makes life a bit more tricky later as that needs to be accounted for. % A new line is added after each call to help to keep the output readable % for debugging. % \begin{macrocode} -\cs_new_protected:Npn \@@_literal:n #1 - { \tex_special:D { dvisvgm:raw~ #1 { ?nl } } } +\cs_new_protected:Npn \@@_literal_svg:n #1 + { \@@_literal:n { dvisvgm:raw~ #1 { ?nl } } } +\cs_generate_variant:Nn \@@_literal_svg:n { x } % \end{macrocode} % \end{macro} % @@ -2247,22 +2410,23 @@ % operations have to be \enquote{tied} to these not simply inside them. % \begin{macrocode} \cs_new_protected:Npn \@@_scope_begin: - { \@@_literal:n { <g> } } + { \@@_literal_svg:n { <g> } } \cs_new_protected:Npn \@@_scope_end: - { \@@_literal:n { </g> } } + { \@@_literal_svg:n { </g> } } % \end{macrocode} % \end{macro} % % \subsection{Driver-specific auxiliaries} % -% \begin{macro}{\@@_scope_begin:n} +% \begin{macro}{\@@_scope_begin:n, \@@_scope_begin:x} % In SVG transformations, clips and so on are attached directly to scopes so % we need a way or allowing for that. This is rather more useful than % \cs{@@_scope_begin:} as a result. No assumptions are made about the nature % of the scoped operation(s). % \begin{macrocode} \cs_new_protected:Npn \@@_scope_begin:n #1 - { \@@_literal:n { <g~ #1 > } } + { \@@_literal_svg:n { <g~ #1 > } } +\cs_generate_variant:Nn \@@_scope_begin:n { x } % \end{macrocode} % \end{macro} % @@ -2282,9 +2446,9 @@ \cs_new_protected:Npn \driver_box_use_clip:N #1 { \int_gincr:N \g_@@_clip_path_int - \@@_literal:n + \@@_literal_svg:x { < clipPath~id = " l3cp \int_use:N \g_@@_clip_path_int " > } - \@@_literal:n + \@@_literal_svg:x { < path ~ d = @@ -2301,7 +2465,7 @@ " /> } - \@@_literal:n + \@@_literal_svg:n { < /clipPath > } % \end{macrocode} % In general the SVG set up does not try to transform coordinates to the @@ -2319,9 +2483,10 @@ scale ( 1 , -1 ) " } - \@@_scope_begin:n + \@@_scope_begin:x { - clip-path = "url ( \c_hash_str l3cp \int_use:N \g_@@_clip_path_int ) " + clip-path = + "url ( \c_hash_str l3cp \int_use:N \g_@@_clip_path_int ) " } \@@_scope_begin:n { @@ -2350,12 +2515,12 @@ % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_rotate:Nn #1#2 { - \@@_scope_begin:n + \@@_scope_begin:x { transform = " rotate - ( \fp_eval:n { round ( -#2 , 5 ) } , ~ { ?x } , ~ { ?y } ) + ( \fp_eval:n { round ( -(#2) , 5 ) } , ~ { ?x } , ~ { ?y } ) " } \box_use:N #1 @@ -2371,7 +2536,7 @@ % \begin{macrocode} \cs_new_protected:Npn \driver_box_use_scale:Nnn #1#2#3 { - \@@_scope_begin:n + \@@_scope_begin:x { transform = " @@ -2412,7 +2577,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_image_include_png:n #1 { - \tex_special:D + \@@_literal:x { dvisvgm:img~ \dim_to_decimal:n { \l_image_ury_dim } ~ @@ -2421,7 +2586,8 @@ } } \cs_new_eq:NN \@@_image_include_jpg:n \@@_image_include_png:n -\cs_new:Npn \@@_image_include_bitmap_quote:w #1 " #2 " #3 \q_stop { #1#2 } +\cs_new:Npn \@@_image_include_bitmap_quote:w #1 " #2 " #3 \q_stop + { #1#2 } % \end{macrocode} % \end{macro} % \end{macro} @@ -2431,7 +2597,7 @@ % \begin{macro}{\@@_draw_literal:n, \@@_draw_literal:x} % The same as the more general literal call. % \begin{macrocode} -\cs_new_eq:NN \@@_draw_literal:n \@@_literal:n +\cs_new_eq:NN \@@_draw_literal:n \@@_literal_svg:n \cs_generate_variant:Nn \@@_draw_literal:n { x } % \end{macrocode} % \end{macro} @@ -2655,7 +2821,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\driver_draw_cap_dash:nn} +% \begin{macro}{\driver_draw_dash_pattern:nn} % \begin{macro}{\@@_draw_dash:n} % \begin{macro}{\@@_draw_dash_aux:nn} % \begin{macro}{\driver_draw_linewidth:n} @@ -2669,7 +2835,7 @@ % complexity is converting the dash array properly (doing any required % maths). % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_cap_dash:nn #1#2 +\cs_new_protected:Npn \driver_draw_dash_pattern:nn #1#2 { \use:x { @@ -2696,7 +2862,7 @@ \cs_new_protected:Npn \driver_draw_linewidth:n #1 { \@@_draw_scope:x { stroke-width=" \dim_to_decimal:n {#1} " } } \cs_new_protected:Npn \driver_draw_miterlimit:n #1 - { \@@_draw_scope:x { stroke-miterlimit=" #1 " } } + { \@@_draw_scope:x { stroke-miterlimit=" \fp_eval:n {#1} " } } \cs_new_protected:Npn \driver_draw_cap_butt: { \@@_draw_scope:n { stroke-linecap="butt" } } \cs_new_protected:Npn \driver_draw_cap_round: @@ -2813,16 +2979,16 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\driver_draw_hbox:Nnnnnnn} +% \begin{macro}{\driver_draw_box_use:Nnnnn} % No special savings can be made here: simply displace the box inside % a scope. As there is nothing to re-box, just make the box passed of % zero size. % \begin{macrocode} -\cs_new_protected:Npn \driver_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7 +\cs_new_protected:Npn \driver_draw_box_use:Nnnnn #1#2#3#4#5#6#7 { \@@_scope_begin: \driver_draw_cm:nnnn {#2} {#3} {#4} {#5} - \@@_literal:n + \@@_literal_svg:n { < g~ stroke="none"~ @@ -2833,7 +2999,7 @@ \box_set_ht:Nn #1 { 0pt } \box_set_dp:Nn #1 { 0pt } \box_use:N #1 - \@@_literal:n { </g> } + \@@_literal_svg:n { </g> } \@@_scope_end: } % \end{macrocode} |