TikZ-PGF – Using Form-Only Patterns with Variable: Possible Bug

pgf-coretikz-pgf

While trying to use a variable pattern in TikZ with varying pattern color, I found that it did not seem to work. Here's a minimal working example:

\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
%
%
\tikzset{slope/.store in=\slope}
%
\pgfdeclarepatternformonly[\slope]{slant lines}
{\pgfpoint{-.1mm/\slope}{-.1mm}}{\pgfpoint{1.1mm/\slope}{1.1mm}}
{\pgfpoint{1mm/\slope}{1mm}}
{
    \pgfsetlinewidth{0.4pt}
    \pgfpathmoveto{\pgfpoint{-.1mm/\slope}{-.1mm}}
    \pgfpathlineto{\pgfpoint{1.1mm/\slope}{1.1mm}}
    \pgfusepath{stroke}
}
%
%
\newcommand{\theslope}{0.7}
%
\pgfdeclarepatternformonly{diagonal lines}
{\pgfpoint{-.1mm/\theslope}{-.1mm}}{\pgfpoint{1.1mm/\theslope}{1.1mm}}
{\pgfpoint{1mm/\theslope}{1mm}}
{
    \pgfsetlinewidth{0.4pt}
    \pgfpathmoveto{\pgfpoint{-.1mm/\theslope}{-.1mm}}
    \pgfpathlineto{\pgfpoint{1.1mm/\theslope}{1.1mm}}
    \pgfusepath{stroke}
}
%
%
\begin{document}
\begin{tikzpicture}
    \draw[pattern=diagonal lines,pattern color=blue] (0,0) rectangle (5,5);
    \tikzset{every path/.append style={xshift=6cm}}
    \draw[pattern=slant lines,pattern color=blue,slope=0.7] (0,0) rectangle (5,5);
\end{tikzpicture}
\end{document}

The output looks like this:

enter image description here

If I understand the system correctly, both squares should be filled with diagonal blue lines. But for the variable-slope pattern, the pattern color=blue option seems to have been ignored.

Am I doing something wrong, or is this an actual bug? In either case, is there a reasonable way for me to make it right?

Best Answer

From the manual p.162, As such, form-only patterns do not have any colors of their own, but when it is used the current pattern color is used as its color.

The reason for this is because form-only pattern declarations without variables are frozen so TikZ can set a pattern color beforehand and the pattern inherits that stroke color. However patterns with variables are not frozen and reevaluated whenever they are called. So the color should be set each time independently. As Qrrbirlbel's answer, the color should be provided to the pattern at the time of creation.

\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
\tikzset{
    slope/.code={\edef\slope{#1}},
    slope/.default=0.5,
    slope
}
\makeatletter
\pgfdeclarepatternformonly[\tikz@pattern@color,\slope]{slant lines}
{\pgfpoint{-.1mm/\slope}{-.1mm}}
{\pgfpoint{1.1mm/\slope}{1.1mm}}
{\pgfpoint{1mm/\slope}{1mm}}
{
    \pgfsetlinewidth{0.4pt}
    \pgfpathmoveto{\pgfpoint{-.1mm/\slope}{-.1mm}}
    \pgfpathlineto{\pgfpoint{1.1mm/\slope}{1.1mm}}
    \pgfsetstrokecolor{\tikz@pattern@color}
    \pgfusepath{stroke}
}
\makeatother
\begin{document}
\begin{tikzpicture}
    \fill[pattern=slant lines,pattern color=red] (0,0) rectangle (5,5);
    \fill[pattern color=blue,pattern=slant lines,slope=0.3] (5,0) rectangle (10,5);
\end{tikzpicture}
\end{document}

enter image description here