% \iffalse meta-comment
%
%% File: l3drivers-color.dtx
%
% Copyright (C) 2011-2019 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 "l3kernel 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}
%</driver>
% \fi
%
% \title{^^A
%   The \textsf{l3drivers-color} package\\ Driver 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 2019-05-09}
%
% \maketitle
%
% \begin{documentation}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3drivers-color} Implementation}
%
%    \begin{macrocode}
%<*initex|package>
%<@@=driver>
%    \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}{\driver_color_pickup:N}
% \begin{macro}{\@@_color_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 \driver_color_pickup:N #1 { }
\AtBeginDocument
  {
    \@ifpackageloaded { color }
      {
        \cs_set_protected:Npn \driver_color_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 \@@_color_pickup:w
                  { \current@color } \q_stop #1
              }
          }
        \cs_new_protected:Npn \@@_color_pickup:w #1 ~ #2 \q_stop #3
          { \tl_set:Nn #3 { #1 ~ #2 } }
      }
      { }
  }
%</package>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\driver_color_cmyk:nnnn}
% \begin{macro}{\driver_color_gray:n}
% \begin{macro}{\driver_color_rgb:nnn}
% \begin{macro}{\driver_color_spot:nn}
% \begin{macro}{\@@_color_select:n, \@@_color_select:x}
% \begin{macro}{\@@_color_reset:}
% \begin{macro}{driver.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 \driver_color_cmyk:nnnn #1#2#3#4
  {
    \@@_color_select:x
      {
        cmyk~
        \fp_eval:n {#1} ~ \fp_eval:n {#2} ~
        \fp_eval:n {#3} ~ \fp_eval:n {#4}
      }
  }
\cs_new_protected:Npn \driver_color_gray:n #1
  { \@@_color_select:x { gray~ \fp_eval:n {#1} } }
\cs_new_protected:Npn \driver_color_rgb:nnn #1#2#3
  {
    \@@_color_select:x
      { rgb~ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} }
  }
\cs_new_protected:Npn \driver_color_spot:nn #1#2
  { \@@_color_select:n { #1 } }
\cs_new_protected:Npn \@@_color_select:n #1
  {
    \@@_literal:n { color~push~ #1 }
%<*dvips>
    \@@_postscript:n { /driver.fc~{ }~def }
%</dvips>
    \group_insert_after:N \@@_color_reset:
  }
\cs_generate_variant:Nn \@@_color_select:n { x }
\cs_new_protected:Npn \@@_color_reset:
  { \@@_literal:n { color~pop } }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</dvisvgm|dvipdfmx|dvips|xdvipdfmx>
%    \end{macrocode}
%
% \subsection{\texttt{pdfmode}}
%
%    \begin{macrocode}
%<*pdfmode>
%    \end{macrocode}
%
% \begin{macro}{\driver_color_pickup:N}
% \begin{macro}{\@@_color_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{@@_color_pickup:w} breaks it apart, because for instance
%   \pkg{xcolor} sets it to be instructions to generate a colour
%    \begin{macrocode}
%<*package>
\cs_new_protected:Npn \driver_color_pickup:N #1 { }
\AtBeginDocument
  {
    \@ifpackageloaded { color }
      {
        \cs_set_protected:Npn \driver_color_pickup:N #1
          {
            \exp_last_unbraced:Nx \@@_color_pickup:w
              { \current@color } ~ 0 ~ 0 ~ 0 \q_stop #1
          }
        \cs_new_protected:Npn \@@_color_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 }
                           }
                       }
                  }
              }
          }
      }
      { }
  }
%</package>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{variable}{\l_@@_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_@@_color_stack_int
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\driver_color_cmyk:nnnn, \@@_color_cmyk:nnnn}
% \begin{macro}{\driver_color_gray:n, \@@_color_gray:n}
% \begin{macro}{\driver_color_rgb:nnn, \@@_color_rgb:nnn}
% \begin{macro}{\driver_color_spot:nn}
% \begin{macro}{\@@_color_select:n, \@@_color_select:x}
% \begin{macro}{\@@_color_reset:}
%   Simply dump the data, but allowing for \LuaTeX{}.
%    \begin{macrocode}
\cs_new_protected:Npn \driver_color_cmyk:nnnn #1#2#3#4
  {
     \use:x
       {
         \@@_color_cmyk:nnnn
           { \fp_eval:n {#1} }
           { \fp_eval:n {#2} }
           { \fp_eval:n {#3} }
           { \fp_eval:n {#4} }
       } 
  }
\cs_new_protected:Npn \@@_color_cmyk:nnnn #1#2#3#4
  {
    \@@_color_select:n
      { #1 ~ #2 ~ #3 ~ #4 ~ k ~ #1 ~ #2 ~ #3 ~ #4 ~ K }
  }
\cs_new_protected:Npn \driver_color_gray:n #1
  { \exp_args:Nx \@@_color_gray:n { \fp_eval:n {#1} } }
\cs_new_protected:Npn \@@_color_gray:n #1
  { \@@_color_select:n { #1 ~ g ~ #1 ~ G } }
\cs_new_protected:Npn \driver_color_rgb:nnn #1#2#3
  {
     \use:x
       {
         \@@_color_rgb:nnn
           { \fp_eval:n {#1} }
           { \fp_eval:n {#2} }
           { \fp_eval:n {#3} }
       } 
  }
\cs_new_protected:Npn \@@_color_rgb:nnn #1#2#3
  { \@@_color_select:n { #1 ~ #2 ~ #3 ~ rg ~ #1 ~ #2 ~ #3 ~ RG } }
\cs_new_protected:Npn \driver_color_spot:nn #1#2
  { \@@_color_select:n { /#1 ~ cs ~ /#1 ~ CS ~ #2 ~ sc ~ #2 ~ SC } }
\cs_new_protected:Npx \@@_color_select:n #1
  {
    \cs_if_exist:NTF \tex_pdfextension:D
      { \tex_pdfextension:D colorstack }
      { \tex_pdfcolorstack:D }
        \exp_not:N \l_@@_color_stack_int push {#1}
      \group_insert_after:N \exp_not:N \@@_color_reset:
  }
\cs_generate_variant:Nn \@@_color_select:n { x }
\cs_new_protected:Npx \@@_color_reset:
  {
    \cs_if_exist:NTF \tex_pdfextension:D
      { \tex_pdfextension:D colorstack }
      { \tex_pdfcolorstack:D }
        \exp_not:N \l_@@_color_stack_int pop \scan_stop:
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</pdfmode>
%    \end{macrocode}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
