diff options
Diffstat (limited to 'macros/latex/contrib/l3backend/l3backend-color.dtx')
-rw-r--r-- | macros/latex/contrib/l3backend/l3backend-color.dtx | 1356 |
1 files changed, 0 insertions, 1356 deletions
diff --git a/macros/latex/contrib/l3backend/l3backend-color.dtx b/macros/latex/contrib/l3backend/l3backend-color.dtx deleted file mode 100644 index eaa89add8c..0000000000 --- a/macros/latex/contrib/l3backend/l3backend-color.dtx +++ /dev/null @@ -1,1356 +0,0 @@ -% \iffalse meta-comment -% -%% File: l3backend-color.dtx -% -% Copyright (C) 2019-2024 The LaTeX Project -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file -% -% https://www.latex-project.org/lppl.txt -% -% This file is part of the "l3backend bundle" (The Work in LPPL) -% and all files in that bundle must be distributed together. -% -% ----------------------------------------------------------------------- -% -% The development version of the bundle can be found at -% -% https://github.com/latex3/latex3 -% -% for those people who are interested. -% -%<*driver> -\documentclass[full,kernel]{l3doc} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -%</driver> -% \fi -% -% \title{^^A -% The \pkg{l3backend-color} module\\ Backend color support^^A -% } -% -% \author{^^A -% The \LaTeX{} Project\thanks -% {^^A -% E-mail: -% \href{mailto:latex-team@latex-project.org} -% {latex-team@latex-project.org}^^A -% }^^A -% } -% -% \date{Released 2024-03-14} -% -% \maketitle -% -% \begin{documentation} -% -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3backend-color} implementation} -% -% \begin{macrocode} -%<*package> -%<@@=color> -% \end{macrocode} -% -% Color support is split into parts: collecting data from \LaTeXe{}, the color -% stack, general color, separations, and color for drawings. We have different -% approaches in each backend, and have some choices to make about -% \texttt{dvipdfmx}/\XeTeX{} in particular. Whilst it is in some ways -% convenient to use the same approach in multiple backends, the fact that -% \texttt{dvipdfmx}/\XeTeX{} is PDF-based means it (largely) sticks closer to -% direct PDF output. -% -% \subsection{The color stack} -% -% For PDF-based engines, we have a color stack available inside the specials. -% This is used for concepts beyond color itself: it is needed to manage the -% graphics state generally. Although \texttt{dvipdfmx}/\XeTeX{} have multiple -% color stacks in recent releases, the way these interact with the original -% single stack and with other graphic state operations means that currently it -% is not feasible to use the multiple stacks. -% -% \subsubsection{Common code} -% -% \begin{macrocode} -%<*luatex|pdftex> -% \end{macrocode} -% -% \begin{variable}{\l_@@_backend_stack_int} -% For tracking which stack is in use where multiple stacks are used: -% currently just \pdfTeX{}/\LuaTeX{} but at some future stage may also cover -% \texttt{dvipdfmx}/\XeTeX{}. -% \begin{macrocode} -\int_new:N \l_@@_backend_stack_int -% \end{macrocode} -% \end{variable} -% -% \begin{macrocode} -%</luatex|pdftex> -% \end{macrocode} -% -% \subsubsection{\LuaTeX and \pdfTeX{}} -% -% \begin{macrocode} -%<*luatex|pdftex> -% \end{macrocode} -% -% \begin{macro}{\__kernel_color_backend_stack_init:Nnn} -% \begin{macrocode} -\cs_new_protected:Npn \__kernel_color_backend_stack_init:Nnn #1#2#3 - { - \int_const:Nn #1 - { -%<*luatex> - \tex_pdffeedback:D colorstackinit ~ -%</luatex> -%<*pdftex> - \tex_pdfcolorstackinit:D -%</pdftex> - \tl_if_blank:nF {#2} { #2 ~ } - {#3} - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\__kernel_color_backend_stack_push:nn} -% \begin{macro}{\__kernel_color_backend_stack_pop:n} -% \begin{macrocode} -\cs_new_protected:Npn \__kernel_color_backend_stack_push:nn #1#2 - { -%<*luatex> - \tex_pdfextension:D colorstack ~ -%</luatex> -%<*pdftex> - \tex_pdfcolorstack:D -%</pdftex> - \int_eval:n {#1} ~ push ~ {#2} - } -\cs_new_protected:Npn \__kernel_color_backend_stack_pop:n #1 - { -%<*luatex> - \tex_pdfextension:D colorstack ~ -%</luatex> -%<*pdftex> - \tex_pdfcolorstack:D -%</pdftex> - \int_eval:n {#1} ~ pop \scan_stop: - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macrocode} -%</luatex|pdftex> -% \end{macrocode} -% -% \subsection{General color} -% -% \subsubsection{\texttt{dvips}-style} -% -% \begin{macrocode} -%<*dvips|dvisvgm> -% \end{macrocode} -% -% \begin{macro} -% { -% \@@_backend_select_cmyk:n , -% \@@_backend_select_gray:n , -% \@@_backend_select_named:n , -% \@@_backend_select_rgb:n , -% \@@_backend_select:n -% } -% \begin{macro}{\@@_backend_reset:} -% Push the data to the stack. In the case of \texttt{dvips} also saves the -% drawing color in raw PostScript. The |spot| model is for handling data -% in classical format. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_select_cmyk:n #1 - { \@@_backend_select:n { cmyk ~ #1 } } -\cs_new_protected:Npn \@@_backend_select_gray:n #1 - { \@@_backend_select:n { gray ~ #1 } } -\cs_new_protected:Npn \@@_backend_select_named:n #1 - { \@@_backend_select:n { ~ #1 } } -\cs_new_protected:Npn \@@_backend_select_rgb:n #1 - { \@@_backend_select:n { rgb ~ #1 } } -\cs_new_protected:Npn \@@_backend_select:n #1 - { - \__kernel_backend_literal:n { color~push~ #1 } -%<*dvips> - \__kernel_backend_postscript:n { /color.sc ~ { } ~ def } -%</dvips> - } -\cs_new_protected:Npn \@@_backend_reset: - { \__kernel_backend_literal:n { color~pop } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macrocode} -%</dvips|dvisvgm> -% \end{macrocode} -% -% \subsubsection{\LuaTeX{} and \pdfTeX{}} -% -% \begin{macrocode} -%<*luatex|pdftex> -% \end{macrocode} -% -% \begin{variable}{\l_@@_backend_fill_tl, \l_@@_backend_stroke_tl} -% \begin{macrocode} -\tl_new:N \l_@@_backend_fill_tl -\tl_new:N \l_@@_backend_stroke_tl -\tl_set:Nn \l_@@_backend_fill_tl { 0 ~ g } -\tl_set:Nn \l_@@_backend_stroke_tl { 0 ~ G } -% \end{macrocode} -% \end{variable} -% -% \begin{macro} -% { -% \@@_backend_select_cmyk:n , -% \@@_backend_select_gray:n , -% \@@_backend_select_rgb:n -% } -% \begin{macro}{\@@_backend_select:nn} -% \begin{macro}{\@@_backend_reset:} -% Store the values then pass to the stack. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_select_cmyk:n #1 - { \@@_backend_select:nn { #1 ~ k } { #1 ~ K } } -\cs_new_protected:Npn \@@_backend_select_gray:n #1 - { \@@_backend_select:nn { #1 ~ g } { #1 ~ G } } -\cs_new_protected:Npn \@@_backend_select_rgb:n #1 - { \@@_backend_select:nn { #1 ~ rg } { #1 ~ RG } } -\cs_new_protected:Npn \@@_backend_select:nn #1#2 - { - \tl_set:Nn \l_@@_backend_fill_tl {#1} - \tl_set:Nn \l_@@_backend_stroke_tl {#2} - \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int { #1 ~ #2 } - } -\cs_new_protected:Npn \@@_backend_reset: - { \__kernel_color_backend_stack_pop:n \l_@@_backend_stack_int } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macrocode} -%</luatex|pdftex> -% \end{macrocode} -% -% \subsubsection{\texttt{dvipmdfx}/\XeTeX{}} -% -% These backends have the most possible approaches: it recognises both -% \texttt{dvips}-based color specials and its own format, plus one can -% include PDF statements directly. Recent releases also have a color stack -% approach similar to \pdfTeX{}. Of the stack methods, the dedicated -% the most versatile is the latter as it can cover all of the use cases -% we have. However, at present this interacts problematically with any color -% on the original stack. We therefore stick to a single-stack approach here. -% -% \begin{macrocode} -%<*dvipdfmx|xetex> -% \end{macrocode} -% -% \begin{macro} -% { -% \@@_backend_select:n , -% \@@_backend_select_cmyk:n , -% \@@_backend_select_gray:n , -% \@@_backend_select_rgb:n -% } -% \begin{macro}{\@@_backend_reset:} -% Using the single stack is relatively easy as there is only one route. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_select:n #1 - { \__kernel_backend_literal:n { pdf : bc ~ [ #1 ] } } -\cs_new_eq:NN \@@_backend_select_cmyk:n \@@_backend_select:n -\cs_new_eq:NN \@@_backend_select_gray:n \@@_backend_select:n -\cs_new_eq:NN \@@_backend_select_rgb:n \@@_backend_select:n -\cs_new_protected:Npn \@@_backend_reset: - { \__kernel_backend_literal:n { pdf : ec } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_backend_select_named:n} -% For classical named colors, the only value we should get is |Black|. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_select_named:n #1 - { - \str_if_eq:nnTF {#1} { Black } - { \@@_backend_select_gray:n { 0 } } - { \msg_error:nnn { color } { unknown-named-color } {#1} } - } -\msg_new:nnn { color } { unknown-named-color } - { Named~color~'#1'~is~not~known. } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</dvipdfmx|xetex> -% \end{macrocode} -% -% \subsection{Separations} -% -% Here, life gets interesting and we need essentially one approach per -% backend. -% -% \begin{macrocode} -%<*dvipdfmx|luatex|pdftex|xetex|dvips> -% \end{macrocode} -% -% But we start with some functionality needed for both PostScript and -% PDF based backends. -% -% \begin{variable}{\g_@@_backend_colorant_prop} -% \begin{macrocode} -\prop_new:N \g_@@_backend_colorant_prop -% \end{macrocode} -% \end{variable} -% -% \begin{macro}[EXP]{\@@_backend_devicen_colorants:n} -% \begin{macro}[EXP]{\@@_backend_devicen_colorants:w} -% \begin{macrocode} -\cs_new:Npe \@@_backend_devicen_colorants:n #1 - { - \exp_not:N \tl_if_blank:nF {#1} - { - \c_space_tl - << ~ - /Colorants ~ - << ~ - \exp_not:N \@@_backend_devicen_colorants:w #1 ~ - \exp_not:N \q_recursion_tail \c_space_tl - \exp_not:N \q_recursion_stop - >> ~ - >> - } - } -\cs_new:Npn \@@_backend_devicen_colorants:w #1 ~ - { - \quark_if_recursion_tail_stop:n {#1} - \prop_if_in:NnT \g_@@_backend_colorant_prop {#1} - { - #1 ~ - \prop_item:Nn \g_@@_backend_colorant_prop {#1} ~ - } - \@@_backend_devicen_colorants:w - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macrocode} -%</dvipdfmx|luatex|pdftex|xetex|dvips> -% \end{macrocode} -% -% \begin{macrocode} -%<*dvips> -% \end{macrocode} -% -% \begin{macro}{\@@_backend_select_separation:nn, \@@_backend_select_devicen:nn} -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2 - { \@@_backend_select:n { separation ~ #1 ~ #2 } } -\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_select_iccbased:nn} -% No support. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_select_iccbased:nn #1#2 { } -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% { -% \@@_backend_separation_init:nnnnn, -% \@@_backend_separation_init:neenn -% } -% \begin{macro} -% {\@@_backend_separation_init_aux:nnnnnn} -% \begin{macro}[EXP] -% { -% \@@_backend_separation_init_/DeviceCMYK:nnn , -% \@@_backend_separation_init_/DeviceGray:nnn , -% \@@_backend_separation_init_/DeviceRGB:nnn -% } -% \begin{macro}[EXP]{\@@_backend_separation_init_Device:Nn} -% \begin{macro}[EXP]{\@@_backend_separation_init:nnn} -% \begin{macro}[EXP]{\@@_backend_separation_init_count:n} -% \begin{macro}[EXP]{\@@_backend_separation_init_count:w} -% \begin{macro}[EXP]{\@@_backend_separation_init:nnnn} -% \begin{macro}[EXP]{\@@_backend_separation_init:w} -% \begin{macro}[EXP]{\@@_backend_separation_init:n} -% \begin{macro}[EXP]{\@@_backend_separation_init:nw} -% \begin{macro}{\@@_backend_separation_init_CIELAB:nnn} -% Initialising here means creating a small header set up plus massaging -% some data. This comes about as we have to deal with PDF-focussed data, -% which makes most sense \enquote{higher-up}. The approach is based on -% ideas from \url{https://tex.stackexchange.com/q/560093} plus using -% the PostScript manual for other aspects. -% \begin{macrocode} -\cs_new_protected:Npe \@@_backend_separation_init:nnnnn #1#2#3#4#5 - { - \bool_if:NT \g__kernel_backend_header_bool - { - \exp_not:N \exp_args:Ne \__kernel_backend_first_shipout:n - { - \exp_not:N \@@_backend_separation_init_aux:nnnnnn - { \exp_not:N \int_use:N \g_@@_model_int } - {#1} {#2} {#3} {#4} {#5} - } - \prop_gput:Nee \exp_not:N \g_@@_backend_colorant_prop - { / \exp_not:N \str_convert_pdfname:n {#1} } - { - << ~ - /setcolorspace ~ {} ~ - >> ~ begin ~ - color \exp_not:N \int_use:N \g_@@_model_int \c_space_tl - end - } - } - } -\cs_generate_variant:Nn \@@_backend_separation_init:nnnnn { nee } -\cs_new_protected:Npn \@@_backend_separation_init_aux:nnnnnn #1#2#3#4#5#6 - { - \__kernel_backend_literal:e - { - ! - TeXDict ~ begin ~ - /color #1 - { - [ ~ - /Separation ~ ( \str_convert_pdfname:n {#2} ) ~ - [ ~ #3 ~ ] ~ - { - \cs_if_exist_use:cF { @@_backend_separation_init_ #3 :nnn } - { \@@_backend_separation_init:nnn } - {#4} {#5} {#6} - } - ] ~ setcolorspace - } ~ def ~ - end - } - } -\cs_new:cpn { @@_backend_separation_init_ /DeviceCMYK :nnn } #1#2#3 - { \@@_backend_separation_init_Device:Nn 4 {#3} } -\cs_new:cpn { @@_backend_separation_init_ /DeviceGray :nnn } #1#2#3 - { \@@_backend_separation_init_Device:Nn 1 {#3} } -\cs_new:cpn { @@_backend_separation_init_ /DeviceRGB :nnn } #1#2#3 - { \@@_backend_separation_init_Device:Nn 2 {#3} } -\cs_new:Npn \@@_backend_separation_init_Device:Nn #1#2 - { - #2 ~ - \prg_replicate:nn {#1} - { #1 ~ index ~ mul ~ #1 ~ 1 ~ roll ~ } - \int_eval:n { #1 + 1 } ~ -1 ~ roll ~ pop - } -% \end{macrocode} -% For the generic case, we cannot use |/FunctionType 2| unfortunately, so -% we have to code that idea up in PostScript. Here, we will therefore assume -% that a range is \emph{always} given. First, we count values in each argument: -% at the backend level, we can assume there are always well-behaved with -% spaces present. -% \begin{macrocode} -\cs_new:Npn \@@_backend_separation_init:nnn #1#2#3 - { - \exp_args:Ne \@@_backend_separation_init:nnnn - { \@@_backend_separation_init_count:n {#2} } - {#1} {#2} {#3} - } -\cs_new:Npn \@@_backend_separation_init_count:n #1 - { \int_eval:n { 0 \@@_backend_separation_init_count:w #1 ~ \s_@@_stop } } -\cs_new:Npn \@@_backend_separation_init_count:w #1 ~ #2 \s_@@_stop - { - +1 - \tl_if_blank:nF {#2} - { \@@_backend_separation_init_count:w #2 \s_@@_stop } - } -% \end{macrocode} -% Now we implement the algorithm. In the terms in the PostScript manual, -% we have $\mathbf{N} = 1$ and $\mathbf{Domain} = [0~1]$, with -% $\mathbf{Range}$ as |#2|, $\mathbf{C0}$ as |#3| and $\mathbf{C1}$ -% as |#4|, with the number of output components in |#1|. So all we have -% to do is implement $y_{i} = \mathbf{C0}_{i} + x(\mathbf{C1}_{i} - -% \mathbf{C0}_{i})$ with lots of stack manipulation, then check the -% ranges. That's done by adding everything to the stack first, then using -% the fact we know all of the offsets. As manipulating the stack is tricky, -% we start by re-formatting the $\mathbf{C0}$ and $\mathbf{C1}$ arrays to -% be interleaved, and add a \texttt{0} to each pair: this is used -% to keep the stack of constant length while we are doing the first pass of -% mathematics. We then working through that list, calculating from the -% last to the first value before tidying up by removing all of the input -% values. We do that by first copying all of the final $y$ values to the -% end of the stack, then rolling everything so we can pop the now-unneeded -% material. -% \begin{macrocode} -\cs_new:Npn \@@_backend_separation_init:nnnn #1#2#3#4 - { - \@@_backend_separation_init:w #3 ~ \s_@@_stop #4 ~ \s_@@_stop - \prg_replicate:nn {#1} - { - pop ~ 1 ~ index ~ neg ~ 1 ~ index ~ add ~ - \int_eval:n { 3 * #1 } ~ index ~ mul ~ - 2 ~ index ~ add ~ - \int_eval:n { 3 * #1 } ~ #1 ~ roll ~ - } - \int_step_function:nnnN {#1} { -1 } { 1 } - \@@_backend_separation_init:n - \int_eval:n { 4 * #1 + 1 } ~ #1 ~ roll ~ - \prg_replicate:nn { 3 * #1 + 1 } { pop ~ } - \tl_if_blank:nF {#2} - { \@@_backend_separation_init:nw {#1} #2 ~ \s_@@_stop } - } -\cs_new:Npn \@@_backend_separation_init:w - #1 ~ #2 \s_@@_stop #3 ~ #4 \s_@@_stop - { - #1 ~ #3 ~ 0 ~ - \tl_if_blank:nF {#2} - { \@@_backend_separation_init:w #2 \s_@@_stop #4 \s_@@_stop } - } -\cs_new:Npn \@@_backend_separation_init:n #1 - { \int_eval:n { #1 * 2 } ~ index ~ } -% \end{macrocode} -% Finally, we deal with the range limit if required. This is handled -% by splitting the range into pairs. It's then just a question of doing -% the comparisons, this time dropping everything except the desired -% result. -% \begin{macrocode} -\cs_new:Npn \@@_backend_separation_init:nw #1#2 ~ #3 ~ #4 \s_@@_stop - { - #2 ~ #3 ~ - 2 ~ index ~ 2 ~ index ~ lt ~ - { ~ pop ~ exch ~ pop ~ } ~ - { ~ - 2 ~ index ~ 1 ~ index ~ gt ~ - { ~ exch ~ pop ~ exch ~ pop ~ } ~ - { ~ pop ~ pop ~ } ~ - ifelse ~ - } - ifelse ~ - #1 ~ 1 ~ roll ~ - \tl_if_blank:nF {#4} - { \@@_backend_separation_init:nw {#1} #4 \s_@@_stop } - } -% \end{macrocode} -% CIELAB support uses the detail from the PostScript reference, page 227; -% other than that block of PostScript, this is the same as for PDF-based -% routes. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3 - { - \@@_backend_separation_init:neenn - {#2} - { - /CIEBasedABC ~ - << ~ - /RangeABC ~ [ ~ \c_@@_model_range_CIELAB_tl \c_space_tl ] ~ - /DecodeABC ~ - [ ~ - { ~ 16 ~ add ~ 116 ~ div ~ } ~ bind ~ - { ~ 500 ~ div ~ } ~ bind ~ - { ~ 200 ~ div ~ } ~ bind ~ - ] ~ - /MatrixABC ~ [ ~ 1 ~ 1 ~ 1 ~ 1 ~ 0 ~ 0 ~ 0 ~ 0 ~ -1 ~ ] ~ - /DecodeLMN ~ - [ ~ - { ~ - dup ~ 6 ~ 29 ~ div ~ ge ~ - { ~ dup ~ dup ~ mul ~ mul ~ ~ } ~ - { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~ - ifelse ~ - 0.9505 ~ mul ~ - } ~ bind ~ - { ~ - dup ~ 6 ~ 29 ~ div ~ ge ~ - { ~ dup ~ dup ~ mul ~ mul ~ } ~ - { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~ - ifelse ~ - } ~ bind ~ - { ~ - dup ~ 6 ~ 29 ~ div ~ ge ~ - { ~ dup ~ dup ~ mul ~ mul ~ } ~ - { ~ 4 ~ 29 ~ div ~ sub ~ 108 ~ 841 ~ div ~ mul ~ } ~ - ifelse ~ - 1.0890 ~ mul ~ - } ~ bind - ] ~ - /WhitePoint ~ - [ ~ \tl_use:c { c_@@_model_whitepoint_CIELAB_ #1 _tl } ~ ] ~ - >> - } - { \c_@@_model_range_CIELAB_tl } - { 100 ~ 0 ~ 0 } - {#3} - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_backend_devicen_init:nnn} -% Trivial as almost all of the work occurs in the shared code. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 - { - \__kernel_backend_literal:e - { - ! - TeXDict ~ begin ~ - /color \int_use:N \g_@@_model_int - { - [ ~ - /DeviceN ~ - [ ~ #1 ~ ] ~ - #2 ~ - { ~ #3 ~ } ~ - \@@_backend_devicen_colorants:n {#1} - ] ~ setcolorspace - } ~ def ~ - end - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_iccbased_init:nnn} -% No support at present. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_iccbased_init:nnn #1#2#3 { } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</dvips> -% \end{macrocode} -% -% \begin{macrocode} -%<*dvisvgm> -% \end{macrocode} -% -% \begin{macro} -% { -% \@@_backend_select_separation:nn, -% \@@_backend_select_devicen:nn -% } -% No support at present. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2 { } -\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% {\@@_backend_separation_init:nnnnn, \@@_backend_separation_init_CIELAB:nnn} -% No support at present. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5 { } -\cs_new_protected:Npn \@@_backend_separation_init_CIELAB:nnnnnn #1#2#3 { } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_select_iccbased:nn} -% As detailed in \url{https://www.w3.org/TR/css-color-4/#at-profile}, -% we can apply a color profile using CSS. As we have a local file, we use -% a relative URL. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_select_iccbased:nn #1#2 - { - \__kernel_backend_literal_svg:e - { - <style> - @color-profile ~ - \str_if_eq:nnTF {#2} { cmyk } - { device-cmyk } - { --color \int_use:N \g_@@_model_int } - \c_space_tl - { - src:("#1") - } - </style> - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</dvisvgm> -% \end{macrocode} -% -% \begin{macrocode} -%<*dvipdfmx|luatex|pdftex|xetex> -% \end{macrocode} -% -% \begin{macro} -% { -% \@@_backend_select_separation:nn, -% \@@_backend_select_devicen:nn , -% \@@_backend_select_iccbased:nn -% } -% \begin{macrocode} -%<*dvipdfmx|xetex> -\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2 - { \__kernel_backend_literal:e { pdf : bc ~ \pdf_object_ref:n {#1} ~ [ #2 ] } } -%</dvipdfmx|xetex> -%<*luatex|pdftex> -\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2 - { \@@_backend_select:nn { /#1 ~ cs ~ #2 ~ scn } { /#1 ~ CS ~ #2 ~ SCN } } -%</luatex|pdftex> -\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn -\cs_new_eq:NN \@@_backend_select_iccbased:nn \@@_backend_select_separation:nn -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_init_resource:n} -% Resource initiation comes up a few times. For \texttt{dvipdfmx}/\XeTeX{}, -% we skip this as at present it's handled by the backend. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_init_resource:n #1 - { -%<*luatex|pdftex> - \bool_lazy_and:nnT - { \cs_if_exist_p:N \pdfmanagement_if_active_p: } - { \pdfmanagement_if_active_p: } - { - \use:e - { - \pdfmanagement_add:nnn - { Page / Resources / ColorSpace } - { #1 } - { \pdf_object_ref_last: } - } - } -%</luatex|pdftex> - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_separation_init:nnnnn} -% \begin{macro}{\@@_backend_separation_init:nn} -% \begin{macro}{\@@_backend_separation_init_CIELAB:nnn} -% Initialising the PDF structures needs two parts: creating an object -% containing the \enquote{real} name of the Separation, then adding a reference -% to that to each page. We use a separate object for the tint transformation -% following the model in the PDF reference. The object here for the color -% needs to be named as that way it's accessible to -% \texttt{dvipdfmx}/\XeTeX{}. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5 - { - \pdf_object_unnamed_write:ne { dict } - { - /FunctionType ~ 2 - /Domain ~ [0 ~ 1] - \tl_if_blank:nF {#3} { /Range ~ [#3] } - /C0 ~ [#4] ~ - /C1 ~ [#5] /N ~ 1 - } - \exp_args:Ne \@@_backend_separation_init:nn - { \str_convert_pdfname:n {#1} } {#2} - \@@_backend_init_resource:n { color \int_use:N \g_@@_model_int } - } -\cs_new_protected:Npn \@@_backend_separation_init:nn #1#2 - { - \use:e - { - \pdf_object_new:n { color \int_use:N \g_@@_model_int } - \pdf_object_write:nnn { color \int_use:N \g_@@_model_int } { array } - { /Separation /#1 ~ #2 ~ \pdf_object_ref_last: } - } - \prop_gput:Nne \g_@@_backend_colorant_prop { /#1 } - { \pdf_object_ref_last: } - } -% \end{macrocode} -% For CIELAB colors, we need one object per document for the illuminant, -% plus initialisation of the color space referencing that object. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3 - { - \pdf_object_if_exist:nF { @@_illuminant_CIELAB_ #1 } - { - \pdf_object_new:n { @@_illuminant_CIELAB_ #1 } - \pdf_object_write:nne { @@_illuminant_CIELAB_ #1 } { array } - { - /Lab ~ - << - /WhitePoint ~ - [ \tl_use:c { c_@@_model_whitepoint_CIELAB_ #1 _tl } ] - /Range ~ [ \c_@@_model_range_CIELAB_tl ] - >> - } - } - \@@_backend_separation_init:nnnnn - {#2} - { \pdf_object_ref:n { @@_illuminant_CIELAB_ #1 } } - { \c_@@_model_range_CIELAB_tl } - { 100 ~ 0 ~ 0 } - {#3} - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_backend_devicen_init:nnn} -% \begin{macro}[EXP]{\@@_backend_devicen_init:w} -% Similar to the Separations case, but with an arbitrary function for -% the alternative space work. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 - { - \pdf_object_unnamed_write:ne { stream } - { - { - /FunctionType ~ 4 ~ - /Domain ~ - [ ~ - \prg_replicate:nn - { 0 \@@_backend_devicen_init:w #1 ~ \s_@@_stop } - { 0 ~ 1 ~ } - ] ~ - /Range ~ - [ ~ - \str_case:nn {#2} - { - { /DeviceCMYK } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 } - { /DeviceGray } { 0 ~ 1 } - { /DeviceRGB } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 } - } ~ - ] - } - { {#3} } - } - \use:e - { - \pdf_object_new:n { color \int_use:N \g_@@_model_int } - \pdf_object_write:nnn { color \int_use:N \g_@@_model_int } { array } - { - /DeviceN ~ - [ ~ #1 ~ ] ~ - #2 ~ - \pdf_object_ref_last: - \@@_backend_devicen_colorants:n {#1} - } - } - \@@_backend_init_resource:n { color \int_use:N \g_@@_model_int } - } -\cs_new:Npn \@@_backend_devicen_init:w #1 ~ #2 \s_@@_stop - { - + 1 - \tl_if_blank:nF {#2} - { \@@_backend_devicen_init:w #2 \s_@@_stop } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_backend_iccbased_init:nnn} -% Lots of data to save here: we only want to do that once per file, -% so track it by name. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_iccbased_init:nnn #1#2#3 - { - \pdf_object_if_exist:nF { @@_icc_ #1 } - { - \pdf_object_new:n { @@_icc_ #1 } - \pdf_object_write:nne { @@_icc_ #1 } { fstream } - { - { - /N ~ \exp_not:n { #2 } ~ - \tl_if_empty:nF { #3 } { /Range~[ #3 ] } - } - {#1} - } - } - \pdf_object_unnamed_write:ne { array } - { /ICCBased ~ \pdf_object_ref:n { @@_icc_ #1 } } - \@@_backend_init_resource:n { color \int_use:N \g_@@_model_int } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_iccbased_device:nnn} -% This is very similar to setting up a color space: the only part we -% add to the page resources differently. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_iccbased_device:nnn #1#2#3 - { - \pdf_object_if_exist:nF { @@_icc_ #1 } - { - \pdf_object_new:n { @@_icc_ #1 } - \pdf_object_write:nnn { @@_icc_ #1 } { fstream } - { - { /N ~ #3 } - {#1} - } - } - \pdf_object_unnamed_write:ne { array } - { /ICCBased ~ \pdf_object_ref:n { @@_icc_ #1 } } - \@@_backend_init_resource:n { Default #2 } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</dvipdfmx|luatex|pdftex|xetex> -% \end{macrocode} -% -% \subsection{Fill and stroke color} -% -% Here, \texttt{dvipdfmx}/\XeTeX{} we write direct PDF specials for the fill, -% and only use the stack for the stroke color (see above for comments on why -% we cannot use multiple stacks with these backends). \LuaTeX{} and \pdfTeX{} -% have mutiple stacks that can deal with fill and stroke. For \texttt{dvips} -% we have to manage fill and stroke color ourselves. We also handle -% \texttt{dvisvgm} independently, as there we can create SVG directly. -% -% \begin{macrocode} -%<*dvipdfmx|xetex> -% \end{macrocode} -% -% \begin{macro} -% { -% \@@_backend_fill:n , -% \@@_backend_fill_cmyk:n , -% \@@_backend_fill_gray:n , -% \@@_backend_fill_rgb:n , -% \@@_backend_stroke:n , -% \@@_backend_stroke_cmyk:n , -% \@@_backend_stroke_gray:n , -% \@@_backend_stroke_rgb:n -% } -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_fill:n #1 - { \__kernel_backend_literal:n { pdf : bc ~ fill ~ [ #1 ] } } -\cs_new_eq:NN \@@_backend_fill_cmyk:n \@@_backend_fill:n -\cs_new_eq:NN \@@_backend_fill_gray:n \@@_backend_fill:n -\cs_new_eq:NN \@@_backend_fill_rgb:n \@@_backend_fill:n -\cs_new_protected:Npn \@@_backend_stroke:n #1 - { \__kernel_backend_literal:n { pdf : bc ~ stroke ~ [ #1 ] } } -\cs_new_eq:NN \@@_backend_stroke_cmyk:n \@@_backend_stroke:n -\cs_new_eq:NN \@@_backend_stroke_gray:n \@@_backend_stroke:n -\cs_new_eq:NN \@@_backend_stroke_rgb:n \@@_backend_stroke:n -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% { -% \@@_backend_fill_separation:nn, -% \@@_backend_stroke_separation:nn, -% \@@_backend_fill_devicen:nn, -% \@@_backend_stroke_devicen:nn -% } -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 - { - \__kernel_backend_literal:e - { pdf : bc ~ fill ~ \pdf_object_ref:n {#1} ~ [ #2 ] } - } -\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 - { - \__kernel_backend_literal:e - { pdf : bc ~ stroke ~ \pdf_object_ref:n {#1} ~ [ #2 ] } - } -\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn -\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:} -% \begin{macrocode} -\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset: -\cs_new_eq:NN \@@_backend_stroke_reset: \@@_backend_reset: -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</dvipdfmx|xetex> -% \end{macrocode} -% -% \begin{macrocode} -%<*luatex|pdftex> -% \end{macrocode} -% -% \begin{macro} -% { -% \@@_backend_fill_cmyk:n , -% \@@_backend_fill_gray:n , -% \@@_backend_fill_rgb:n , -% \@@_backend_fill:n , -% \@@_backend_stroke_cmyk:n , -% \@@_backend_stroke_gray:n , -% \@@_backend_stroke_rgb:n , -% \@@_backend_stroke:n -% } -% Drawing (fill/stroke) color is handled in \texttt{dvipdfmx}/\XeTeX{} in the -% same way as \LuaTeX{}/\pdfTeX{}. We use the same approach as earlier, except the -% color stack is not involved so the generic direct PDF operation is used. -% There is no worry about the nature of strokes: everything is handled -% automatically. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1 - { \@@_backend_fill:n { #1 ~ k } } -\cs_new_protected:Npn \@@_backend_fill_gray:n #1 - { \@@_backend_fill:n { #1 ~ g } } -\cs_new_protected:Npn \@@_backend_fill_rgb:n #1 - { \@@_backend_fill:n { #1 ~ rg } } -\cs_new_protected:Npn \@@_backend_fill:n #1 - { - \tl_set:Nn \l_@@_backend_fill_tl {#1} - \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int - { #1 ~ \l_@@_backend_stroke_tl } - } -\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1 - { \@@_backend_stroke:n { #1 ~ K } } -\cs_new_protected:Npn \@@_backend_stroke_gray:n #1 - { \@@_backend_stroke:n { #1 ~ G } } -\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1 - { \@@_backend_stroke:n { #1 ~ RG } } -\cs_new_protected:Npn \@@_backend_stroke:n #1 - { - \tl_set:Nn \l_@@_backend_stroke_tl {#1} - \__kernel_color_backend_stack_push:nn \l_@@_backend_stack_int - { \l_@@_backend_fill_tl \c_space_tl #1 } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% { -% \@@_backend_fill_separation:nn, -% \@@_backend_stroke_separation:nn, -% \@@_backend_fill_devicen:nn, -% \@@_backend_stroke_devicen:nn -% } -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 - { \@@_backend_fill:n { /#1 ~ cs ~ #2 ~ scn } } -\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 - { \@@_backend_stroke:n { /#1 ~ CS ~ #2 ~ SCN } } -\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn -\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:} -% \begin{macrocode} -\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset: -\cs_new_eq:NN \@@_backend_stroke_reset: \@@_backend_reset: -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</luatex|pdftex> -% \end{macrocode} -% -% \begin{macrocode} -%<*dvips> -% \end{macrocode} -% -% \begin{macro} -% { -% \@@_backend_fill_cmyk:n , -% \@@_backend_fill_gray:n , -% \@@_backend_fill_rgb:n , -% \@@_backend_fill:n , -% \@@_backend_stroke_cmyk:n , -% \@@_backend_stroke_gray:n , -% \@@_backend_stroke_rgb:n -% } -% Fill color here is the same as general color \emph{except} we skip the -% stroke part. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1 - { \@@_backend_fill:n { cmyk ~ #1 } } -\cs_new_protected:Npn \@@_backend_fill_gray:n #1 - { \@@_backend_fill:n { gray ~ #1 } } -\cs_new_protected:Npn \@@_backend_fill_rgb:n #1 - { \@@_backend_fill:n { rgb ~ #1 } } -\cs_new_protected:Npn \@@_backend_fill:n #1 - { - \__kernel_backend_literal:n { color~push~ #1 } - } -\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1 - { \__kernel_backend_postscript:n { /color.sc { #1 ~ setcmykcolor } def } } -\cs_new_protected:Npn \@@_backend_stroke_gray:n #1 - { \__kernel_backend_postscript:n { /color.sc { #1 ~ setgray } def } } -\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1 - { \__kernel_backend_postscript:n { /color.sc { #1 ~ setrgbcolor } def } } -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% { -% \@@_backend_fill_separation:nn, -% \@@_backend_stroke_separation:nn, -% \@@_backend_fill_devicen:nn, -% \@@_backend_stroke_devicen:nn -% } -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 - { \@@_backend_fill:n { separation ~ #1 ~ #2 } } -\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 - { \__kernel_backend_postscript:n { /color.sc { separation ~ #1 ~ #2 } def } } -\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn -\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:} -% \begin{macrocode} -\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset: -\cs_new_protected:Npn \@@_backend_stroke_reset: { } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</dvips> -% \end{macrocode} -% -% \begin{macrocode} -%<*dvisvgm> -% \end{macrocode} -% -% \begin{macro} -% { -% \@@_backend_fill_cmyk:n , -% \@@_backend_fill_gray:n , -% \@@_backend_fill_rgb:n , -% \@@_backend_fill:n -% } -% Fill color here is the same as general color \emph{except} we skip the -% stroke part. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1 - { \@@_backend_fill:n { cmyk ~ #1 } } -\cs_new_protected:Npn \@@_backend_fill_gray:n #1 - { \@@_backend_fill:n { gray ~ #1 } } -\cs_new_protected:Npn \@@_backend_fill_rgb:n #1 - { \@@_backend_fill:n { rgb ~ #1 } } -\cs_new_protected:Npn \@@_backend_fill:n #1 - { - \__kernel_backend_literal:n { color~push~ #1 } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_stroke_cmyk:n} -% \begin{macro}{\@@_backend_stroke_cmyk:w} -% \begin{macro}{\@@_backend_stroke_gray:n, \@@_backend_stroke_gray_aux:n} -% \begin{macro}{\@@_backend_stroke_rgb:n} -% \begin{macro}{\@@_backend_stroke_rgb:w} -% \begin{macro}{\@@_backend:nnn} -% For drawings in SVG, we use scopes for all stroke colors. That -% requires using \texttt{RGB} values, which luckily are easy to -% convert here (|cmyk| to |RGB| is a fixed function). -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1 - { \@@_backend_cmyk:w #1 \s_@@_stop } -\cs_new_protected:Npn \@@_backend_stroke_cmyk:w - #1 ~ #2 ~ #3 ~ #4 \s_@@_stop - { - \use:e - { - \@@_backend:nnn - { \fp_eval:n { -100 * ( 1 - min ( 1 , #1 + #4 ) ) } } - { \fp_eval:n { -100 * ( 1 - min ( 1 , #2 + #4 ) ) } } - { \fp_eval:n { -100 * ( 1 - min ( 1 , #3 + #4 ) ) } } - } - } -\cs_new_protected:Npn \@@_backend_stroke_gray:n #1 - { - \use:e - { - \@@_backend_stroke_gray_aux:n - { \fp_eval:n { 100 * (#1) } } - } - } -\cs_new_protected:Npn \@@_backend_stroke_gray_aux:n #1 - { \@@_backend:nnn {#1} {#1} {#1} } -\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1 - { \@@_backend_rgb:w #1 \s_@@_stop } -\cs_new_protected:Npn \@@_backend_stroke_rgb:w - #1 ~ #2 ~ #3 \s_@@_stop - { - \use:e - { - \@@_backend:nnn - { \fp_eval:n { 100 * (#1) } } - { \fp_eval:n { 100 * (#2) } } - { \fp_eval:n { 100 * (#3) } } - } - } -\cs_new_protected:Npe \@@_backend:nnn #1#2#3 - { - \__kernel_backend_scope:n - { - stroke = - " - rgb - ( - #1 \c_percent_str , - #2 \c_percent_str , - #3 \c_percent_str - ) - " - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro} -% { -% \@@_backend_fill_separation:nn, -% \@@_backend_stroke_separation:nn, -% \@@_backend_fill_devicen:nn, -% \@@_backend_stroke_devicen:nn -% } -% At present, these are no-ops. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 { } -\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 { } -\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn -\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_fill_reset:, \@@_backend_stroke_reset:} -% \begin{macrocode} -\cs_new_eq:NN \@@_backend_fill_reset: \@@_backend_reset: -\cs_new_protected:Npn \@@_backend_stroke_reset: { } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_backend_devicen_init:nnn, \@@_backend_iccbased_init:nnn} -% No support at present. -% \begin{macrocode} -\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 { } -\cs_new_protected:Npn \@@_backend_iccbased_init:nnn #1#2#3 { } -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</dvisvgm> -% \end{macrocode} -% -% \begin{macrocode} -%</package> -% \end{macrocode} -% -% \subsection{Font handling integration} -% -% In \LuaTeX{} these colors should also be usable to color fonts, so -% \texttt{luaotfload} color handling is extended to include these. -% -% \begin{macrocode} -%<*lua> -% \end{macrocode} -% -% \begin{macrocode} -local l = lpeg -local spaces = l.P' '^0 -local digit16 = l.R('09', 'af', 'AF') - -local octet = digit16 * digit16 / function(s) - return string.format('%.3g ', tonumber(s, 16) / 255) -end - -if luaotfload and luaotfload.set_transparent_colorstack then - local htmlcolor = l.Cs(octet * octet * octet * -1 * l.Cc'rg') - local color_export = { - token.create'tex_endlocalcontrol:D', - token.create'tex_hpack:D', - token.new(0, 1), - token.create'color_export:nnN', - token.new(0, 1), - '', - token.new(0, 2), - token.new(0, 1), - 'backend', - token.new(0, 2), - token.create'l_tmpa_tl', - token.create'exp_after:wN', - token.create'@@_select:nn', - token.create'l_tmpa_tl', - token.new(0, 2), - } - local group_end = token.create'group_end:' - local value = (1 - l.P'}')^0 - luatexbase.add_to_callback('luaotfload.parse_color', function (value) -% Also allow HTML colors to preserve compatibility - local html = htmlcolor:match(value) - if html then return html end - -% If no l3color named color with this name is known, check for defined xcolor colors - local l3color_prop = token.get_macro(string.format('l_@@_named_%s_prop', value)) - if l3color_prop == nil or l3color_prop == '' then - local legacy_color_macro = token.create(string.format('\\color@%s', value)) - if legacy_color_macro.cmdname ~= 'undefined_cs' then - token.put_next(legacy_color_macro) - return token.scan_argument() - end - end - - tex.runtoks(function() - token.get_next() - color_export[6] = value - tex.sprint(-2, color_export) - end) - local list = token.scan_list() - if not list.head or list.head.next - or list.head.subtype ~= node.subtype'pdf_colorstack' then - error'Unexpected backend behavior' - end - local cmd = list.head.data - node.free(list) - return cmd - end, 'l3color') -end -% \end{macrocode} -% -% \begin{macrocode} -%</lua> -% \end{macrocode} -% -% \begin{macrocode} -%<*luatex> -% \end{macrocode} -% -% \begin{macrocode} -%<*package> -\lua_load_module:n {l3backend-luatex} -%</package> -% \end{macrocode} -% -% \begin{macrocode} -%</luatex> -% \end{macrocode} -% -% \end{implementation} -% -% \PrintIndex |