Why do true grayscale gradients get converted to cthek/rgb resulting in a possible color tint when printing

colorgradientprintingtikz-pgf

While printing my thesis in a professional printing shop I encountered various issues. First, pages with grayscale graphics have not been recognized as such (requires manual fixing by the shop) and and also have a color tint, which I assume comes from color conversions and a not perfectly calibrated printer. I learned about the command \selectcolormodel{gray}, which is a quick fix for the first issue, and that I should define gray colors with \definecolor{xxx}{gray}{0.5} instead of \definecolor{xxx}{rgb}{0.5,0.5,0.5} to actually fix both issues. So far so good.

But there remains one case I could not fix: graphics with color components, so I cannot use \selectcolormodel{gray} and grayshade gradients occurring at the same time. Even if I define the shade/fading with true grayscale colors, it gets converted to rgb/cmyk in the end, so that again there is a color tint in the print. Is this a bug? Is it by design? Is there a fix?

Thank you very much!

MWE

\documentclass{standalone}

\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows}

\definecolor{grau-}{gray}{0.50}
\definecolor{grau}{gray}{0.73}
\definecolor{grau+}{gray}{0.84}

%\selectcolormodel{gray}  % only fix for entire document

\begin{document}

\begin{tikzpicture}
%% mixed colors! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\node[single arrow, left color=grau+, right color=grau-,
      minimum height = 7.5cm] at (0,0) {Hello World!};
\shadedraw[top  color=gray!30, bottom color=gray!30, middle color=white, thin, yshift =1cm, xshift =-3cm] 
    (0,-2) -- ++(0, 2) -- ++(-2, 0) -- ++(0, -2) -- cycle;

%% true grayscale! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\node[single arrow, fill=grau+,                          
%     minimum height = 7.5cm] at (0,0) {Hello World!};
%\draw[fill=gray, thin, yshift =1cm, xshift =-3cm] 
%    (0,-2) -- ++(0, 2) -- ++(-2, 0) -- ++(0, -2) -- cycle;
%\end{tikzpicture}

\end{document}

How to check for true grayscale

To check whether an output pdf contains only grayscale I installed Ghostscript and use a batch-file (drag and drop the pdf on the batch file):

gswin64c.exe -o - -sDEVICE=inkcov "%~1"
pause

For a true grayscale pdf the output only has value at the 4th position::

Page 1
 0.00000  0.00000  0.00000  0.43900 CMYK OK

For a color containing pdf the output shows values at all positions:

Page 1
 0.41208  0.41208  0.40833  0.10622 CMYK OK

Complex Example

Consider the following graphic. When printed, the lower "cylinder" has a color tint when printed, because the grayshade is converted to a color mix. That is what I would like to avoid.

enter image description here

Best Answer

Shadings are special objects in a PDF. The code pgf uses to create such a shading starts like this:

\def\pgf@setup@shading@model{%
  \pgfshadingmodelrgbtrue
  \pgfshadingmodelcmykfalse
  \pgfshadingmodelgrayfalse
  \XC@sdef\pgf@mod@test{\XC@tgt@mod{natural}}%
  \def\pgf@shading@device{/DeviceRGB}% <-------------- 1
  \def\pgf@shading@ps@device{setrgbcolor}%
  \def\pgf@shading@functional@range{0 1 0 1 0 1}%
  \def\pgf@shading@model{rgb}%
  \ifx\pgf@mod@test\XC@mod@cmyk
    \def\pgf@shading@device{/DeviceCMYK}%
    \def\pgf@shading@ps@device{setcmykcolor}%
    \def\pgf@shading@functional@range{0 1 0 1 0 1 0 1}%
    \def\pgf@shading@model{cmyk}%
    \pgfshadingmodelrgbfalse
    \pgfshadingmodelcmyktrue
  \fi
  \ifx\pgf@mod@test\XC@mod@gray %<----------------------2
    \def\pgf@shading@device{/DeviceGray}% %<------------3
    \def\pgf@shading@ps@device{setgray}%
    \def\pgf@shading@functional@range{0 1}%
    \def\pgf@shading@model{gray}%
    \pgfshadingmodelrgbfalse
    \pgfshadingmodelgraytrue
  \fi

The line marked with 1

\def\pgf@shading@device{/DeviceRGB}%

means that the default colorspace for a shading is /DeviceRGB, so rgb.

The lines 2 + 3 mean that you get a shading using /DeviceGray if you set the colormodel of xcolor locally or globally to gray.