[latex3-commits] [git/LaTeX3-latex3-latex3] master: Initial support for DeviceN color spaces (5685656b1)
Joseph Wright
joseph.wright at morningstar2.co.uk
Wed Sep 16 11:34:04 CEST 2020
Repository : https://github.com/latex3/latex3
On branch : master
Link : https://github.com/latex3/latex3/commit/5685656b11b08da6eadd73fc02cf68dc5c2063a4
>---------------------------------------------------------------
commit 5685656b11b08da6eadd73fc02cf68dc5c2063a4
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date: Wed Sep 16 10:34:04 2020 +0100
Initial support for DeviceN color spaces
At the moment no mixing - tints are a must, so are
to follow shortly.
>---------------------------------------------------------------
5685656b11b08da6eadd73fc02cf68dc5c2063a4
l3backend/l3backend-color.dtx | 124 ++++++++--
l3experimental/CHANGELOG.md | 3 +
l3experimental/l3color/l3color.dtx | 391 +++++++++++++++++++++++++++++++-
l3kernel/testfiles/m3expl001.luatex.tlg | 6 +
l3kernel/testfiles/m3expl001.ptex.tlg | 4 +
l3kernel/testfiles/m3expl001.tlg | 6 +
l3kernel/testfiles/m3expl001.uptex.tlg | 4 +
l3kernel/testfiles/m3expl001.xetex.tlg | 6 +
l3kernel/testfiles/m3expl003.luatex.tlg | 6 +
l3kernel/testfiles/m3expl003.ptex.tlg | 4 +
l3kernel/testfiles/m3expl003.tlg | 6 +
l3kernel/testfiles/m3expl003.uptex.tlg | 4 +
l3kernel/testfiles/m3expl003.xetex.tlg | 6 +
13 files changed, 550 insertions(+), 20 deletions(-)
diff --git a/l3backend/l3backend-color.dtx b/l3backend/l3backend-color.dtx
index a9a86daeb..4424c1d46 100644
--- a/l3backend/l3backend-color.dtx
+++ b/l3backend/l3backend-color.dtx
@@ -308,10 +308,11 @@
%<*dvips>
% \end{macrocode}
%
-% \begin{macro}{\@@_backend_select_separation:nn}
+% \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}
%
@@ -362,7 +363,7 @@
{
!
TeXDict ~ begin ~
- /color \int_use:N \g_@@_separation_int
+ /color \int_use:N \g_@@_model_int
{
[ ~
/Separation ~ ( \str_convert_pdfname:n {#1} ) ~
@@ -541,6 +542,30 @@
% \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 ~ } ~
+ ] ~ setcolorspace
+ } ~ def ~
+ end
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macrocode}
%</dvips>
% \end{macrocode}
@@ -549,10 +574,11 @@
%<*dvisvgm>
% \end{macrocode}
%
-% \begin{macro}{\@@_backend_select_separation:nn}
+% \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_protected:Npn \@@_backend_select_devicen:nn #1#2 { }
% \end{macrocode}
% \end{macro}
%
@@ -573,7 +599,7 @@
%<*dvipdfmx|luatex|pdftex|xetex>
% \end{macrocode}
%
-% \begin{macro}{\@@_backend_select_separation:nn}
+% \begin{macro}{\@@_backend_select_separation:nn, \@@_backend_select_devicen:nn}
% \begin{macro}{\@@_backend_select:n}
% Different syntaxes here as the stacks are accessed very differently.
% \begin{macrocode}
@@ -591,6 +617,7 @@
\group_insert_after:N \@@_backend_reset:
}
%</dvipdfmx|xetex>
+\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -617,7 +644,7 @@
}
\@@_backend_separation_init:n
{
- /Separation
+ /Separation ~
/ \str_convert_pdfname:n {#1} ~ #2 ~
\pdf_object_last:
}
@@ -626,7 +653,7 @@
{
\pdfcoredict_gput:nnn
{ Page / Resources / ColorSpace }
- { color \int_use:N \g_@@_separation_int }
+ { color \int_use:N \g_@@_model_int }
{ \pdf_object_last: }
}
%</luatex|pdftex>
@@ -638,7 +665,7 @@
%<*dvipdfmx|xetex>
\__kernel_backend_literal:x
{
- pdf:obj ~ @color \int_use:N \g_@@_separation_int \c_space_tl
+ pdf:obj ~ @color \int_use:N \g_@@_model_int \c_space_tl
[#1]
}
%</dvipdfmx|xetex>
@@ -682,6 +709,65 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\@@_backend_devicen_init:nnn}
+% \begin{macro}[EXP]{\@@_backend_devicen_init:w}
+% \begin{macro}{\@@_backend_devicen_init:n}
+% 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_now:nx { 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}
+ }
+ \@@_backend_separation_init:n
+ {
+ /DeviceN ~
+ [ ~ #1 ~ ] ~
+ #2 ~
+ \pdf_object_last:
+ }
+%<*luatex|pdftex>
+ \use:x
+ {
+ \pdfcoredict_gput:nnn
+ { Page / Resources / ColorSpace }
+ { color \int_use:N \g_@@_model_int }
+ { \pdf_object_last: }
+ }
+%</luatex|pdftex>
+ }
+\cs_new:Npn \@@_backend_devicen_init:w #1 ~ #2 \s_@@_stop
+ {
+ + 1
+ \tl_if_blank:nF {#2}
+ { \@@_backend_devicen_init:w #2 \s_@@_stop }
+ }
+\cs_new_eq:NN \@@_backend_devicen_init:n \@@_backend_separation_init:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macrocode}
%</dvipdfmx|luatex|pdftex|xetex>
% \end{macrocode}
@@ -730,13 +816,17 @@
% \begin{macro}
% {
% \@@_backend_fill_separation:nn,
-% \@@_backend_stroke_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_pdf:n { /#1 ~ cs ~ #2 ~ scn } }
\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2
{ \__kernel_backend_literal_pdf: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}
%
@@ -777,13 +867,17 @@
% \begin{macro}
% {
% \@@_backend_fill_separation:nn,
-% \@@_backend_stroke_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_postscript:n { /color.fc { #1 } def } }
\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2
{ \__kernel_backend_postscript:n { /color.sc { #1 } 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}
%
@@ -892,14 +986,16 @@
% \begin{macro}
% {
% \@@_backend_fill_separation:nn,
-% \@@_backend_stroke_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_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}
%
diff --git a/l3experimental/CHANGELOG.md b/l3experimental/CHANGELOG.md
index 362059210..edefc1c56 100644
--- a/l3experimental/CHANGELOG.md
+++ b/l3experimental/CHANGELOG.md
@@ -7,6 +7,9 @@ this project uses date-based 'snapshot' version identifiers.
## [Unreleased]
+### Added
+- Support for DeviceN color spaces
+
## [2020-09-11]
### Fixed
diff --git a/l3experimental/l3color/l3color.dtx b/l3experimental/l3color/l3color.dtx
index f644bf5fd..e30d2a83b 100644
--- a/l3experimental/l3color/l3color.dtx
+++ b/l3experimental/l3color/l3color.dtx
@@ -362,6 +362,7 @@
% Creates a new \meta{model} which is derived from the color model \meta{family}.
% The latter should be one of
% \begin{itemize}
+% \item \texttt{DeviceN}
% \item \texttt{Separation}
% \end{itemize}
% (The \meta{family} may be given in mixed case as-in the PDF reference:
@@ -398,6 +399,13 @@
% not the case, \pkg{l3color} will fallback to using black as the colorant in
% any mixing.
%
+% For a \texttt{DeviceN} space, there is one \emph{compulsory} key.
+% \begin{itemize}
+% \item \texttt{names} The names of the components of the \texttt{DeviceN}
+% space. Each should be either the \meta{name} of a \texttt{Separation} model,
+% a process color name (\texttt{cyan}, etc.) or the special name \texttt{none}.
+% \end{itemize}
+%
% \end{documentation}
%
% \begin{implementation}
@@ -439,8 +447,9 @@
%
% \subsection{Setup}
%
-% \begin{variable}{\l_@@_internal_tl}
+% \begin{variable}{\l_@@_internal_int, \l_@@_internal_tl}
% \begin{macrocode}
+\int_new:N \l_@@_internal_int
\tl_new:N \l_@@_internal_tl
% \end{macrocode}
% \end{variable}
@@ -1517,10 +1526,25 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\g_@@_separation_int}
-% A tracker for the total number of separations.
+% \begin{variable}{\g_@@_model_int}
+% A tracker for the total number of new models.
+% \begin{macrocode}
+\int_new:N \g_@@_model_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_colorants_prop}
+% Mapping from names to colorants.
% \begin{macrocode}
-\int_new:N \g_@@_separation_int
+\prop_new:N \g_@@_colorants_prop
+\prop_gput:Nnn \g_@@_colorants_prop { black } { Black }
+\prop_gput:Nnn \g_@@_colorants_prop { blue } { Blue }
+\prop_gput:Nnn \g_@@_colorants_prop { cyan } { Cyan }
+\prop_gput:Nnn \g_@@_colorants_prop { green } { Green }
+\prop_gput:Nnn \g_@@_colorants_prop { magenta } { Magenta }
+\prop_gput:Nnn \g_@@_colorants_prop { none } { None }
+\prop_gput:Nnn \g_@@_colorants_prop { red } { Red }
+\prop_gput:Nnn \g_@@_colorants_prop { yellow } { Yellow }
% \end{macrocode}
% \end{variable}
%
@@ -1553,6 +1577,31 @@
% \end{macrocode}
% \end{variable}
%
+% \begin{variable}{\g_@@_alternative_model_prop}
+% For tracking the alternative model set up for separations, etc.
+% \begin{macrocode}
+\prop_new:N \g_@@_alternative_model_prop
+\clist_map_inline:nn { cyan , magenta , yellow , black }
+ { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { cmyk } }
+\clist_map_inline:nn { red , green , blue }
+ { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { rgb } }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_alternative_values_prop}
+% Same for the values: a bit more involved.
+% \begin{macrocode}
+\prop_new:N \g_@@_alternative_values_prop
+\prop_gput:Nnn \g_@@_alternative_values_prop { cyan } { 1 , 0 , 0 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { magenta } { 0 , 1 , 0 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { yellow } { 0 , 0 , 1 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { black } { 0 , 0 , 0 , 1 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { red } { 1 , 0 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { green } { 0 , 1 , 0 }
+\prop_gput:Nnn \g_@@_alternative_values_prop { blue } { 0 , 0 , 1 }
+% \end{macrocode}
+% \end{variable}
+%
% \begin{macro}{\color_model_new:nnn, \@@_model_new:nnn}
% Set up a new model: in general this has to be handled by a family-dependent
% function. To avoid some \enquote{interesting} questions with casing, we
@@ -1665,7 +1714,7 @@
\cs_new_protected:Npn \@@_model_separation:w
#1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7#8
{
- \int_gincr:N \g_@@_separation_int
+ \int_gincr:N \g_@@_model_int
\tl_const:cn { c_@@_fallback_ #6 _tl } { 1 }
\cs_new_eq:cN { @@_parse_mix_ #6 :nw } \@@_parse_mix_gray:nw
\cs_new:cpn { @@_parse_model_ #6 :w } ##1 , ##2 \s_@@_stop
@@ -1675,11 +1724,14 @@
\cs_new_protected:cpx { @@_backend_ ##1 _ #6 :n } ####1
{
\exp_not:c { @@_backend_ ##1 _ separation:nn }
- { color \int_use:N \g_@@_separation_int } {####1}
+ { color \int_use:N \g_@@_model_int } {####1}
}
}
\use:c { @@_model_separation_ #8 :nnnnnn }
{#6} {#7} {#1} {#2} {#3} {#4}
+ \prop_gput:Nnn \g_@@_alternative_model_prop {#6} {#8}
+ \prop_gput:Nnx \g_@@_colorants_prop {#6}
+ { \str_convert_pdfname:n {#7} }
\cs_new_protected:cpx { @@_model_ #6 _white: }
{
\prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#6} { 0 }
@@ -1699,6 +1751,7 @@
}
\@@_model_convert:nnn {#1} { cmyk } { rgb }
\@@_model_convert:nnn {#1} { cmyk } { gray }
+ \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 , #6 }
\@@_backend_separation_init:nnnnn {#2} { /DeviceCMYK } { }
{ 0 ~ 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 ~ #6 }
}
@@ -1712,6 +1765,7 @@
}
\@@_model_convert:nnn {#1} { rgb } { cmyk }
\@@_model_convert:nnn {#1} { rgb } { gray }
+ \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 }
\@@_backend_separation_init:nnnnn {#2} { /DeviceRGB } { }
{ 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 }
}
@@ -1732,6 +1786,7 @@
\fp_eval:n {##1 * #3} ~
\fp_eval:n {##1 * #3}
}
+ \prop_gput:Nnn \g_@@_alternative_values_prop {#1} {#3}
\@@_backend_separation_init:nnnnn {#2} { /DeviceGray } { } { 0 } {#3}
}
% \end{macrocode}
@@ -1797,6 +1852,308 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\@@_model_devicen:n}
+% \begin{macro}{\@@_model_devicen:nn}
+% \begin{macro}{\@@_model_devicen:nnn}
+% \begin{macro}{\@@_model_devicen:nnnn}
+% \begin{macro}
+% {
+% \@@_model_devicen_parse_1:nn ,
+% \@@_model_devicen_parse_2:nn ,
+% \@@_model_devicen_parse_3:nn ,
+% \@@_model_devicen_parse_4:nn ,
+% \@@_model_devicen_parse_generic:nn
+% }
+% \begin{macro}[EXP]{\@@_model_devicen_parse:nw}
+% \begin{macro}{\@@_model_devicen_init:nnn}
+% \begin{macro}{\@@_model_devicen_init:nnnn}
+% \begin{macro}{\@@_model_devicen_tranform:w}
+% \begin{macro}
+% {
+% \@@_model_devicen_tranform_1:nnnnn ,
+% \@@_model_devicen_tranform_3:nnnnn ,
+% \@@_model_devicen_tranform_4:nnnnn ,
+% }
+% \begin{macro}{\@@_model_devicen_tranform:nnn}
+% \begin{macro}[EXP]{\@@_model_devicen_colorant:n}
+% We require a list of component names here: one might call them colorants,
+% but it's convenient to use \TeX{} names instead so we slightly adjust the
+% terminology.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen:n #1
+ {
+ \prop_get:NnNTF \l_@@_internal_prop { names }
+ \l_@@_internal_tl
+ {
+ \exp_args:NV \@@_model_devicen:nn
+ \l_@@_internal_tl {#1}
+ }
+ {
+ \__kernel_msg_error:nnn { color }
+ { DeviceN-requires-names } {#1}
+ }
+ }
+% \end{macrocode}
+% All valid models will have an alternative listed, either hard-coded for
+% the core device ones, or dynamically added for Separations, etc.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen:nn #1#2
+ {
+ \tl_clear:N \l_@@_model_tl
+ \clist_map_inline:nn {#1}
+ {
+ \prop_get:NnNTF \g_@@_alternative_model_prop {##1}
+ \l_@@_internal_tl
+ {
+ \tl_if_empty:NTF \l_@@_model_tl
+ { \tl_set_eq:NN \l_@@_model_tl \l_@@_internal_tl }
+ {
+ \tl_if_eq:NNF \l_@@_model_tl \l_@@_internal_tl
+ {
+ \__kernel_msg_error:nnn { color }
+ { DeviceN-inconsistent-alternative }
+ {#1}
+ \clist_map_break:n { \use_none:nnnnn }
+ }
+ }
+ }
+ {
+ \__kernel_msg_error:nnn { color }
+ { DeviceN-no-alternative }
+ {#2}
+ }
+ }
+ \exp_args:NV \@@_model_devicen:nnn \l_@@_model_tl {#1} {#2}
+ }
+% \end{macrocode}
+% We now complete the data we require by first finding out how many
+% colorants there are, then moving on to begin constructing the function
+% required to map to the alternative color space.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen:nnn #1#2#3
+ {
+ \exp_args:Nx \@@_model_devicen:nnnn
+ { \clist_count:n {#2} } {#1} {#2} {#3}
+ }
+% \end{macrocode}
+% At this stage, we have checked everything is in place, so we can set up
+% the \TeX{} and backend data structures. As for separations, it's not really
+% possible in general to have a fallback, so we simply provide
+% \enquote{black} for each element.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen:nnnn #1#2#3#4
+ {
+ \int_gincr:N \g_@@_model_int
+ \tl_const:cx { c_@@_fallback_ #4 _tl }
+ { \prg_replicate:nn {#1} { 1 ~ } }
+ \cs_if_exist_use:cF { @@_model_devicen_parse_ #1 :nn }
+ { \@@_model_devicen_parse_generic:nn }
+ {#4} {#1}
+ \clist_map_inline:nn { fill , stroke , select }
+ {
+ \cs_new_protected:cpx { @@_backend_ ##1 _ #4 :n } ####1
+ {
+ \exp_not:c { @@_backend_ ##1 _ devicen:nn }
+ { color \int_use:N \g_@@_model_int } {####1}
+ }
+ }
+ \@@_model_devicen_init:nnn {#1} {#2} {#3}
+ }
+% \end{macrocode}
+% For short lists of DeviceN colors, wee can use hand-tuned parsing. This
+% lines up with other models, where we allow for up to four components. For
+% larger spaces,. rather than limit artificially, we use a somewhat slow
+% approach based on open-ended commas-lists.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_model_devicen_parse_1:nn } #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop
+ { {#1} { \@@_parse_number:n {##1} } }
+ }
+\cs_new_protected:cpn { @@_model_devicen_parse_2:nn } #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 \s_@@_stop
+ { {#1} { \@@_parse_number:n {##1} ~ \@@_parse_number:n {##2} } }
+ }
+\cs_new_protected:cpn { @@_model_devicen_parse_3:nn } #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 , ##4 \s_@@_stop
+ {
+ {#1}
+ {
+ \@@_parse_number:n {##1} ~
+ \@@_parse_number:n {##2} ~
+ \@@_parse_number:n {##3}
+ }
+ }
+ }
+\cs_new_protected:cpn { @@_model_devicen_parse_4:nn } #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w }
+ ##1 , ##2 , ##3 , ##4 , ##5 \s_@@_stop
+ {
+ {#1}
+ {
+ \@@_parse_number:n {##1} ~
+ \@@_parse_number:n {##2} ~
+ \@@_parse_number:n {##3} ~
+ \@@_parse_number:n {##4}
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_model_devicen_parse_generic:nn #1#2
+ {
+ \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop
+ {
+ {#1}
+ { \@@_model_devicen_parse:nw {#2} ##2 , \q_nil , \s_@@_stop }
+ }
+ }
+\cs_new:Npn \@@_model_devicen_parse:nw #1#2 , #3 \s_@@_stop
+ {
+ \int_compare:nNnT {#1} > 0
+ {
+ \quark_if_nil:nTF {#2}
+ { \prg_replicate:nn {#1} { 0 ~ } }
+ {
+ \@@_parse_number:n {#2}
+ \int_compare:nNnT {#1} > 1 { ~ }
+ \exp_args:Nf \@@_model_devicen_parse:nw
+ { \int_eval:n { #1 - 1 } } #3 \s_@@_stop
+ }
+ }
+ }
+% \end{macrocode}
+% To construct the tint transformation, we have to use PostScript. The
+% aim is to have the final tint for each device colorant as
+% \[
+% 1 - \prod_{n} (1 - X_{n} D_{X_{n}})
+% \]
+% where $X$ is a DeviceN colorant and $D$ is the amount of device colorant
+% that the DeviceN colorant maps to. At the start of the process, the
+% PostScript stack will contain the $X_{n}$ values, whilst we have the
+% $D$ values on a per-DeviceN colorant basis. The more convenient approach
+% for us is therefore to take each DeviceN colorant in turn and find the
+% value $1 - X_{n} D_{X_{n}}$, multiplying as we go, and finalise with the
+% subtraction. That contrasts to \pkg{colorspace}: it splits the process
+% up by process color, which works better when you have a fixed list
+% of colorants. (\pkg{colorspace} only supports up to $4$ DeviceN colors,
+% and only \texttt{cmyk} as the alternative space.) To set this up,
+% we first need to know the number of values in the target color space:
+% this is easily handled as there are a very small range of possibles.
+% Once we have that information, it's relatively easy to build the required
+% PostScript using some generic code.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen_init:nnn #1#2#3
+ {
+ \exp_args:Ne \@@_model_devicen_init:nnnn
+ {
+ \str_case:nn {#2}
+ {
+ { cmyk } { 4 }
+ { gray } { 1 }
+ { rgb } { 3 }
+ }
+ }
+ {#1} {#2} {#3}
+ }
+% \end{macrocode}
+% As we always need to split the alternative values into parts, we use a
+% shared auxiliary and only use a minimal difference between code paths.
+% Construction of the tint transformation is as far as possible done using
+% loops, which means there are some inefficiencies for device colors in
+% the \texttt{DeviceN} space: we roll the stack one-at-a-time even if there
+% is a potential shortcut. However, that way there is nothing to special-case.
+% Once this is sorted, we can write the tint transform object, which will
+% remain as the last object until we sort out the final step: the colorant
+% list.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_devicen_init:nnnn #1#2#3#4
+ {
+ \tl_set:Nx \l_@@_internal_tl
+ { \prg_replicate:nn {#1} { 1.0 ~ } }
+ \int_zero:N \l_@@_internal_int
+ \clist_map_inline:nn {#4}
+ {
+ \int_incr:N \l_@@_internal_int
+ \prop_get:NnN \g_@@_alternative_values_prop {##1}
+ \l_@@_value_tl
+ \exp_after:wN \@@_model_devicen_transform:w
+ \l_@@_value_tl , 0 , 0 , 0 \s_@@_stop {#1} {#2}
+ }
+ \tl_put_right:Nx \l_@@_internal_tl
+ {
+ \prg_replicate:nn {#1}
+ { neg ~ 1.0 ~ add ~ #1 ~ -1 ~ roll ~ }
+ \int_eval:n { #2 + 4 } ~ 4 ~ roll
+ \prg_replicate:nn {#2} { ~ pop }
+ }
+ \use:x
+ {
+ \@@_backend_devicen_init:nnn
+ {
+ \clist_map_function:nN {#4}
+ \@@_model_devicen_colorant:n
+ }
+ {
+ \str_case:nn {#3}
+ {
+ { cmyk } { /DeviceCMYK }
+ { gray } { /DeviceGray }
+ { rgb } { /DeviceRGB }
+ }
+ }
+ { \exp_not:V \l_@@_internal_tl }
+ }
+ }
+\cs_new_protected:Npn \@@_model_devicen_transform:w
+ #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7
+ {
+ \use:c { @@_model_devicen_transform_ #6 :nnnnn }
+ {#1} {#2} {#3} {#4} {#7}
+ }
+\cs_new_protected:cpn { @@_model_devicen_transform_1:nnnnn } #1#2#3#4#5
+ { \@@_model_devicen_transform:nnn {#5} { 1 } {#1} }
+\cs_new_protected:cpn { @@_model_devicen_transform_3:nnnnn } #1#2#3#4#5
+ {
+ \clist_map_inline { #1 , #2 , #3 }
+ { \@@_model_devicen_transform:nnn {#5} { 3 } {##1} }
+ }
+\cs_new_protected:cpn { @@_model_devicen_transform_4:nnnnn } #1#2#3#4#5
+ {
+ \clist_map_inline:nn { #1 , #2 , #3 , #4 }
+ { \@@_model_devicen_transform:nnn {#5} { 4 } {##1} }
+ }
+\cs_new_protected:Npn \@@_model_devicen_transform:nnn #1#2#3
+ {
+ \tl_put_right:Nx \l_@@_internal_tl
+ {
+ \fp_compare:nNnF {#3} = \c_zero_fp
+ {
+ \int_eval:n { #1 - \l_@@_internal_int + #2 } ~ index ~
+ #3 ~ neg ~ mul ~ 1.0 ~ add ~ mul ~
+ }
+ #2 ~ -1 ~ roll ~
+ }
+ }
+\cs_new:Npn \@@_model_devicen_colorant:n #1
+ {
+ / \prop_item:Nn \g_@@_colorants_prop {#1} ~
+ }
+% \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}
+%
% \subsection{Diagnostics}
%
% \begin{macro}{\color_show:n}
@@ -1847,6 +2204,28 @@
LaTeX~has~been~asked~to~convert~a~color~from~model~'#1'~
to~model'#2',~but~there~is~no~method~available~to~do~that.
}
+\__kernel_msg_new:nnnn { color } { DeviceN-inconsistent-alternative }
+ { DeviceN~color~spaces~require~a~single~alternative~space. }
+ {
+ LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~
+ but~the~constituent~colors~do~not~have~a~common~alternative~
+ color.
+ }
+\__kernel_msg_new:nnnn { color } { DeviceN-no-alternative }
+ { DeviceN~color~spaces~require~an~alternative~space. }
+ {
+ LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~
+ but~the~constituent~colors~do~not~all~have~a~device-based~alternative.
+ }
+\__kernel_msg_new:nnnn { color } { DeviceN-requires-names }
+ { DeviceN~color~space~'#1'~require~a~list~of~names. }
+ {
+ LaTeX~has~been~asked~to~create~a~DeviceN~color~space,~
+ but~no~\\ \\
+ \iow_indent:n { names~=~<names> }
+ \\ \\
+ key~was~given~with~the~correct~information.
+ }
\__kernel_msg_new:nnnn { color } { model-already-defined }
{ Color~model~'#1'~already~defined. }
{
diff --git a/l3kernel/testfiles/m3expl001.luatex.tlg b/l3kernel/testfiles/m3expl001.luatex.tlg
index 136d88fad..8b9a9ad24 100644
--- a/l3kernel/testfiles/m3expl001.luatex.tlg
+++ b/l3kernel/testfiles/m3expl001.luatex.tlg
@@ -36,9 +36,13 @@ Defining \__color_backend_select_rgb:n on line ...
Defining \__color_backend_select:n on line ...
Defining \__color_backend_reset: on line ...
Defining \__color_backend_select_separation:nn on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
+Defining \__color_backend_devicen_init:w on line ...
+Defining \__color_backend_devicen_init:n on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -47,6 +51,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl001.ptex.tlg b/l3kernel/testfiles/m3expl001.ptex.tlg
index ba9930c14..4d3d1ed8d 100644
--- a/l3kernel/testfiles/m3expl001.ptex.tlg
+++ b/l3kernel/testfiles/m3expl001.ptex.tlg
@@ -35,6 +35,7 @@ Defining \__color_backend_select_rgb:n on line ...
Defining \__color_backend_select:n on line ...
Defining \__color_backend_reset: on line ...
Defining \__color_backend_select_separation:nn on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \exp_args:Nnxx on line ...
Defining \__color_backend_separation_init:nxxnn on line ...
@@ -51,6 +52,7 @@ Defining \__color_backend_separation_init:w on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init:nw on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -59,6 +61,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl001.tlg b/l3kernel/testfiles/m3expl001.tlg
index c2329c9e8..1dc04ecb1 100644
--- a/l3kernel/testfiles/m3expl001.tlg
+++ b/l3kernel/testfiles/m3expl001.tlg
@@ -36,9 +36,13 @@ Defining \__color_backend_select_rgb:n on line ...
Defining \__color_backend_select:n on line ...
Defining \__color_backend_reset: on line ...
Defining \__color_backend_select_separation:nn on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
+Defining \__color_backend_devicen_init:w on line ...
+Defining \__color_backend_devicen_init:n on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -47,6 +51,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl001.uptex.tlg b/l3kernel/testfiles/m3expl001.uptex.tlg
index ba9930c14..4d3d1ed8d 100644
--- a/l3kernel/testfiles/m3expl001.uptex.tlg
+++ b/l3kernel/testfiles/m3expl001.uptex.tlg
@@ -35,6 +35,7 @@ Defining \__color_backend_select_rgb:n on line ...
Defining \__color_backend_select:n on line ...
Defining \__color_backend_reset: on line ...
Defining \__color_backend_select_separation:nn on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \exp_args:Nnxx on line ...
Defining \__color_backend_separation_init:nxxnn on line ...
@@ -51,6 +52,7 @@ Defining \__color_backend_separation_init:w on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init:nw on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -59,6 +61,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl001.xetex.tlg b/l3kernel/testfiles/m3expl001.xetex.tlg
index 72681207d..13b2e496a 100644
--- a/l3kernel/testfiles/m3expl001.xetex.tlg
+++ b/l3kernel/testfiles/m3expl001.xetex.tlg
@@ -32,9 +32,13 @@ Defining \__color_backend_reset: on line ...
Defining \__color_backend_pickup:N on line ...
Defining \__color_backend_select_separation:nn on line ...
Defining \__color_backend_select:n on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
+Defining \__color_backend_devicen_init:w on line ...
+Defining \__color_backend_devicen_init:n on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -43,6 +47,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.luatex.tlg b/l3kernel/testfiles/m3expl003.luatex.tlg
index 136d88fad..8b9a9ad24 100644
--- a/l3kernel/testfiles/m3expl003.luatex.tlg
+++ b/l3kernel/testfiles/m3expl003.luatex.tlg
@@ -36,9 +36,13 @@ Defining \__color_backend_select_rgb:n on line ...
Defining \__color_backend_select:n on line ...
Defining \__color_backend_reset: on line ...
Defining \__color_backend_select_separation:nn on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
+Defining \__color_backend_devicen_init:w on line ...
+Defining \__color_backend_devicen_init:n on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -47,6 +51,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.ptex.tlg b/l3kernel/testfiles/m3expl003.ptex.tlg
index ba9930c14..4d3d1ed8d 100644
--- a/l3kernel/testfiles/m3expl003.ptex.tlg
+++ b/l3kernel/testfiles/m3expl003.ptex.tlg
@@ -35,6 +35,7 @@ Defining \__color_backend_select_rgb:n on line ...
Defining \__color_backend_select:n on line ...
Defining \__color_backend_reset: on line ...
Defining \__color_backend_select_separation:nn on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \exp_args:Nnxx on line ...
Defining \__color_backend_separation_init:nxxnn on line ...
@@ -51,6 +52,7 @@ Defining \__color_backend_separation_init:w on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init:nw on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -59,6 +61,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.tlg b/l3kernel/testfiles/m3expl003.tlg
index c2329c9e8..1dc04ecb1 100644
--- a/l3kernel/testfiles/m3expl003.tlg
+++ b/l3kernel/testfiles/m3expl003.tlg
@@ -36,9 +36,13 @@ Defining \__color_backend_select_rgb:n on line ...
Defining \__color_backend_select:n on line ...
Defining \__color_backend_reset: on line ...
Defining \__color_backend_select_separation:nn on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
+Defining \__color_backend_devicen_init:w on line ...
+Defining \__color_backend_devicen_init:n on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -47,6 +51,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.uptex.tlg b/l3kernel/testfiles/m3expl003.uptex.tlg
index ba9930c14..4d3d1ed8d 100644
--- a/l3kernel/testfiles/m3expl003.uptex.tlg
+++ b/l3kernel/testfiles/m3expl003.uptex.tlg
@@ -35,6 +35,7 @@ Defining \__color_backend_select_rgb:n on line ...
Defining \__color_backend_select:n on line ...
Defining \__color_backend_reset: on line ...
Defining \__color_backend_select_separation:nn on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \exp_args:Nnxx on line ...
Defining \__color_backend_separation_init:nxxnn on line ...
@@ -51,6 +52,7 @@ Defining \__color_backend_separation_init:w on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init:nw on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -59,6 +61,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.xetex.tlg b/l3kernel/testfiles/m3expl003.xetex.tlg
index 72681207d..13b2e496a 100644
--- a/l3kernel/testfiles/m3expl003.xetex.tlg
+++ b/l3kernel/testfiles/m3expl003.xetex.tlg
@@ -32,9 +32,13 @@ Defining \__color_backend_reset: on line ...
Defining \__color_backend_pickup:N on line ...
Defining \__color_backend_select_separation:nn on line ...
Defining \__color_backend_select:n on line ...
+Defining \__color_backend_select_devicen:nn on line ...
Defining \__color_backend_separation_init:nnnnn on line ...
Defining \__color_backend_separation_init:n on line ...
Defining \__color_backend_separation_init_CIELAB:nnn on line ...
+Defining \__color_backend_devicen_init:nnn on line ...
+Defining \__color_backend_devicen_init:w on line ...
+Defining \__color_backend_devicen_init:n on line ...
Defining \__color_backend_fill_cmyk:n on line ...
Defining \__color_backend_fill_gray:n on line ...
Defining \__color_backend_fill_rgb:n on line ...
@@ -43,6 +47,8 @@ Defining \__color_backend_stroke_gray:n on line ...
Defining \__color_backend_stroke_rgb:n on line ...
Defining \__color_backend_fill_separation:nn on line ...
Defining \__color_backend_stroke_separation:nn on line ...
+Defining \__color_backend_fill_devicen:nn on line ...
+Defining \__color_backend_stroke_devicen:nn on line ...
Defining \__box_backend_clip:N on line ...
Defining \__box_backend_rotate:Nn on line ...
Defining \__box_backend_rotate_aux:Nn on line ...
More information about the latex3-commits
mailing list.