summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx363
1 files changed, 288 insertions, 75 deletions
diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
index 6875ce75790..6defac4817a 100644
--- a/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
+++ b/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2020-06-29}
+% \date{Released 2020-08-07}
%
% \maketitle
%
@@ -56,7 +56,7 @@
% \section{\pkg{l3backend-color} Implementation}
%
% \begin{macrocode}
-%<*initex|package>
+%<*package>
%<@@=color>
% \end{macrocode}
%
@@ -81,62 +81,55 @@
% spot ones (here we need a model and a tint). The \texttt{x}-type expansion
% is there to cover the case where \pkg{xcolor} is in use.
% \begin{macrocode}
-%<*package>
\cs_new_protected:Npn \@@_backend_pickup:N #1 { }
-\AtBeginDocument
+\cs_if_exist:cT { ver@color.sty }
{
- \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
{
- \exp_args:NV \tl_if_head_is_space:nTF \current@color
- {
- \tl_set:Nx #1
- {
- { spot }
- { \exp_after:wN \use:n \current@color \c_space_tl 1 }
- }
- }
- {
- \exp_last_unbraced:Nx \@@_backend_pickup:w
- { \current@color } \s_@@_stop #1
- }
+ \tl_set:Nx #1
+ {
+ { \exp_after:wN \use:n \current@color }
+ { 1 }
+ }
+ }
+ {
+ \exp_last_unbraced:Nx \@@_backend_pickup:w
+ { \current@color } \s_@@_stop #1
}
- \cs_new_protected:Npn \@@_backend_pickup:w #1 ~ #2 \s_@@_stop #3
- { \tl_set:Nn #3 { {#1} {#2} } }
}
+ \cs_new_protected:Npn \@@_backend_pickup:w #1 ~ #2 \s_@@_stop #3
+ { \tl_set:Nn #3 { {#1} {#2} } }
}
-%</package>
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}
% {
-% \@@_backend_cmyk:n ,
-% \@@_backend_gray:n ,
-% \@@_backend_rgb:n ,
-% \@@_backend_spot:n ,
+% \@@_backend_select_cmyk:n ,
+% \@@_backend_select_gray:n ,
+% \@@_backend_select_rgb:n ,
% \@@_backend_select:n
% }
% \begin{macro}{\@@_backend_reset:}
-% \begin{macro}{color.fc}
-% Push the data to the stack. In the case of \texttt{dvips} also reset the
-% drawing fill color in raw PostScript.
+% \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_cmyk:n #1
+\cs_new_protected:Npn \@@_backend_select_cmyk:n #1
{ \@@_backend_select:n { cmyk ~ #1 } }
-\cs_new_protected:Npn \@@_backend_gray:n #1
+\cs_new_protected:Npn \@@_backend_select_gray:n #1
{ \@@_backend_select:n { gray ~ #1 } }
-\cs_new_protected:Npn \@@_backend_rgb:n #1
+\cs_new_protected:Npn \@@_backend_select_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 }
%<*dvips>
- \__kernel_backend_postscript:n { /color.fc~{ }~def }
+ \__kernel_backend_postscript:n { /color.sc~ { ~ } ~def }
+ \__kernel_backend_postscript:n { /color.fc~ { ~ } ~def }
%</dvips>
\group_insert_after:N \@@_backend_reset:
}
@@ -147,6 +140,13 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\@@_backend_select_separation:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2
+ { \@@_backend_select:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macrocode}
%</dvisvgm|dvipdfmx|dvips|xdvipdfmx>
% \end{macrocode}
@@ -166,43 +166,38 @@
% \cs{@@_backend_pickup:w} breaks it apart, because for instance
% \pkg{xcolor} sets it to be instructions to generate a color
% \begin{macrocode}
-%<*package>
\cs_new_protected:Npn \@@_backend_pickup:N #1 { }
-\AtBeginDocument
+\cs_if_exist:cT { ver@color.sty }
{
- \cs_if_exist:cT { ver@color.sty }
+ \cs_set_protected:Npn \@@_backend_pickup:N #1
{
- \cs_set_protected:Npn \@@_backend_pickup:N #1
- {
- \exp_last_unbraced:Nx \@@_backend_pickup:w
- { \current@color } ~ 0 ~ 0 ~ 0 \s_@@_stop #1
- }
- \cs_new_protected:Npn \@@_backend_pickup:w
- #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 \s_@@_stop #7
+ \exp_last_unbraced:Nx \@@_backend_pickup:w
+ { \current@color } ~ 0 ~ 0 ~ 0 \s_@@_stop #1
+ }
+ \cs_new_protected:Npn \@@_backend_pickup:w
+ #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 \s_@@_stop #7
+ {
+ \str_if_eq:nnTF {#2} { g }
+ { \tl_set:Nn #7 { { gray } {#1} } }
{
- \str_if_eq:nnTF {#2} { g }
- { \tl_set:Nn #7 { { gray } {#1} } }
+ \str_if_eq:nnTF {#4} { rg }
+ { \tl_set:Nn #7 { { rgb } { #1 ~ #2 ~ #3 } } }
{
- \str_if_eq:nnTF {#4} { rg }
- { \tl_set:Nn #7 { { rgb } { #1 ~ #2 ~ #3 } } }
- {
- \str_if_eq:nnTF {#5} { k }
- { \tl_set:Nn #7 { { cmyk } { #1 ~ #2 ~ #3 ~ #4 } } }
+ \str_if_eq:nnTF {#5} { k }
+ { \tl_set:Nn #7 { { cmyk } { #1 ~ #2 ~ #3 ~ #4 } } }
+ {
+ \str_if_eq:nnTF {#2} { cs }
+ {
+ \tl_set:Nx #7 { { \use:n #1 } { #5 } }
+ }
{
- \str_if_eq:nnTF {#2} { cs }
- {
- \tl_set:Nx #7 { { spot } { \use_none:n #1 ~ #5 } }
- }
- {
- \tl_set:Nn #7 { { gray } { 0 } }
- }
+ \tl_set:Nn #7 { { gray } { 0 } }
}
- }
+ }
}
}
}
}
-%</package>
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -217,26 +212,19 @@
%
% \begin{macro}
% {
-% \@@_backend_cmyk:n ,
-% \@@_backend_gray:n ,
-% \@@_backend_rgb:n ,
-% \@@_backend_spot:n
+% \@@_backend_select_cmyk:n ,
+% \@@_backend_select_gray:n ,
+% \@@_backend_select_rgb:n
% }
-% \begin{macro}{\@@_backend_spot:w}
-% \begin{macro}{\@@_backend_select:n}
% \begin{macro}{\@@_backend_reset:}
% Simply dump the data, but allowing for \LuaTeX{}.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_cmyk:n #1
+\cs_new_protected:Npn \@@_backend_select_cmyk:n #1
{ \@@_backend_select:n { #1 ~ k ~ #1 ~ K } }
-\cs_new_protected:Npn \@@_backend_gray:n #1
+\cs_new_protected:Npn \@@_backend_select_gray:n #1
{ \@@_backend_select:n { #1 ~ g ~ #1 ~ G } }
-\cs_new_protected:Npn \@@_backend_rgb:n #1
+\cs_new_protected:Npn \@@_backend_select_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
@@ -255,15 +243,240 @@
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
+%
+% \begin{macro}{\@@_backend_select_separation:nn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_select_separation:nn #1#2
+ { \@@_backend_select:n { /#1 ~ cs ~ /#1 ~ CS ~ #2 ~ scn ~ #2 ~ SCN } }
+% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%</pdfmode>
% \end{macrocode}
%
+% \subsection{Fill and stroke color}
+%
+% Here, \texttt{(x)dvipdfmx} follows \texttt{pdfmode}, while for \texttt{dvips}
+% we have to manage fill and stroke color ourselves. We also handle
+% \texttt{dvisvgm} independently, as there we can create SVG directly.
+%
+% \begin{macrocode}
+%<*dvipdfmx|pdfmode|xdvipdfmx>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_stroke_cmyk:n ,
+% \@@_backend_stroke_gray:n ,
+% \@@_backend_stroke_rgb:n
+% }
+% Drawing (fill/stroke) color is handled in \texttt{(x)dvipdfmx} in the
+% same way as \texttt{pdfmode}. We use the same approach as earlier, except the
+% color stack is not involved so the generic direct PDF operation is used.
+% There is no worry about the nature of strokes: everything is handled
+% automatically.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1
+ { \__kernel_backend_literal_pdf:n { #1 ~ k } }
+\cs_new_protected:Npn \@@_backend_fill_gray:n #1
+ { \__kernel_backend_literal_pdf:n { #1 ~ g } }
+\cs_new_protected:Npn \@@_backend_fill_rgb:n #1
+ { \__kernel_backend_literal_pdf:n { #1 ~ rg } }
+ \cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1
+ { \__kernel_backend_literal_pdf:n { #1 ~ K } }
+\cs_new_protected:Npn \@@_backend_stroke_gray:n #1
+ { \__kernel_backend_literal_pdf:n { #1 ~ G } }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1
+ { \__kernel_backend_literal_pdf:n { #1 ~ RG } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation: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 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvipdfmx|pdfmode|xdvipdfmx>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvips>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_fill_gray:n ,
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_stroke_cmyk:n ,
+% \@@_backend_stroke_gray:n ,
+% \@@_backend_stroke_rgb:n
+% }
+% All questions of saving the non-stacked data.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1
+ { \__kernel_backend_postscript:n { /color.fc { #1 ~ setcmykcolor } def } }
+\cs_new_protected:Npn \@@_backend_fill_gray:n #1
+ { \__kernel_backend_postscript:n { /color.fc { #1 ~ setgray } def } }
+\cs_new_protected:Npn \@@_backend_fill_rgb:n #1
+ { \__kernel_backend_postscript:n { /color.fc { #1 ~ setrgbcolor } def } }
+ \cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setcmykcolor } def } }
+\cs_new_protected:Npn \@@_backend_stroke_gray:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setgray } def } }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1
+ { \__kernel_backend_postscript:n { /color.sc { #1 ~ setrgbcolor } def } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation:nn
+% }
+% \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 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvips>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dvisvgm>
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_cmyk:n ,
+% \@@_backend_stroke_cmyk:n
+% }
+% \begin{macro}{\@@_backend_cmyk:nw}
+% \begin{macro}
+% {
+% \@@_backend_fill_gray:n ,
+% \@@_backend_stroke_gray:n
+% }
+% \begin{macro}{\@@_backend_gray:nn, \@@_backend_gray_aux:n}
+% \begin{macro}
+% {
+% \@@_backend_fill_rgb:n ,
+% \@@_backend_stroke_rgb:n
+% }
+% \begin{macro}{\@@_backend_rgb:nw}
+% \begin{macro}{\@@_backend:nnnn}
+% For drawings in SVG, we use scopes for all colors. That
+% requires using \texttt{RGB} values, which luckily are easy to
+% convert here (|cmyk| to |RGB| is a fixed function).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_backend_fill_cmyk:n #1
+ { \@@_backend_cmyk:nw { fill } #1 \s_@@_stop }
+\cs_new_protected:Npn \@@_backend_stroke_cmyk:n #1
+ { \@@_backend_cmyk:nw { stroke } #1 \s_@@_stop }
+\cs_new_protected:Npn \@@_backend_cmyk:nw
+ #1#2 ~ #3 ~ #4 ~ #5 \s_@@_stop
+ {
+ \use:x
+ {
+ \@@_backend:nnnn
+ {#1}
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #2 + #5 ) ) } }
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #3 + #5 ) ) } }
+ { \fp_eval:n { -100 * ( 1 - min ( 1 , #4 + #5 ) ) } }
+ }
+ }
+\cs_new_protected:Npn \@@_backend_fill_gray:n #1
+ { \@@_backend_grab:nn { fill } {#1} }
+\cs_new_protected:Npn \@@_backend_stroke_gray:n #1
+ { \@@_backend_grab:nn { stroke } {#1} }
+\cs_new_protected:Npn \@@_backend_gray:nn #1#2
+ {
+ \use:x
+ {
+ \@@_backend_gray_aux:nn
+ {#1}
+ { \fp_eval:n { 100 * (#2) } }
+ }
+ }
+\cs_new_protected:Npn \@@_backend_gray_aux:nn #1#2
+ { \@@_backend:nnn {#1} {#2} {#2} {#2} }
+\cs_new_protected:Npn \@@_backend_fill_rgb:n #1
+ { \@@_backend_rgb:nw { fill } #1 \s_@@_stop }
+\cs_new_protected:Npn \@@_backend_stroke_rgb:n #1
+ { \@@_backend_rgb:nw { stroke } #1 \s_@@_stop }
+\cs_new_protected:Npn \@@_backend_rgb:nw
+ #1#2 ~ #3 ~ #4\s_@@_stop
+ {
+ \use:x
+ {
+ \@@_backend:nnnn
+ { fill }
+ { \fp_eval:n { 100 * (#2) } }
+ { \fp_eval:n { 100 * (#3) } }
+ { \fp_eval:n { 100 * (#4) } }
+ }
+ }
+\cs_new_protected:Npx \@@_backend:nnnn #1#2#3#4
+ {
+ \__kernel_backend_scope:n
+ {
+ #1 =
+ "
+ rgb
+ (
+ #2 \c_percent_str ,
+ #3 \c_percent_str ,
+ #4 \c_percent_str
+ )
+ "
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_backend_fill_separation:nn,
+% \@@_backend_stroke_separation: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
+ { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</dvisvgm>
+% \end{macrocode}
+%
% \begin{macrocode}
-%</initex|package>
+%</package>
% \end{macrocode}
%
% \end{implementation}