[latex3-commits] [git/LaTeX3-latex3-latex3] color-models: Add \color_model_new:nnn (2235c9ec4)

Joseph Wright joseph.wright at morningstar2.co.uk
Wed Jun 24 15:52:00 CEST 2020


Repository : https://github.com/latex3/latex3
On branch  : color-models
Link       : https://github.com/latex3/latex3/commit/2235c9ec4314eb8d04e039b0bb554441145d76b2

>---------------------------------------------------------------

commit 2235c9ec4314eb8d04e039b0bb554441145d76b2
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Thu Jun 11 18:25:33 2020 +0100

    Add \color_model_new:nnn
    
    No backend code at present, and no proper mixing:
    that's a second step!


>---------------------------------------------------------------

2235c9ec4314eb8d04e039b0bb554441145d76b2
 l3backend/l3backend-color.dtx                      |  25 +-
 l3experimental/CHANGELOG.md                        |   1 +
 l3experimental/l3color/l3color.dtx                 | 260 +++++++++++++++++++--
 l3experimental/l3color/testfiles/m3color003.lvt    |  42 ++++
 .../l3color/testfiles/m3color003.ptex.tlg          |  97 ++++++++
 l3experimental/l3color/testfiles/m3color003.tlg    |  97 ++++++++
 .../l3color/testfiles/m3color003.uptex.tlg         |  97 ++++++++
 .../l3color/testfiles/m3color003.xetex.tlg         |  97 ++++++++
 l3kernel/testfiles/m3expl001.luatex.tlg            |   3 +-
 l3kernel/testfiles/m3expl001.ptex.tlg              |   2 +-
 l3kernel/testfiles/m3expl001.tlg                   |   3 +-
 l3kernel/testfiles/m3expl001.uptex.tlg             |   2 +-
 l3kernel/testfiles/m3expl001.xetex.tlg             |   2 +-
 l3kernel/testfiles/m3expl003.luatex.tlg            |   3 +-
 l3kernel/testfiles/m3expl003.ptex.tlg              |   2 +-
 l3kernel/testfiles/m3expl003.tlg                   |   3 +-
 l3kernel/testfiles/m3expl003.uptex.tlg             |   2 +-
 l3kernel/testfiles/m3expl003.xetex.tlg             |   2 +-
 18 files changed, 703 insertions(+), 37 deletions(-)

diff --git a/l3backend/l3backend-color.dtx b/l3backend/l3backend-color.dtx
index 4aef1ed93..c0e68b723 100644
--- a/l3backend/l3backend-color.dtx
+++ b/l3backend/l3backend-color.dtx
@@ -116,7 +116,6 @@
 %     \@@_backend_cmyk:n  ,
 %     \@@_backend_gray:n  ,
 %     \@@_backend_rgb:n   ,
-%     \@@_backend_spot:n  ,
 %     \@@_backend_select:n
 %   }
 % \begin{macro}{\@@_backend_reset:}
@@ -130,8 +129,6 @@
   { \@@_backend_select:n { gray ~ #1 } }
 \cs_new_protected:Npn \@@_backend_rgb:n #1
   { \@@_backend_select:n { rgb ~ #1 } }
-\cs_new_protected:Npn \@@_backend_spot:n #1
-  { \@@_backend_select:n {#1} }
 \cs_new_protected:Npn \@@_backend_select:n #1
   {
     \__kernel_backend_literal:n { color~push~ #1 }
@@ -147,6 +144,14 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\@@_backend_family_separation:nn}
+%   Set up for meta-models: at present relies on a |.pro| file to do the work.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_family_separation:nn #1#2
+  { \@@_backend_select:n {#1} }
+%    \end{macrocode}
+% \end{macro}
+%
 %    \begin{macrocode}
 %</dvisvgm|dvipdfmx|dvips|xdvipdfmx>
 %    \end{macrocode}
@@ -220,9 +225,7 @@
 %     \@@_backend_cmyk:n ,
 %     \@@_backend_gray:n ,
 %     \@@_backend_rgb:n  ,
-%     \@@_backend_spot:n
 %   }
-% \begin{macro}{\@@_backend_spot:w}
 % \begin{macro}{\@@_backend_select:n}
 % \begin{macro}{\@@_backend_reset:}
 %   Simply dump the data, but allowing for \LuaTeX{}.
@@ -233,10 +236,6 @@
   { \@@_backend_select:n { #1 ~ g ~ #1 ~ G } }
 \cs_new_protected:Npn \@@_backend_rgb:n #1
   { \@@_backend_select:n { #1 ~ rg ~ #1 ~ RG } }
-\cs_new_protected:Npn \@@_backend_spot:n #1
-  { \@@_backend_spot:w #1 \s_@@_stop }
-\cs_new_protected:Npn \@@_backend_spot:w #1 ~ #2 \s_@@_stop
-  { \@@_backend_select:n { /#1 ~ cs ~ /#1 ~ CS ~ #2 ~ scn ~ #2 ~ SCN } }
 \cs_new_protected:Npx \@@_backend_select:n #1
   {
     \cs_if_exist:NTF \tex_pdfextension:D
@@ -258,6 +257,14 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\@@_backend_family_separation:nn}
+%   Set up for meta-models.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_family_separation:nn #1#2
+  { \@@_backend_select:n { /#1 ~ cs ~ /#1 ~ CS ~ #2 ~ scn ~ #2 ~ SCN } }
+%    \end{macrocode}
+% \end{macro}
+%
 %    \begin{macrocode}
 %</pdfmode>
 %    \end{macrocode}
diff --git a/l3experimental/CHANGELOG.md b/l3experimental/CHANGELOG.md
index fbb8cfbb7..30765e9a6 100644
--- a/l3experimental/CHANGELOG.md
+++ b/l3experimental/CHANGELOG.md
@@ -22,6 +22,7 @@ this project uses date-based 'snapshot' version identifiers.
 ### Added
 - `\cctab_select:N`
 - Support for `Hsb`, `HSB`, `HTML` and `RGB` color models
+- Generalise color model support
 
 ## [2020-05-18]
 
diff --git a/l3experimental/l3color/l3color.dtx b/l3experimental/l3color/l3color.dtx
index cee80af8b..175e70bdd 100644
--- a/l3experimental/l3color/l3color.dtx
+++ b/l3experimental/l3color/l3color.dtx
@@ -71,9 +71,6 @@
 %     the components
 %   \item \texttt{cmyk} Cyan-magenta-yellow-black color, with four axes, one for
 %     each of the components
-%   \item \texttt{spot} Spot color, with one value, the name of the color
-%     (see \url{https://helpx.adobe.com/indesign/using/spot-process-colors.html}
-%     for details of the use of spot colors in print)
 % \end{itemize}
 % There are also interface models: these are convenient for users but have
 % to be manipulated before storing/passing to the backend. Interface models
@@ -93,9 +90,9 @@
 % \end{itemize}
 % All interface models are internally stored as |rgb|.
 % 
-% Additional models may be created to allow mixing of spot colors
-% with each other or with those from other models. See
-% Section~\ref{l3color:sec:spot} for more detail of spot color support.
+% Additional models may be created to allow for more complex constructs, for
+% example support for spot colors. See Section~\ref{l3color:sec:addn} for more
+% detail.
 %
 % When color is selected by model, the \meta{values} given are specified as
 % a comma-separated list. The length of the list will therefore be determined
@@ -302,8 +299,38 @@
 %   assigns the data to the \meta{tl}.
 % \end{function}
 %
-% \section{Spot colors}
-% \label{l3color:sec:spot}
+% \section{Additional color models}
+% \label{l3color:sec:addn}
+%
+% Additional color models are required to support specialist workflows, for
+% example those involving separations (see
+% \url{https://helpx.adobe.com/indesign/using/spot-process-colors.html}
+% for details of the use of separations in print). Color models may be split
+% into families; in the case of the basic \texttt{cmyk}, \texttt{gray}
+% and \texttt{rgb} models, the family and the model itself are synonymous. This
+% is not generally the case: see the PDF reference for more details. 
+% 
+% \begin{function}{\color_model_new:nnn}
+%   \begin{syntax}
+%     \cs{color_model_new:nnn} \Arg{name} \Arg{family} \Arg{params}
+%   \end{syntax}
+%   Creates a new \meta{model} which is derived from the color model \meta{family}.
+%   The latter should be one of
+%   \begin{itemize}
+%     \item \texttt{Separation}
+%   \end{itemize}
+%   (The \meta{family} may be given in mixed case as-in the PDF reference:
+%   internally, case of these strings is folded.)
+%   Depending on the \meta{family}, one or more \meta{params} are mandatory or
+%   optional.
+% \end{function}
+%
+% For a \texttt{Separation} space, there is one \emph{compulsory} key, the
+% \texttt{alternative-space}. This should the form
+% \meta{model}\texttt{:}\meta{values}, for example \texttt{rgb:0.1,0.2,0.3}.
+% This information is used by the PDF application if the \texttt{Separation}
+% is not available, and also creates a second model under the multiple
+% model approach described earlier.
 %
 % \end{documentation}
 %
@@ -398,6 +425,13 @@
 %
 % \subsection{Model conversion}
 %
+% \begin{variable}{\c_@@_numerical_model_clist}
+%   Core models which can be converted to: all are parameter-based.
+%    \begin{macrocode}
+\clist_const:Nn \c_@@_numerical_model_clist { cmyk , gray , rgb }
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{macro}{\@@_convert:nnN, \@@_convert:VVN}
 % \begin{macro}{\@@_convert:nnnN, \@@_convert:nVnN, \@@_convert:nnVN}
 % \begin{macro}[aux, EXP]
@@ -419,10 +453,10 @@
 \cs_generate_variant:Nn \@@_convert:nnN { VV }
 \cs_new_protected:Npn \@@_convert:nnnN #1#2#3#4
   {
-    \str_if_eq:nnT {#1} { spot } % TO DO!!!
-      { }
     \tl_set:Nx #4
-      { \use:c { @@_convert_ #1 _ #2 :w } #3 ~ 0 ~ 0 ~ 0 \s_@@_stop }
+      {
+        \use:c { @@_convert_ #1 _ #2 :w } #3 ~ 0 ~ 0 ~ 0 \s_@@_stop
+      }
   }
 \cs_generate_variant:Nn \@@_convert:nnnN { nV , nnV }
 \cs_new:Npn \@@_convert_gray_rgb:w #1 ~ #2 \s_@@_stop
@@ -878,8 +912,12 @@
         \exp_after:wN \@@_check_model:nn #1
         \tl_if_eq:NNF \l_@@_model_tl \l_color_fixed_model_tl
           {
-            \@@_convert:VVN \l_@@_model_tl \l_color_fixed_model_tl
-              \l_@@_value_tl
+            \clist_if_in:NVT \c_@@_numerical_model_clist
+              \l_color_fixed_model_tl
+              {
+                \@@_convert:VVN \l_@@_model_tl \l_color_fixed_model_tl
+                  \l_@@_value_tl
+              }
           }
         \tl_set:Nx #1
           { { \l_color_fixed_model_tl } { \l_@@_value_tl } }
@@ -965,6 +1003,11 @@
   }
 \cs_new_protected:Npn \@@_select:nnN #1#2#3
   {
+    \exp_args:Ne \@@_direct_aux:nnN
+      { \tl_to_str:n {#1} } {#2} #3
+  }
+\cs_new_protected:Npn \@@_direct_aux:nnN #1#2#3
+  {
     \cs_if_exist:cTF { @@_parse_model_ #1 :w }
       {
         \tl_set:Nx #3
@@ -1028,7 +1071,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_set:nnw #1#2 ! #3 \s_@@_stop
   {
-    \clist_map_inline:nn { cmyk , gray , rgb }
+    \clist_map_inline:Nn \c_@@_numerical_model_clist
       {
         \prop_get:cnNT { l_@@_named_ #2 _prop } {##1} \l_@@_internal_tl
           {
@@ -1253,6 +1296,174 @@
 % \end{macro}
 % \end{macro}
 %
+% \subsection{Additional color models}
+%
+% \begin{variable}{\l_@@_internal_prop}
+%    \begin{macrocode}
+\prop_new:N \l_@@_internal_prop
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\color_model_new:nnn, \@@_model_new:nnn}
+% \begin{macro}{\@@_model_separation:n}
+% \begin{macro}{\@@_model_separation:w}
+% \begin{macro}{\@@_model_separation:nnw}
+% \begin{macro}
+%   {
+%     \@@_model_separation_cmyk:nnnnn ,
+%     \@@_model_separation_gray:nnnnn ,
+%     \@@_model_separation_rgb:nnnnn
+%   }
+%  \begin{macro}{\@@_model_convert: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
+%   fold the case of the family name. The key--value list should always be
+%   present, so we convert it up-front to a |prop|, then deal with the detail
+%   on a per-family basis.
+%    \begin{macrocode}
+\cs_new_protected:Npn \color_model_new:nnn #1#2#3
+  {
+    \exp_args:Nee \@@_model_new:nnn
+      { \tl_to_str:n {#1} }
+      { \str_foldcase:n {#2} } {#3}
+  }
+\cs_new_protected:Npn \@@_model_new:nnn #1#2#3
+  {
+    \cs_if_exist:cTF { @@_parse_model_ #1 :w }
+      {
+        \__kernel_msg_error:nnn { color } { model-already-defined } {#1}
+      }
+      {
+        \cs_if_exist:cTF { @@_model_ #2 :n }
+          {
+            \prop_set_from_keyval:Nn \l_@@_internal_prop {#3}
+            \use:c { @@_model_ #2 :n } {#1}
+          }
+          {
+            \__kernel_msg_error:nnn { color } { unknown-model-type } {#2}
+          }
+      }
+  }
+%    \end{macrocode}
+%   For separations, we know that there must be an alternative color space,
+%   and it has to be one of |cmyk|,|gray| or |rgb|. The format
+%   is slightly tricky, so we use |x|-type expansion to sort it.
+%    \begin{macrocode}
+\cs_new_protected:Npx \@@_model_separation:n #1
+  {
+    \prop_get:NnNTF \exp_not:N \l_@@_internal_prop { alternative-space }
+      \exp_not:N \l_@@_internal_tl
+      {
+        \exp_not:N \exp_after:wN \exp_not:N \@@_model_separation:w
+          \exp_not:N \l_@@_internal_tl
+          \token_to_str:N : \token_to_str:N :
+          \exp_not:N \s_@@_stop {#1}
+      }
+      {
+        \__kernel_msg_error:nnn { color }
+          { separation-requires-alternative } {#1}
+      }
+  }
+\use:x
+  {
+    \cs_new_protected:Npn \exp_not:N \@@_model_separation:w
+      ##1 \token_to_str:N : ##2 \token_to_str:N : ##3
+      \exp_not:N \s_@@_stop ##4
+  }
+  {
+    \bool_lazy_or:nnTF
+      { \tl_if_blank_p:n {#1} }
+      { \tl_if_blank_p:n {#2} }
+      {
+        \__kernel_msg_error:nnn { color }
+          { separation-requires-alternative } {#1}
+      }
+      { \@@_model_separation:nnw {#4} {#1} #2 , 0 , 0 , 0 , 0 \s_@@_stop }
+  }
+%    \end{macrocode}
+%   As each alternative space leads to a different requirement for conversion,
+%   and as there are only a small number of choices, we manually split the data
+%   and then set up.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_model_separation:nnw
+  #1#2 #3 , #4 , #5 , #6 , #7 \s_@@_stop
+  {
+    \cs_if_exist:cTF { @@_model_separation_ #2 :nnnnn }
+      {
+        \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop
+          { {#1} { \@@_parse_number:n {##1} } }
+        \cs_new_protected:cpn { @@_backend_ #1 :n } ##1
+          { \@@_backend_family_separation:nn {#1} {##1} }
+        \use:c { @@_model_separation_ #2 :nnnnn }
+          {#1} {#3} {#4} {#5} {#6}
+      }
+      {
+        \__kernel_msg_error:nnn { color }
+          { separation-requires-alternative } {#1}
+      }
+  }
+\cs_new_protected:Npn \@@_model_separation_cmyk:nnnnn #1#2#3#4#5
+  {
+    \cs_new:cpn { @@_convert_ #1 _cmyk:w } ##1 ~ ##2 \s_@@_stop
+      {
+         \fp_eval:n {##1 * #2} ~
+         \fp_eval:n {##1 * #3} ~
+         \fp_eval:n {##1 * #4} ~
+         \fp_eval:n {##1 * #5}
+      }
+    \@@_model_convert:nnn {#1} { cmyk } { rgb }
+    \@@_model_convert:nnn {#1} { cmyk } { gray }
+  }
+\cs_new_protected:Npn \@@_model_separation_rgb:nnnnn #1#2#3#4#5
+  {
+    \cs_new:cpn { @@_convert_ #1 _rgb:w } ##1 ~ ##2 \s_@@_stop
+      {
+         \fp_eval:n {##1 * #2} ~
+         \fp_eval:n {##1 * #3} ~
+         \fp_eval:n {##1 * #4}
+      }
+    \@@_model_convert:nnn {#1} { rgb } { cmyk }
+    \@@_model_convert:nnn {#1} { rgb } { gray }
+  }
+\cs_new_protected:Npn \@@_model_separation_gray:nnnnn #1#2#3#4#5
+  {
+    \cs_new:cpn { @@_convert_ #1 _cmyk:w } ##1 ~ ##2 \s_@@_stop
+      {
+        \fp_eval:n {##1 * #2} ~
+        \fp_eval:n {##1 * #2} ~
+        \fp_eval:n {##1 * #2} ~
+        \fp_eval:n {##1 * #2}
+      }
+    \cs_new:cpn { @@_convert_ #1 _gray:w } ##1 ~ ##2 \s_@@_stop
+      { \fp_eval:n {##1 * #2} }
+    \cs_new:cpn { @@_convert_ #1 _rgb:w } ##1 ~ ##2 \s_@@_stop
+      {
+        \fp_eval:n {##1 * #2} ~
+        \fp_eval:n {##1 * #2} ~
+        \fp_eval:n {##1 * #2}
+      }
+  }
+%    \end{macrocode}
+%   Generic model conversion \emph{via} an alternative intermediate.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_model_convert:nnn #1#2#3
+  {
+    \cs_new:cpx { @@_convert_ #1 _ #3 :w } ##1 ~ ##2 \s_@@_stop
+      {
+        \exp_not:N \exp_args:NNe \exp_not:N \use:nn
+        \exp_not:c { @@_convert_  #2 _ #3 :w }
+          { \exp_not:c { @@_convert_ #1 _ #2 :w } ##1 ~ ##2 \s_@@_stop }
+          \c_space_tl \exp_not:N \s_@@_stop
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Diagnostics}
 %
 % \begin{macro}{\color_show:n}
@@ -1287,6 +1498,21 @@
 % \subsection{Messages}
 %
 % \begin{macrocode}
+\__kernel_msg_new:nnnn { color } { model-already-defined }
+  { Color~model~'#1'~already~defined. }
+  {
+    LaTeX~was~asked~to~define~a~new~color~model~called~'#1',~but~
+    this~color~model~already~exists.
+  }
+\__kernel_msg_new:nnnn { color } { separation-requires-alternative }
+  { Separation~color~space~'#1'~require~an~alternative~space. }
+  {
+    LaTeX~has~been~asked~to~create~a~separation~color~space,~
+    but~no~\\ \\
+    \iow_indent:n { alternative-space = <model>:<value(s)> }
+    \\ \\
+    key~was~given~with~the~correct~information.
+  }
 \__kernel_msg_new:nnnn { color } { unknown-color }
   { Unknown~color~'#1'. }
   {
@@ -1305,6 +1531,12 @@
     LaTeX~has~been~asked~to~use~a~color~model~called~'#1',~
     but~this~model~is~not~set~up.
   }
+\__kernel_msg_new:nnnn { color } { unknown-model-type }
+  { Unknown~color~model~type~'#1'. }
+  {
+    LaTeX~has~been~asked~to~use~create~a~new~color~model~of~type~'#1',~
+    but~this~type~of~model~is~not~set~up.
+  }
 % \end{macrocode}
 %
 % \begin{macrocode}
diff --git a/l3experimental/l3color/testfiles/m3color003.lvt b/l3experimental/l3color/testfiles/m3color003.lvt
index 9c6273649..04c60348d 100644
--- a/l3experimental/l3color/testfiles/m3color003.lvt
+++ b/l3experimental/l3color/testfiles/m3color003.lvt
@@ -110,4 +110,46 @@
     \color_show:n { foo1 }
   }
 
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\TEST { Creating~new~models }
+  {
+    \OMIT
+      \cs_set_protected:Npn \test:nn #1#2
+        {
+          \color_model_new:nnn { BarTone #1 } { Separation }
+            { alternative-space = {#2} }
+          \color_set:nnn { foo #1 } { BarTone #1 } { 0.5 }
+          \color_show:n { foo #1 }
+        }
+      \cs_generate_variant:Nn \test:nn { nx }
+    \TIMO
+    \test:nx { CMYK } { cmyk \token_to_str:N : 0.1 , 0.2 , 0.3 , 0.4 }
+    \test:nx { RGB  } { rgb  \token_to_str:N : 0.1 , 0.2 , 0.3 }
+    \test:nx { Gray } { gray \token_to_str:N : 0.1 }
+  }
+
+\TEST { Creating~new~models:~errors }
+  {
+    \color_model_new:nnn { BarToneCMYK } { Separation } { }
+    \color_model_new:nnn { foo1 } { nope } { who-cares }
+    \color_model_new:nnn { foo2 } { separation } { }
+    \color_model_new:nnn { foo3 } { separation } { alternative-space }
+    \color_model_new:nnn { foo4 } { separation } { alternative-space = foo }
+  }
+
+\TEST { Converting~new~models }
+  {
+    \OMIT
+    \color_set:nnn { fooCMYK } { BarToneCMYK } { 0.5 }
+    \TIMO
+    \color_export:nnN { fooCMYK } { HTML } \l_tmpa_tl
+    \tl_show:N \l_tmpa_tl
+    \color_export:nnN { fooCMYK } { space-sep-cmyk } \l_tmpa_tl
+    \tl_show:N \l_tmpa_tl
+    \color_export:nnnN { BarToneCMYK } { 0.125 } { HTML } \l_tmpa_tl
+    \tl_show:N \l_tmpa_tl
+  }
+
 \END
diff --git a/l3experimental/l3color/testfiles/m3color003.ptex.tlg b/l3experimental/l3color/testfiles/m3color003.ptex.tlg
index 8ac01fe6c..2b6aec37c 100644
--- a/l3experimental/l3color/testfiles/m3color003.ptex.tlg
+++ b/l3experimental/l3color/testfiles/m3color003.ptex.tlg
@@ -150,3 +150,100 @@ The color foo1 has the properties:
 <recently read> }
 l. ...  }
 ============================================================
+============================================================
+TEST 6: Creating new models
+============================================================
+Defining \__color_parse_model_BarToneCMYK:w on line ...
+Defining \__color_backend_BarToneCMYK:n on line ...
+Defining \__color_convert_BarToneCMYK_cmyk:w on line ...
+Defining \__color_convert_BarToneCMYK_rgb:w on line ...
+Defining \__color_convert_BarToneCMYK_gray:w on line ...
+Defining \l__color_named_fooCMYK_tl on line ...
+Defining \l__color_named_fooCMYK_prop on line ...
+The color fooCMYK has the properties:
+>  model  =>  BarToneCMYK
+>  BarToneCMYK  =>  0.5.
+<recently read> }
+l. ...  }
+Defining \__color_parse_model_BarToneRGB:w on line ...
+Defining \__color_backend_BarToneRGB:n on line ...
+Defining \__color_convert_BarToneRGB_rgb:w on line ...
+Defining \__color_convert_BarToneRGB_cmyk:w on line ...
+Defining \__color_convert_BarToneRGB_gray:w on line ...
+Defining \l__color_named_fooRGB_tl on line ...
+Defining \l__color_named_fooRGB_prop on line ...
+The color fooRGB has the properties:
+>  model  =>  BarToneRGB
+>  BarToneRGB  =>  0.5.
+<recently read> }
+l. ...  }
+Defining \__color_parse_model_BarToneGray:w on line ...
+Defining \__color_backend_BarToneGray:n on line ...
+Defining \__color_convert_BarToneGray_cmyk:w on line ...
+Defining \__color_convert_BarToneGray_gray:w on line ...
+Defining \__color_convert_BarToneGray_rgb:w on line ...
+Defining \l__color_named_fooGray_tl on line ...
+Defining \l__color_named_fooGray_prop on line ...
+The color fooGray has the properties:
+>  model  =>  BarToneGray
+>  BarToneGray  =>  0.5.
+<recently read> }
+l. ...  }
+============================================================
+============================================================
+TEST 7: Creating new models: errors
+============================================================
+! LaTeX3 Error: Color model 'BarToneCMYK' already defined.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX was asked to define a new color model called 'BarToneCMYK', but this
+color model already exists.
+! LaTeX3 Error: Unknown color model type 'nope'.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to use create a new color model of type 'nope', but this
+type of model is not set up.
+! LaTeX3 Error: Separation color space 'foo2' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+! LaTeX3 Error: Missing/extra '=' in 'alternative-space' (in '..._keyval:Nn')
+Type <return> to continue.
+ ...                                              
+l. ...  }
+LaTeX does not know anything more about this error, sorry.
+Try typing <return> to proceed.
+If that doesn't work, type X <return> to quit.
+! LaTeX3 Error: Separation color space 'foo3' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+! LaTeX3 Error: Separation color space 'foo' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+============================================================
+============================================================
+TEST 8: Converting new models
+============================================================
+> \l_tmpa_tl=BFB2A6.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0.05 0.1 0.15 0.2.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=EFECE9.
+<recently read> }
+l. ...  }
+============================================================
diff --git a/l3experimental/l3color/testfiles/m3color003.tlg b/l3experimental/l3color/testfiles/m3color003.tlg
index 045f93432..838d40b9f 100644
--- a/l3experimental/l3color/testfiles/m3color003.tlg
+++ b/l3experimental/l3color/testfiles/m3color003.tlg
@@ -145,3 +145,100 @@ The color foo1 has the properties:
 <recently read> }
 l. ...  }
 ============================================================
+============================================================
+TEST 6: Creating new models
+============================================================
+Defining \__color_parse_model_BarToneCMYK:w on line ...
+Defining \__color_backend_BarToneCMYK:n on line ...
+Defining \__color_convert_BarToneCMYK_cmyk:w on line ...
+Defining \__color_convert_BarToneCMYK_rgb:w on line ...
+Defining \__color_convert_BarToneCMYK_gray:w on line ...
+Defining \l__color_named_fooCMYK_tl on line ...
+Defining \l__color_named_fooCMYK_prop on line ...
+The color fooCMYK has the properties:
+>  model  =>  BarToneCMYK
+>  BarToneCMYK  =>  0.5.
+<recently read> }
+l. ...  }
+Defining \__color_parse_model_BarToneRGB:w on line ...
+Defining \__color_backend_BarToneRGB:n on line ...
+Defining \__color_convert_BarToneRGB_rgb:w on line ...
+Defining \__color_convert_BarToneRGB_cmyk:w on line ...
+Defining \__color_convert_BarToneRGB_gray:w on line ...
+Defining \l__color_named_fooRGB_tl on line ...
+Defining \l__color_named_fooRGB_prop on line ...
+The color fooRGB has the properties:
+>  model  =>  BarToneRGB
+>  BarToneRGB  =>  0.5.
+<recently read> }
+l. ...  }
+Defining \__color_parse_model_BarToneGray:w on line ...
+Defining \__color_backend_BarToneGray:n on line ...
+Defining \__color_convert_BarToneGray_cmyk:w on line ...
+Defining \__color_convert_BarToneGray_gray:w on line ...
+Defining \__color_convert_BarToneGray_rgb:w on line ...
+Defining \l__color_named_fooGray_tl on line ...
+Defining \l__color_named_fooGray_prop on line ...
+The color fooGray has the properties:
+>  model  =>  BarToneGray
+>  BarToneGray  =>  0.5.
+<recently read> }
+l. ...  }
+============================================================
+============================================================
+TEST 7: Creating new models: errors
+============================================================
+! LaTeX3 Error: Color model 'BarToneCMYK' already defined.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX was asked to define a new color model called 'BarToneCMYK', but this
+color model already exists.
+! LaTeX3 Error: Unknown color model type 'nope'.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to use create a new color model of type 'nope', but this
+type of model is not set up.
+! LaTeX3 Error: Separation color space 'foo2' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+! LaTeX3 Error: Missing/extra '=' in 'alternative-space' (in '..._keyval:Nn')
+Type <return> to continue.
+ ...                                              
+l. ...  }
+LaTeX does not know anything more about this error, sorry.
+Try typing <return> to proceed.
+If that doesn't work, type X <return> to quit.
+! LaTeX3 Error: Separation color space 'foo3' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+! LaTeX3 Error: Separation color space 'foo' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+============================================================
+============================================================
+TEST 8: Converting new models
+============================================================
+> \l_tmpa_tl=BFB2A6.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0.05 0.1 0.15 0.2.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=EFECE9.
+<recently read> }
+l. ...  }
+============================================================
diff --git a/l3experimental/l3color/testfiles/m3color003.uptex.tlg b/l3experimental/l3color/testfiles/m3color003.uptex.tlg
index 8ac01fe6c..2b6aec37c 100644
--- a/l3experimental/l3color/testfiles/m3color003.uptex.tlg
+++ b/l3experimental/l3color/testfiles/m3color003.uptex.tlg
@@ -150,3 +150,100 @@ The color foo1 has the properties:
 <recently read> }
 l. ...  }
 ============================================================
+============================================================
+TEST 6: Creating new models
+============================================================
+Defining \__color_parse_model_BarToneCMYK:w on line ...
+Defining \__color_backend_BarToneCMYK:n on line ...
+Defining \__color_convert_BarToneCMYK_cmyk:w on line ...
+Defining \__color_convert_BarToneCMYK_rgb:w on line ...
+Defining \__color_convert_BarToneCMYK_gray:w on line ...
+Defining \l__color_named_fooCMYK_tl on line ...
+Defining \l__color_named_fooCMYK_prop on line ...
+The color fooCMYK has the properties:
+>  model  =>  BarToneCMYK
+>  BarToneCMYK  =>  0.5.
+<recently read> }
+l. ...  }
+Defining \__color_parse_model_BarToneRGB:w on line ...
+Defining \__color_backend_BarToneRGB:n on line ...
+Defining \__color_convert_BarToneRGB_rgb:w on line ...
+Defining \__color_convert_BarToneRGB_cmyk:w on line ...
+Defining \__color_convert_BarToneRGB_gray:w on line ...
+Defining \l__color_named_fooRGB_tl on line ...
+Defining \l__color_named_fooRGB_prop on line ...
+The color fooRGB has the properties:
+>  model  =>  BarToneRGB
+>  BarToneRGB  =>  0.5.
+<recently read> }
+l. ...  }
+Defining \__color_parse_model_BarToneGray:w on line ...
+Defining \__color_backend_BarToneGray:n on line ...
+Defining \__color_convert_BarToneGray_cmyk:w on line ...
+Defining \__color_convert_BarToneGray_gray:w on line ...
+Defining \__color_convert_BarToneGray_rgb:w on line ...
+Defining \l__color_named_fooGray_tl on line ...
+Defining \l__color_named_fooGray_prop on line ...
+The color fooGray has the properties:
+>  model  =>  BarToneGray
+>  BarToneGray  =>  0.5.
+<recently read> }
+l. ...  }
+============================================================
+============================================================
+TEST 7: Creating new models: errors
+============================================================
+! LaTeX3 Error: Color model 'BarToneCMYK' already defined.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX was asked to define a new color model called 'BarToneCMYK', but this
+color model already exists.
+! LaTeX3 Error: Unknown color model type 'nope'.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to use create a new color model of type 'nope', but this
+type of model is not set up.
+! LaTeX3 Error: Separation color space 'foo2' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+! LaTeX3 Error: Missing/extra '=' in 'alternative-space' (in '..._keyval:Nn')
+Type <return> to continue.
+ ...                                              
+l. ...  }
+LaTeX does not know anything more about this error, sorry.
+Try typing <return> to proceed.
+If that doesn't work, type X <return> to quit.
+! LaTeX3 Error: Separation color space 'foo3' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+! LaTeX3 Error: Separation color space 'foo' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+============================================================
+============================================================
+TEST 8: Converting new models
+============================================================
+> \l_tmpa_tl=BFB2A6.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0.05 0.1 0.15 0.2.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=EFECE9.
+<recently read> }
+l. ...  }
+============================================================
diff --git a/l3experimental/l3color/testfiles/m3color003.xetex.tlg b/l3experimental/l3color/testfiles/m3color003.xetex.tlg
index 47e130f05..0491073cf 100644
--- a/l3experimental/l3color/testfiles/m3color003.xetex.tlg
+++ b/l3experimental/l3color/testfiles/m3color003.xetex.tlg
@@ -145,3 +145,100 @@ The color foo1 has the properties:
 <recently read> }
 l. ...  }
 ============================================================
+============================================================
+TEST 6: Creating new models
+============================================================
+Defining \__color_parse_model_BarToneCMYK:w on line ...
+Defining \__color_backend_BarToneCMYK:n on line ...
+Defining \__color_convert_BarToneCMYK_cmyk:w on line ...
+Defining \__color_convert_BarToneCMYK_rgb:w on line ...
+Defining \__color_convert_BarToneCMYK_gray:w on line ...
+Defining \l__color_named_fooCMYK_tl on line ...
+Defining \l__color_named_fooCMYK_prop on line ...
+The color fooCMYK has the properties:
+>  model  =>  BarToneCMYK
+>  BarToneCMYK  =>  0.5.
+<recently read> }
+l. ...  }
+Defining \__color_parse_model_BarToneRGB:w on line ...
+Defining \__color_backend_BarToneRGB:n on line ...
+Defining \__color_convert_BarToneRGB_rgb:w on line ...
+Defining \__color_convert_BarToneRGB_cmyk:w on line ...
+Defining \__color_convert_BarToneRGB_gray:w on line ...
+Defining \l__color_named_fooRGB_tl on line ...
+Defining \l__color_named_fooRGB_prop on line ...
+The color fooRGB has the properties:
+>  model  =>  BarToneRGB
+>  BarToneRGB  =>  0.5.
+<recently read> }
+l. ...  }
+Defining \__color_parse_model_BarToneGray:w on line ...
+Defining \__color_backend_BarToneGray:n on line ...
+Defining \__color_convert_BarToneGray_cmyk:w on line ...
+Defining \__color_convert_BarToneGray_gray:w on line ...
+Defining \__color_convert_BarToneGray_rgb:w on line ...
+Defining \l__color_named_fooGray_tl on line ...
+Defining \l__color_named_fooGray_prop on line ...
+The color fooGray has the properties:
+>  model  =>  BarToneGray
+>  BarToneGray  =>  0.5.
+<recently read> }
+l. ...  }
+============================================================
+============================================================
+TEST 7: Creating new models: errors
+============================================================
+! LaTeX3 Error: Color model 'BarToneCMYK' already defined.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX was asked to define a new color model called 'BarToneCMYK', but this
+color model already exists.
+! LaTeX3 Error: Unknown color model type 'nope'.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to use create a new color model of type 'nope', but this
+type of model is not set up.
+! LaTeX3 Error: Separation color space 'foo2' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+! LaTeX3 Error: Missing/extra '=' in 'alternative-space' (in '..._keyval:Nn')
+Type <return> to continue.
+ ...                                              
+l. ...  }
+LaTeX does not know anything more about this error, sorry.
+Try typing <return> to proceed.
+If that doesn't work, type X <return> to quit.
+! LaTeX3 Error: Separation color space 'foo3' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+! LaTeX3 Error: Separation color space 'foo' require an alternative space.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+LaTeX has been asked to create a separation color space, but no 
+    alternative-space=<model>:<value(s)>
+key was given with the correct information.
+============================================================
+============================================================
+TEST 8: Converting new models
+============================================================
+> \l_tmpa_tl=BFB2A6.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=0.05 0.1 0.15 0.2.
+<recently read> }
+l. ...  }
+> \l_tmpa_tl=EFECE9.
+<recently read> }
+l. ...  }
+============================================================
diff --git a/l3kernel/testfiles/m3expl001.luatex.tlg b/l3kernel/testfiles/m3expl001.luatex.tlg
index c00a6d455..de8199190 100644
--- a/l3kernel/testfiles/m3expl001.luatex.tlg
+++ b/l3kernel/testfiles/m3expl001.luatex.tlg
@@ -33,10 +33,9 @@ Defining \l__kernel_color_stack_int on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
-Defining \__color_backend_spot:w on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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 aa8996c73..6c949a999 100644
--- a/l3kernel/testfiles/m3expl001.ptex.tlg
+++ b/l3kernel/testfiles/m3expl001.ptex.tlg
@@ -32,9 +32,9 @@ Defining \__color_backend_pickup:N on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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 c00a6d455..de8199190 100644
--- a/l3kernel/testfiles/m3expl001.tlg
+++ b/l3kernel/testfiles/m3expl001.tlg
@@ -33,10 +33,9 @@ Defining \l__kernel_color_stack_int on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
-Defining \__color_backend_spot:w on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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 aa8996c73..6c949a999 100644
--- a/l3kernel/testfiles/m3expl001.uptex.tlg
+++ b/l3kernel/testfiles/m3expl001.uptex.tlg
@@ -32,9 +32,9 @@ Defining \__color_backend_pickup:N on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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 60e68ec4d..9c4784540 100644
--- a/l3kernel/testfiles/m3expl001.xetex.tlg
+++ b/l3kernel/testfiles/m3expl001.xetex.tlg
@@ -29,9 +29,9 @@ Defining \__color_backend_pickup:N on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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 c00a6d455..de8199190 100644
--- a/l3kernel/testfiles/m3expl003.luatex.tlg
+++ b/l3kernel/testfiles/m3expl003.luatex.tlg
@@ -33,10 +33,9 @@ Defining \l__kernel_color_stack_int on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
-Defining \__color_backend_spot:w on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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 aa8996c73..6c949a999 100644
--- a/l3kernel/testfiles/m3expl003.ptex.tlg
+++ b/l3kernel/testfiles/m3expl003.ptex.tlg
@@ -32,9 +32,9 @@ Defining \__color_backend_pickup:N on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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 c00a6d455..de8199190 100644
--- a/l3kernel/testfiles/m3expl003.tlg
+++ b/l3kernel/testfiles/m3expl003.tlg
@@ -33,10 +33,9 @@ Defining \l__kernel_color_stack_int on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
-Defining \__color_backend_spot:w on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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 aa8996c73..6c949a999 100644
--- a/l3kernel/testfiles/m3expl003.uptex.tlg
+++ b/l3kernel/testfiles/m3expl003.uptex.tlg
@@ -32,9 +32,9 @@ Defining \__color_backend_pickup:N on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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 60e68ec4d..9c4784540 100644
--- a/l3kernel/testfiles/m3expl003.xetex.tlg
+++ b/l3kernel/testfiles/m3expl003.xetex.tlg
@@ -29,9 +29,9 @@ Defining \__color_backend_pickup:N on line ...
 Defining \__color_backend_cmyk:n on line ...
 Defining \__color_backend_gray:n on line ...
 Defining \__color_backend_rgb:n on line ...
-Defining \__color_backend_spot:n on line ...
 Defining \__color_backend_select:n on line ...
 Defining \__color_backend_reset: on line ...
+Defining \__color_backend_family_separation: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.