summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3backend/l3backend-color.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-01-10 03:01:42 +0000
committerNorbert Preining <norbert@preining.info>2021-01-10 03:01:42 +0000
commitef57fc77f3c939d55d51322d428e40a5a3c9ed8e (patch)
treec296d1bf47b8ffa67bb75b1843c2e0786fb0634c /macros/latex/contrib/l3backend/l3backend-color.dtx
parent0b5fb424a9fab0df06b2d7b9f8edc803cb89a760 (diff)
CTAN sync 202101100301
Diffstat (limited to 'macros/latex/contrib/l3backend/l3backend-color.dtx')
-rw-r--r--macros/latex/contrib/l3backend/l3backend-color.dtx382
1 files changed, 242 insertions, 140 deletions
diff --git a/macros/latex/contrib/l3backend/l3backend-color.dtx b/macros/latex/contrib/l3backend/l3backend-color.dtx
index baefde5d3c..f3087b0904 100644
--- a/macros/latex/contrib/l3backend/l3backend-color.dtx
+++ b/macros/latex/contrib/l3backend/l3backend-color.dtx
@@ -2,7 +2,7 @@
%
%% File: l3backend-color.dtx
%
-% Copyright (C) 2019,2020 The LaTeX3 Project
+% Copyright (C) 2019-2021 The LaTeX3 Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2020-09-24}
+% \date{Released 2021-01-09}
%
% \maketitle
%
@@ -60,59 +60,16 @@
%<@@=color>
% \end{macrocode}
%
-% Color support is split into parts: general color, separations, and color for
+% 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{\texttt{dvipmdfx}/\XeTeX{}}
+% \subsection{Collecting information from \LaTeXe{}}
%
-% \begin{macrocode}
-%<*dvipdfmx|xetex>
-% \end{macrocode}
-%
-% These backends have the most possible approaches: it recognises both
-% \texttt{dvips}-based color specials and it's own format, plus one can
-% include PDF statements directly. The latter are not subject to the stack,
-% so are not suitable for general use. Of the two stack methods, the dedicated
-% one has been extended to cover color spaces, so it is used in preference to
-% the \texttt{dvips} one.
-%
-% The \LaTeXe{} backend code uses \texttt{dvips}-based code with
-% \texttt{dvipmdfx}/\XeTeX{}, and so we leave getting color from \LaTeXe{} to
-% a shared code path below.
-%
-% \begin{macro}
-% {
-% \@@_backend_select_cmyk:n ,
-% \@@_backend_select_gray:n ,
-% \@@_backend_select_rgb:n
-% }
-% \begin{macro}{\@@_backend_reset:}
-% \begin{macro}{color.sc, color.fc}
-% Push the data to the stack.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_select_cmyk:n #1
- {
- \__kernel_backend_literal:n { pdf: bc ~ [#1] }
- \group_insert_after:N \@@_backend_reset:
- }
-\cs_new_eq:NN \@@_backend_select_gray:n \@@_backend_select_cmyk:n
-\cs_new_eq:NN \@@_backend_select_rgb:n \@@_backend_select_cmyk:n
-\cs_new_protected:Npn \@@_backend_reset:
- { \__kernel_backend_literal:n { pdf: ec } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macrocode}
-%</dvipdfmx|xetex>
-% \end{macrocode}
-%
-% \subsection{\texttt{dvips}-style}
+% \subsubsection{\texttt{dvips}-style}
%
% \begin{macrocode}
%<*dvisvgm|dvipdfmx|dvips|xetex>
@@ -128,7 +85,7 @@
\cs_new_protected:Npn \@@_backend_pickup:N #1 { }
\cs_if_exist:cT { ver@color.sty }
{
- \cs_set_protected:Npn \@@_backend_pickup:N #1
+ \cs_set_protected:Npn \@@_backend_pickup:N #1
{
\exp_args:NV \tl_if_head_is_space:nTF \current@color
{
@@ -154,49 +111,7 @@
%</dvisvgm|dvipdfmx|dvips|xetex>
% \end{macrocode}
%
-% \begin{macrocode}
-%<*dvisvgm|dvips>
-% \end{macrocode}
-%
-% \begin{macro}
-% {
-% \@@_backend_select_cmyk:n ,
-% \@@_backend_select_gray:n ,
-% \@@_backend_select_rgb:n ,
-% \@@_backend_select:n
-% }
-% \begin{macro}{\@@_backend_reset:}
-% \begin{macro}{color.sc, color.fc}
-% Push the data to the stack. In the case of \texttt{dvips} also saves the
-% drawing color in raw PostScript.
-% \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_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 }
- \__kernel_backend_postscript:n { /color.fc~ { ~ } ~def }
-%</dvips>
- \group_insert_after:N \@@_backend_reset:
- }
-\cs_new_protected:Npn \@@_backend_reset:
- { \__kernel_backend_literal:n { color~pop } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macrocode}
-%</dvisvgm|dvips>
-% \end{macrocode}
-%
-% \subsection{\LuaTeX{} and \pdfTeX{}}
+% \subsubsection{\LuaTeX{} and \pdfTeX{}}
%
% \begin{macrocode}
%<*luatex|pdftex>
@@ -247,9 +162,192 @@
% \end{macro}
% \end{macro}
%
+% \begin{macrocode}
+%</luatex|pdftex>
+% \end{macrocode}
+%
+% \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 th graphics
+% state generally. The exact form depends on the engine, and for
+% \texttt{dvipdfmx}/\XeTeX{} the backend version.
+%
+% \subsubsection{\texttt{dvipdfmx}/\XeTeX{}}
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_color_stack_init:Nnn}
+% \begin{variable}{\g__color_stack_int}
+% In \texttt{(x)dvipdfmx}, the base color stack is not set up, so we have to
+% force that, as well as providing a mechanism more generally.
+% \begin{macrocode}
+\int_compare:nNnF \c__kernel_sys_dvipdfmx_version_int < { 20201111 }
+ {
+ \int_new:N \g__color_stack_int
+ \cs_new_protected:Npn \__kernel_color_stack_init:Nnn #1#2#3
+ {
+ \int_gincr:N \g__color_stack_int
+ \int_const:Nn #1 { \g__color_stack_int }
+ \__kernel_backend_literal:x
+ {
+ pdfcolorstackinit ~
+ \int_use:N \g__color_stack_int \c_space_tl
+ \tl_if_blank:nF {#2} { #2 ~ }
+ (#3)
+ }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_color_stack_push:nn}
+% \begin{macro}{\__kernel_color_stack_pop:n}
+% Simple enough but needs a version check.
+% \begin{macrocode}
+\int_compare:nNnF \c__kernel_sys_dvipdfmx_version_int < { 20201111 }
+ {
+ \cs_new_protected:Npn \__kernel_color_stack_push:nn #1#2
+ {
+ \__kernel_backend_literal:x
+ {
+ pdfcolorstack ~
+ \int_eval:n {#1} ~
+ push ~ (#2)
+ }
+ }
+ \cs_new_protected:Npn \__kernel_color_stack_pop:n #1
+ {
+ \__kernel_backend_literal:x
+ {
+ pdfcolorstack ~
+ \int_eval:n {#1} ~
+ pop
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|xetex>
+% \end{macrocode}
+%
+% \subsubsection{\LuaTeX and \pdfTeX{}}
+%
+% \begin{macrocode}
+%<*luatex|pdftex>
+% \end{macrocode}
+%
+% \begin{macro}{\__kernel_color_stack_init:Nnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_color_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_stack_push:nn}
+% \begin{macro}{\__kernel_color_stack_pop:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \__kernel_color_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_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_rgb:n ,
+% \@@_backend_select:n
+% }
+% \begin{macro}{\@@_backend_reset:}
+% \begin{macro}{color.sc, color.fc}
+% Push the data to the stack. In the case of \texttt{dvips} also saves the
+% drawing color in raw PostScript.
+% \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_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 }
+ \__kernel_backend_postscript:n { /color.fc~ { ~ } ~def }
+%</dvips>
+ \group_insert_after:N \@@_backend_reset:
+ }
+\cs_new_protected:Npn \@@_backend_reset:
+ { \__kernel_backend_literal:n { color~pop } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips|dvisvgm>
+% \end{macrocode}
+%
+% \subsubsection{\LuaTeX{} and \pdfTeX{}}
+%
+% \begin{macrocode}
+%<*dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
% \begin{variable}{\l__kernel_color_stack_int}
-% \pdfTeX{} and \LuaTeX{} have multiple stacks available, and to track
-% which one is in use a variable is required.
+% \pdfTeX{}, \LuaTeX{} and recent \texttt{(x)dvipdfmx} have multiple stacks
+% available, and to track which one is in use a variable is required.
% \begin{macrocode}
\int_new:N \l__kernel_color_stack_int
% \end{macrocode}
@@ -272,31 +370,60 @@
{ \@@_backend_select:n { #1 ~ rg ~ #1 ~ RG } }
\cs_new_protected:Npn \@@_backend_select:n #1
{
-%<*luatex>
- \tex_pdfextension:D colorstack
-%</luatex>
-%<*pdftex>
- \tex_pdfcolorstack:D
-%</pdftex>
- \l__kernel_color_stack_int push {#1}
+ \__kernel_color_stack_push:nn \l__kernel_color_stack_int {#1}
\group_insert_after:N \@@_backend_reset:
}
\cs_new_protected:Npn \@@_backend_reset:
+ { \__kernel_color_stack_pop:n \l__kernel_color_stack_int }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|luatex|pdftex|xetex>
+% \end{macrocode}
+%
+% \subsubsection{\texttt{dvipmdfx}/\XeTeX{}}
+%
+% \begin{macrocode}
+%<*dvipdfmx|xetex>
+% \end{macrocode}
+%
+% These backends have the most possible approaches: it recognises both
+% \texttt{dvips}-based color specials and it's 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. Thus it is used in preference to the \texttt{dvips}-style interface
+% or the \enquote{native} color specials (which have only one stack).
+%
+% \begin{macro}
+% {
+% \@@_backend_select_cmyk:n ,
+% \@@_backend_select_gray:n ,
+% \@@_backend_select_rgb:n
+% }
+% \begin{macro}{\@@_backend_reset:}
+% Push the data to the stack.
+% \begin{macrocode}
+\int_compare:nNnT \c__kernel_sys_dvipdfmx_version_int < { 20201111 }
{
-%<*luatex>
- \tex_pdfextension:D colorstack
-%</luatex>
-%<*pdftex>
- \tex_pdfcolorstack:D
-%</pdftex>
- \l__kernel_color_stack_int pop \scan_stop:
+ \cs_gset_protected:Npn \@@_backend_select_cmyk:n #1
+ {
+ \__kernel_backend_literal:n { pdf: bc ~ [#1] }
+ \group_insert_after:N \@@_backend_reset:
+ }
+ \cs_gset_eq:NN \@@_backend_select_gray:n \@@_backend_select_cmyk:n
+ \cs_gset_eq:NN \@@_backend_select_rgb:n \@@_backend_select_cmyk:n
+ \cs_gset_protected:Npn \@@_backend_reset:
+ { \__kernel_backend_literal:n { pdf: ec } }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macrocode}
-%</luatex|pdftex>
+%</dvipdfmx|xetex>
% \end{macrocode}
%
% \subsection{Separations}
@@ -601,22 +728,12 @@
%
% \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.
+% Although \texttt{(x)dvipdfmx} has a built-in approach to color spaces, that
+% can't be used with the generic color stacks. So we take an approach in which
+% we share the same code as for \pdfTeX{}.
% \begin{macrocode}
\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2
-%<*dvipdfmx|xetex>
- { \@@_backend_select:n { @#1 ~ [#2] } }
-%</dvipdfmx|xetex>
-%<*luatex|pdftex>
{ \@@_backend_select:n { /#1 ~ cs ~ /#1 ~ CS ~ #2 ~ scn ~ #2 ~ SCN } }
-%</luatex|pdftex>
-%<*dvipdfmx|xetex>
-\cs_new_protected:Npn \@@_backend_select:n #1
- {
- \__kernel_backend_literal:n { pdf: bc ~ #1 }
- \group_insert_after:N \@@_backend_reset:
- }
-%</dvipdfmx|xetex>
\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn
% \end{macrocode}
% \end{macro}
@@ -627,9 +744,7 @@
% \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. The latter uses the internal name of the \texttt{cs}.
-% For \texttt{dvipdfmx}/\XeTeX{}, the backend does most of the work so we need a
-% simplified version. We use a separate object for the tint transformation
+% to that to each page. We use a separate object for the tint transformation
% following the model in the PDF reference.
% \begin{macrocode}
\cs_new_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5
@@ -648,30 +763,19 @@
/ \str_convert_pdfname:n {#1} ~ #2 ~
\pdf_object_last:
}
-%<*luatex|pdftex>
\use:x
{
- \pdfcoredict_gput:nnn
+ \pdfmanagement_add:nnn
{ Page / Resources / ColorSpace }
{ color \int_use:N \g_@@_model_int }
{ \pdf_object_last: }
}
-%</luatex|pdftex>
}
\cs_if_exist:NF \pdf_object_now:nn
{ \cs_gset_protected:Npn \@@_backend_separation_init:nnnnn #1#2#3#4#5 { } }
\cs_new_protected:Npn \@@_backend_separation_init:n #1
{
-%<*dvipdfmx|xetex>
- \__kernel_backend_literal:x
- {
- pdf:obj ~ @color \int_use:N \g_@@_model_int \c_space_tl
- [#1]
- }
-%</dvipdfmx|xetex>
-%<*luatex|pdftex>
\pdf_object_now:nx { array } {#1}
-%</luatex|pdftex>
}
% \end{macrocode}
% For CIELAB colors, we need one object per document for the illuminant,
@@ -746,15 +850,13 @@
#2 ~
\pdf_object_last:
}
-%<*luatex|pdftex>
\use:x
{
- \pdfcoredict_gput:nnn
+ \pdfmanagement_add:nnn
{ Page / Resources / ColorSpace }
{ color \int_use:N \g_@@_model_int }
{ \pdf_object_last: }
}
-%</luatex|pdftex>
}
\cs_if_exist:NF \pdf_object_now:nn
{ \cs_gset_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 { } }