% \iffalse meta-comment % %% File: l3backend-color.dtx % % Copyright (C) 2019,2020 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 % license or (at your option) any later version. The latest version % of this license is in the file % % https://www.latex-project.org/lppl.txt % % This file is part of the "l3backend bundle" (The Work in LPPL) % and all files in that bundle must be distributed together. % % ----------------------------------------------------------------------- % % The development version of the bundle can be found at % % https://github.com/latex3/latex3 % % for those people who are interested. % %<*driver> \documentclass[full,kernel]{l3doc} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \title{^^A % The \textsf{l3backend-color} package\\ Backend color support^^A % } % % \author{^^A % The \LaTeX3 Project\thanks % {^^A % E-mail: % \href{mailto:latex-team@latex-project.org} % {latex-team@latex-project.org}^^A % }^^A % } % % \date{Released 2020-05-05} % % \maketitle % % \begin{documentation} % % \end{documentation} % % \begin{implementation} % % \section{\pkg{l3backend-color} Implementation} % % \begin{macrocode} %<*initex|package> %<@@=color> % \end{macrocode} % % Color support is split into two parts: a \enquote{general} concept and % one directly linked to drawings (or rather the split between filling % and stroking). General color is relatively easy to handle: we have a color % stack available with all modern drivers, and can use that. % Whilst \texttt{(x)dvipdfmx} does have its own approach to color specials, % it is easier to use \texttt{dvips}-like ones for all cases except direct % PDF output. % % \subsection{\texttt{dvips}-style} % % \begin{macrocode} %<*dvisvgm|dvipdfmx|dvips|xdvipdfmx> % \end{macrocode} % % \begin{macro}{\@@_backend_pickup:N} % \begin{macro}{\@@_backend_pickup:w} % Allow for \LaTeXe{} color. Here, the possible input values are limited: % \texttt{dvips}-style colors can mainly be taken as-is with the exception % spot ones (here we need a model and a tint). % \begin{macrocode} %<*package> \cs_new_protected:Npn \@@_backend_pickup:N #1 { } \AtBeginDocument { \cs_if_exist:cT { ver@color.sty } { \cs_set_protected:Npn \@@_backend_pickup:N #1 { \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 } \q_stop #1 } } \cs_new_protected:Npn \@@_backend_pickup:w #1 ~ #2 \q_stop #3 { \tl_set:Nn #3 { #1 ~ #2 } } } } % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\@@_backend_cmyk:nnnn} % \begin{macro}{\@@_backend_gray:n} % \begin{macro}{\@@_backend_rgb:nnn} % \begin{macro}{\@@_backend_spot:nn} % \begin{macro}{\@@_backend_select:n, \@@_backend_select:x} % \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{macrocode} \cs_new_protected:Npn \@@_backend_cmyk:nnnn #1#2#3#4 { \@@_backend_select:x { cmyk~ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ \fp_eval:n {#4} } } \cs_new_protected:Npn \@@_backend_gray:n #1 { \@@_backend_select:x { gray~ \fp_eval:n {#1} } } \cs_new_protected:Npn \@@_backend_rgb:nnn #1#2#3 { \@@_backend_select:x { rgb~ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} } } \cs_new_protected:Npn \@@_backend_spot:nn #1#2 { \@@_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 } % \group_insert_after:N \@@_backend_reset: } \cs_generate_variant:Nn \@@_backend_select:n { x } \cs_new_protected:Npn \@@_backend_reset: { \__kernel_backend_literal:n { color~pop } } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \subsection{\texttt{pdfmode}} % % \begin{macrocode} %<*pdfmode> % \end{macrocode} % % \begin{macro}{\@@_backend_pickup:N} % \begin{macro}{\@@_backend_pickup:w} % The current color in driver-dependent format: pick up the package-mode % data if available. We end up converting back and forward in this route as % we store our color data in \texttt{dvips} format. % The \tn{current@color} needs to be \texttt{x}-expanded before % \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_set_protected:Npn \@@_backend_pickup:N #1 { \exp_last_unbraced:Nx \@@_backend_pickup:w { \current@color } ~ 0 ~ 0 ~ 0 \q_stop #1 } \cs_new_protected:Npn \@@_backend_pickup:w #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 \q_stop #7 { \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 {#5} { k } { \tl_set:Nn #7 { cmyk ~ #1 ~ #2 ~ #3 ~ #4 } } { \str_if_eq:nnTF {#2} { cs } { \tl_set:Nx #7 { spot ~ \use_none:n #1 ~ #5 } } { \tl_set:Nn #7 { gray ~ 0 } } } } } } } } % % \end{macrocode} % \end{macro} % \end{macro} % % \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. % \begin{macrocode} \int_new:N \l__kernel_color_stack_int % \end{macrocode} % \end{variable} % % \begin{macro}{\@@_backend_cmyk:nnnn, \@@_backend_cmyk_aux:nnnn} % \begin{macro}{\@@_backend_gray:n, \@@_backend_gray_aux:n} % \begin{macro}{\@@_backend_rgb:nnn, \@@_backend_rgb_aux:nnn} % \begin{macro}{\@@_backend_spot:nn} % \begin{macro}{\@@_backend_select:n, \@@_backend_select:x} % \begin{macro}{\@@_backend_reset:} % Simply dump the data, but allowing for \LuaTeX{}. % \begin{macrocode} \cs_new_protected:Npn \@@_backend_cmyk:nnnn #1#2#3#4 { \use:x { \@@_backend_cmyk_aux:nnnn { \fp_eval:n {#1} } { \fp_eval:n {#2} } { \fp_eval:n {#3} } { \fp_eval:n {#4} } } } \cs_new_protected:Npn \@@_backend_cmyk_aux:nnnn #1#2#3#4 { \@@_backend_select:n { #1 ~ #2 ~ #3 ~ #4 ~ k ~ #1 ~ #2 ~ #3 ~ #4 ~ K } } \cs_new_protected:Npn \@@_backend_gray:n #1 { \exp_args:Nx \@@_backend_gray_aux:n { \fp_eval:n {#1} } } \cs_new_protected:Npn \@@_backend_gray_aux:n #1 { \@@_backend_select:n { #1 ~ g ~ #1 ~ G } } \cs_new_protected:Npn \@@_backend_rgb:nnn #1#2#3 { \use:x { \@@_backend_rgb_aux:nnn { \fp_eval:n {#1} } { \fp_eval:n {#2} } { \fp_eval:n {#3} } } } \cs_new_protected:Npn \@@_backend_rgb_aux:nnn #1#2#3 { \@@_backend_select:n { #1 ~ #2 ~ #3 ~ rg ~ #1 ~ #2 ~ #3 ~ RG } } \cs_new_protected:Npn \@@_backend_spot:nn #1#2 { \@@_backend_select:n { /#1 ~ cs ~ /#1 ~ CS ~ #2 ~ sc ~ #2 ~ SC } } \cs_new_protected:Npx \@@_backend_select:n #1 { \cs_if_exist:NTF \tex_pdfextension:D { \tex_pdfextension:D colorstack } { \tex_pdfcolorstack:D } \exp_not:N \l__kernel_color_stack_int push {#1} \group_insert_after:N \exp_not:N \@@_backend_reset: } \cs_generate_variant:Nn \@@_backend_select:n { x } \cs_new_protected:Npx \@@_backend_reset: { \cs_if_exist:NTF \tex_pdfextension:D { \tex_pdfextension:D colorstack } { \tex_pdfcolorstack:D } \exp_not:N \l__kernel_color_stack_int pop \scan_stop: } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % % \PrintIndex