diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx | 227 |
1 files changed, 141 insertions, 86 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx index 0ec3f3bd451..7c8e43143c5 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/09/18} +% \date{Released 2017/11/14} % % \maketitle % @@ -123,16 +123,24 @@ % % \section{Color support} % -% \begin{function}[added = 2011-09-03, updated = 2012-05-18] -% {\__driver_color_ensure_current:} +% \begin{function}[added = 2017-10-25] +% {\__driver_color_select:n, \__driver_color_select:V} % \begin{syntax} -% \cs{__driver_color_ensure_current:} +% \cs{__driver_color_select:n} \Arg{color} % \end{syntax} -% Ensures that the color used to typeset material is that which was -% set when the material was placed in a box. This function is therefore -% required inside any \enquote{color safe} box to ensure that the box may -% be inserted in a location where the foreground color has been altered, -% while preserving the color used in the box. +% Selects the \meta{color} (which is given in low-level format: a +% \meta{model} followed by a space and one or more space-separated +% axes). +% \end{function} +% +% \begin{function}[added = 2017-10-25] +% {\__driver_color_pickup:N} +% \begin{syntax} +% \cs{__driver_color_pickup:N} \meta{tl} +% \end{syntax} +% In \LaTeXe{} package mode, collects data on the current color from +% \tn{current@color} and stores it in the low-level format used by \pkg{expl3} +% in the \meta{tl}. % \end{function} % % \section{Drawing} @@ -405,7 +413,7 @@ % \__driver_draw_color_rgb_stroke:nnn % } % \begin{syntax} -% \cs{__driver_draw_color_gray:n} \Arg{red} \Arg{green} \Arg{blue} +% \cs{__driver_draw_color_rgb:nnn} \Arg{red} \Arg{green} \Arg{blue} % \end{syntax} % Sets the color for drawing to the RGB values specified, all of which are % fp expressions which should evaluate to between $0$ and $1$. The @@ -510,39 +518,74 @@ %<*dvisvgm|dvipdfmx|dvips|xdvipdfmx> % \end{macrocode} % -% \begin{macro}[aux]{\@@_color_pickup:} -% Allow for \LaTeXe{}. +% \begin{macro}[int]{\@@_color_pickup:N} +% Allow for \LaTeXe{} color. Here, the possible input values are limited: +% \texttt{dvips}-style colors can mainly be taken as-is with the exception +% spot ones (here we need a model and a tint). % \begin{macrocode} %<*package> +\cs_new_protected:Npn \@@_color_pickup:N #1 { } \AtBeginDocument { \@ifpackageloaded { color } { - \cs_new_protected:Npn \@@_color_pickup: - { \tl_set:Nx \l__color_current_tl { \current@color } } + \cs_set_protected:Npn \@@_color_pickup:N #1 + { + \exp_args:NV \tl_if_head_is_space:nTF \current@color + { + \tl_set:Nx #1 + { + spot ~ + \exp_after:wN \use:n \current@color \c_space_tl 1 + } + } + { \exp_after:wN \@@_color_pickup_aux:w \current@color \q_stop #1 } + } + \cs_new_protected:Npn \@@_color_pickup_aux:w #1 ~ #2 \q_stop #3 + { \tl_set:Nn #3 { #1 ~ #2 } } } - { \cs_new_protected:Npn \@@_color_pickup: { } } + { } } %</package> % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_color_ensure_current:} +% \begin{macro}[int]{\@@_color_select:n, \@@_color_select:V} +% \begin{macro}[aux, EXP]{\@@_convert_model:w} +% \begin{macro}[aux, EXP]{\@@_color_convert_spot:} +% \begin{macro}[aux, EXP]{\@@_color_convert_spot:w} % \begin{macro}[aux]{\@@_color_reset:} -% Directly set the color using the specials: no optimisation here. +% Mainly no conversation but a little work with \texttt{spot} colors as they +% can't have a tint level here! The easy route of just picking up +% \texttt{spot} as a model won't work as there could be additional models +% created for mixing named colors. (They would not be supported at the moment, +% but still need to be handled.) % \begin{macrocode} -\cs_new_protected:Npn \@@_color_ensure_current: +\cs_new_protected:Npn \@@_color_select:n #1 { -%<*package> - \@@_color_pickup: -%</package> - \tex_special:D { color~push~\l__color_current_tl } + \tex_special:D + { + color~push~ + \cs_if_exist_use:cF + { @@_color_convert_ \@@_convert_model:w #1 \q_stop :n } + { \use:n } + {#1} + } } +\cs_generate_variant:Nn \@@_color_select:n { V } +\cs_new:Npn \@@_convert_model:w #1 ~ #2 \q_stop {#1} +\cs_new:Npn \@@_color_convert_spot:n #1 + { \@@_color_convert_spot:w #1 \q_stop } +\cs_new:Npn \@@_color_convert_spot:w #1 ~ #2 ~ #3 \q_stop + { \c_space_tl #2 } \cs_new_protected:Npn \@@_color_reset: { \tex_special:D { color~pop } } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macrocode} %</dvisvgm|dvipdfmx|dvips|xdvipdfmx> @@ -554,7 +597,7 @@ %<*pdfmode> % \end{macrocode} % -% \begin{macro}[aux]{\@@_color_pickup:} +% \begin{macro}[aux]{\@@_color_pickup:N} % \begin{macro}[aux]{\@@_color_pickup_aux:w} % The current color in driver-dependent format: pick up the package-mode % data if available. We end up converting back and forward in this route as @@ -564,34 +607,41 @@ % \pkg{xcolor} sets it to be instructions to generate a colour % \begin{macrocode} %<*package> +\cs_new_protected:Npn \@@_color_pickup:N #1 { } \AtBeginDocument { \@ifpackageloaded { color } { - \cs_new_protected:Npn \@@_color_pickup: + \cs_set_protected:Npn \@@_color_pickup:N #1 { \exp_last_unbraced:Nx \@@_color_pickup_aux:w - { \current@color } ~ 0 ~ 0 ~ 0 \q_stop + { \current@color } ~ 0 ~ 0 ~ 0 \q_stop #1 } - \cs_new:Npn \@@_color_pickup_aux:w #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 \q_stop + \cs_new_protected:Npn \@@_color_pickup_aux:w + #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 \q_stop #7 { - \tl_set:Nx \l__color_current_tl + \str_if_eq:nnTF {#2} { g } + { \tl_set:Nn #7 { gray ~ #1 } } { - \str_if_eq:nnTF {#2} { g } - { gray ~ #1 } + \str_if_eq:nnTF {#4} { rg } + { \tl_set:Nn #7 { rgb ~ #1 ~ #2 ~ #3 } } { - \str_if_eq:nnTF {#4} { rg } - { rgb ~ #1 ~ #2 ~ #3 } - { - \str_if_eq:nnTF {#5} { k } - { cmyk ~ #1 ~ #2 ~ #3 ~ #4 } - { gray ~ #1 } - } + \str_if_eq:nnTF {#5} { k } + { \tl_set:Nn #7 { cmyk ~ #1 ~ #2 ~ #3 ~ #4 } } + { + \str_if_eq:nnTF {#2} { cs } + { + \tl_set:Nx #7 { spot ~ \use_none:n #1 ~ #5 } + } + { + \tl_set:Nn #7 { gray ~ 0 } + } + } } } } } - { \cs_new_protected:Npn \@@_color_pickup: { } } + { } } %</package> % \end{macrocode} @@ -606,43 +656,46 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}[int]{\@@_color_ensure_current:} +% \begin{macro}[int]{\@@_color_select:n, \@@_color_select:V} +% \begin{macro}[aux, EXP]{\@@_color_convert:w} % \begin{macro}[aux, EXP] % { -% \@@_color_convert:w, \@@_color_convert_gray:w, -% \@@_color_convert_cmyk:w, \@@_color_convert_rgb:w +% \@@_color_convert_gray:w , +% \@@_color_convert_cmyk:w , +% \@@_color_convert_rgb:w , +% \@@_color_convert_spot:w % } % \begin{macro}[aux]{\@@_color_reset:} % There is a dedicated primitive/primitive interface for setting colors. % As with scoping, this approach is not suitable for cached operations. -% Since we are using the \texttt{dvips} format to store color, there is a -% bit of work to correctly place it in the output. +% Most of the conversions are trivial but the need to cover spot colors +% makes life slightly more interesting. % \begin{macrocode} -\cs_new_protected:Npx \@@_color_ensure_current: +\cs_new_protected:Npx \@@_color_select:n #1 { -%<*package> - \exp_not:N \@@_color_pickup: -%</package> \cs_if_exist:NTF \luatex_pdfextension:D { \luatex_pdfextension:D colorstack } { \pdftex_pdfcolorstack:D } \exp_not:N \l_@@_color_stack_int push { - \exp_not:N \exp_after:wN \exp_not:N \@@_color_convert:w - \exp_not:N \l__color_current_tl - \c_space_tl 0 ~ 0 ~ 0 + #1 \exp_not:N \q_stop } } -\cs_new:Npn \@@_color_convert:w #1 ~ - { \use:c { @@_color_convert_ #1 :w } } -\cs_new:Npn \@@_color_convert_gray:w #1 ~ #2 \q_stop +\cs_generate_variant:Nn \@@_color_select:n { V } +\cs_new:Npn \@@_color_convert:w #1 ~ #2 \q_stop + { \use:c { @@_color_convert_ #1 :w } #2 \q_stop } +\cs_new:Npn \@@_color_convert_gray:w #1 \q_stop { #1 ~ g ~ #1 ~ G } -\cs_new:Npn \@@_color_convert_cmyk:w #1 ~ #2 ~ #3 ~ #4 ~#5 \q_stop - { #1 ~ #2 ~ #3 ~ #4 ~ k ~ #1 ~ #2 ~ #3 ~ #4 ~ K } -\cs_new:Npn \@@_color_convert_rgb:w #1 ~ #2 ~ #3 ~ #4 \q_stop - { #1 ~ #2 ~ #3 ~ rg ~ #1 ~ #2 ~ #3 ~ RG } +\cs_new:Npn \@@_color_convert_cmyk:w #1 \q_stop + { #1 ~ k ~ #1 ~ K } +\cs_new:Npn \@@_color_convert_rgb:w #1 \q_stop + { #1 ~ rg ~ #1 ~ RG } +\cs_new:Npn \@@_color_convert_spot:w #1 ~ #2 \q_stop + { + /#1 ~ cs ~ /#1 ~ CS ~ #2 ~ sc ~ #2 ~ SC + } \cs_new_protected:Npx \@@_color_reset: { \cs_if_exist:NTF \luatex_pdfextension:D @@ -654,6 +707,7 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macrocode} %</pdfmode> @@ -766,6 +820,7 @@ \box_use:N #1 \@@_scope_end: } +% \end{macrocode} % \end{macro} % % \begin{macro}{\@@_box_use_scale:Nnn} @@ -813,7 +868,7 @@ % 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). -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_literal:n #1 { \tex_special:D { ps:: ~ #1 } } \cs_generate_variant:Nn \@@_draw_literal:n { x } @@ -827,7 +882,7 @@ % |@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. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_begin: { \tex_special:D { ps::[begin] } @@ -847,7 +902,7 @@ % \begin{macro}[int]{\@@_draw_scope_begin:, \@@_draw_scope_end:} % Scope here may need to contain saved definitions, so the entire memory % rather than just the graphic state has to be sent to the stack. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_scope_begin: { \@@_draw_literal:n { save } } \cs_new_protected:Npn \@@_draw_scope_end: @@ -864,7 +919,7 @@ % values are forced to literals before any possible caching. There is % no native rectangular path command (without also clipping, filling or % stroking), so that task is done using a small amount of PostScript. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_moveto:nn #1#2 { \@@_draw_literal:x @@ -902,7 +957,7 @@ % \begin{macro}[int]{\@@_draw_evenodd_rule:, \@@_draw_nonzero_rule:} % \begin{variable}[aux]{\g_@@_draw_eor_bool} % The even-odd rule here can be implemented as a simply switch. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_evenodd_rule: { \bool_gset_true:N \g_@@_draw_eor_bool } \cs_new_protected:Npn \@@_draw_nonzero_rule: @@ -932,7 +987,7 @@ % the color set up functions. For clipping, the required ordering is achieved % using a \TeX{} switch. All of the operations end with a new path instruction % as they do not terminate (again in contrast to PDF). -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_closepath: { \@@_draw_literal:n { closepath } } \cs_new_protected:Npn \@@_draw_stroke: @@ -1030,7 +1085,7 @@ % } % Converting paths to output is again a case of mapping directly to % PostScript operations. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_dash:nn #1#2 { \@@_draw_literal:x @@ -1092,7 +1147,7 @@ % respect scoping, the data needs to be stored at the PostScript level. % We cannot undefine (local) fill/stroke colors once set up but we can % set them blank to improve performance slightly. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_color_reset: { \@@_draw_literal:n { currentdic~/l3fc~known~{ /l3fc~ { } ~def }~if } @@ -1186,7 +1241,7 @@ % The first four arguments here are floats (the affine matrix), the last % two are a displacement vector. Once again, force evaluation to allow for % caching. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_transformcm:nnnnnn #1#2#3#4#5#6 { \@@_draw_literal:x @@ -1211,7 +1266,7 @@ % 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. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7 { \@@_scope_begin: @@ -1878,7 +1933,7 @@ % % \begin{macro}[aux]{\@@_draw_literal:n, \@@_draw_literal:x} % Pass data through using a dedicated interface. -% \begin{macrocode} +% \begin{macrocode} \cs_new_eq:NN \@@_draw_literal:n \@@_literal:n \cs_generate_variant:Nn \@@_draw_literal:n { x } % \end{macrocode} @@ -1886,7 +1941,7 @@ % % \begin{macro}[int]{\@@_draw_begin:, \@@_draw_end:} % No special requirements here, so simply set up a drawing scope. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_begin: { \@@_draw_scope_begin: } \cs_new_protected:Npn \@@_draw_end: @@ -1897,7 +1952,7 @@ % \begin{macro}[int]{\@@_draw_scope_begin:, \@@_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. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_scope_begin: { \@@_draw_literal:n { q } } \cs_new_protected:Npn \@@_draw_scope_end: @@ -1912,7 +1967,7 @@ % 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. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_moveto:nn #1#2 { \@@_draw_literal:x @@ -1950,7 +2005,7 @@ % \begin{macro}[int]{\@@_draw_evenodd_rule:, \@@_draw_nonzero_rule:} % \begin{variable}[int]{\g_@@_draw_eor_bool} % The even-odd rule here can be implemented as a simply switch. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_evenodd_rule: { \bool_gset_true:N \g_@@_draw_eor_bool } \cs_new_protected:Npn \@@_draw_nonzero_rule: @@ -1972,7 +2027,7 @@ % } % Converting paths to output is again a case of mapping directly to % PDF operations. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_closepath: { \@@_draw_literal:n { h } } \cs_new_protected:Npn \@@_draw_stroke: @@ -2010,7 +2065,7 @@ % } % Converting paths to output is again a case of mapping directly to % PDF operations. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_dash:nn #1#2 { \@@_draw_literal:x @@ -2072,7 +2127,7 @@ % \begin{macro}[aux]{\@@_draw_color_rgb_aux:nnn} % Yet more fast conversion, all using the FPU to allow for expressions % in numerical input. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_color_cmyk:nnnn #1#2#3#4 { \use:x @@ -2157,7 +2212,7 @@ % The first four arguments here are floats (the affine matrix), the last % two are a displacement vector. Once again, force evaluation to allow for % caching. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_transformcm:nnnnnn #1#2#3#4#5#6 { \@@_draw_literal:x @@ -2179,7 +2234,7 @@ % skew/scaling component needs to be done using the matrix operation. As this % operation can never be cached, the scope is set directly not using the % \texttt{draw} version. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7 { \hbox_set:Nn \l_@@_tmp_box @@ -2413,7 +2468,7 @@ % % \begin{macro}[aux]{\@@_draw_literal:n, \@@_draw_literal:x} % The same as the more general literal call. -% \begin{macrocode} +% \begin{macrocode} \cs_new_eq:NN \@@_draw_literal:n \@@_literal:n \cs_generate_variant:Nn \@@_draw_literal:n { x } % \end{macrocode} @@ -2422,7 +2477,7 @@ % \begin{macro}[int]{\@@_draw_begin:, \@@_draw_end:} % A drawing needs to be set up such that the co-ordinate system is % translated. That is done inside a scope, which as described below -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_begin: { \@@_draw_scope_begin: @@ -2443,7 +2498,7 @@ % each graphics scope we use a global variable to do the work, with a group % used to save the value between scopes. The result is that no direct action % is needed when creating a scope. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_scope_begin: { \int_set_eq:NN @@ -2486,7 +2541,7 @@ % storage routine, which adds spaces as required. Since paths should % be fully expanded there is no need to worry about the internal % \texttt{x}-type expansion. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_moveto:nn #1#2 { \@@_draw_add_to_path:n @@ -2537,7 +2592,7 @@ % % \begin{macro}[int]{\@@_draw_evenodd_rule:, \@@_draw_nonzero_rule:} % The fill rules here have to be handled as scopes. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_evenodd_rule: { \@@_draw_scope:n { fill-rule="evenodd" } } \cs_new_protected:Npn \@@_draw_nonzero_rule: @@ -2563,7 +2618,7 @@ % auxiliary which deals with the bits and pieces. Clipping paths are reused % for path drawing: not essential but avoids constructing them twice. % Discarding a path needs a separate function as it's not quite the same. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_closepath: { \@@_draw_add_to_path:n { Z } } \cs_new_protected:Npn \@@_draw_path:n #1 @@ -2651,7 +2706,7 @@ % All of these ideas are properties of scopes in SVG. The only slight % complexity is converting the dash array properly (doing any required % maths). -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_dash:nn #1#2 { \use:x @@ -2721,7 +2776,7 @@ % SVG only works with RGB colors, so there is some conversion to % do. The values also need to be given as percentages, which means a % little more maths. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_color_cmyk_aux:NNnnnnn #1#2#3#4#5#6 { \use:x @@ -2814,7 +2869,7 @@ % The first four arguments here are floats (the affine matrix), the last % two are a displacement vector. Once again, force evaluation to allow for % caching. -% \begin{macrocode} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_transformcm:nnnnnn #1#2#3#4#5#6 { \@@_draw_scope:x @@ -2837,7 +2892,7 @@ % 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} +% \begin{macrocode} \cs_new_protected:Npn \@@_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7 { \@@_scope_begin: |