# Using form-only patterns with variable: possible TikZ bug

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:

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?

-
@percusse I don't think that this is a duplicate. The linked answer isn't even talking about pattern colors. And the five pointed stars pattern doesn't react to \pattern color neither. On this note: Using the example pattern stars from the PGF manual and adding an otherwise not even used macro to the optional list of variables, the stars will stay black. –  Qrrbrbirlbel Nov 25 '12 at 2:14
@percusse: I'm pretty sure this is not a duplicate. First, I don't believe this issue is addressed in the answers to the linked question. Secondly, even if the answer to my question were contained in the answers already given to that question, the questions are definitely different. Mine is a question about a very specific issue, whereas the other is more generally about how to construct patterns. –  Charles Staats Nov 25 '12 at 2:42
I wonder if perhaps form-only patterns are already pattern schema (with a new instance created every time the pattern is used with a different pattern color), and declaring a new pattern schema removes the dependence on pattern color unless it is added back explicitly. If so, Qrrbrbirlbel's solution (below) may be the only viable one, in spite of its use of color commands inside a form-only declaration. –  Charles Staats Nov 25 '12 at 2:57
You are right. I'll make sure the question stays open by prodding the mods. I've provided an answer and removed the duplicate comment. –  percusse Nov 25 '12 at 3:05

## 2 Answers

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}


-
Yeah, that's basically what I did but with the actual (and easy to remember) internal name of pattern color/\tikz@pattern@color. –  Qrrbrbirlbel Nov 25 '12 at 3:22
@Qrrbrbirlbel Yes, the problem is that /tikz/pattern color is a /.code so what you receive from the key is not a color name. –  percusse Nov 25 '12 at 3:26
Well, before digging through thousand files and lines of PGF code, I rather use a manual and lazy approach. –  Qrrbrbirlbel Nov 25 '12 at 3:37
@Qrrbrbirlbel Actually I'm lazy too, I'm searching the keywords in all PGF files at once. Whatever comes with \tikzset or \def I just go to that file :) –  percusse Nov 25 '12 at 8:08
Hehe, of course! I didn't meant literally going through every line and file. That could probably take days! On that note: If you add that fact that /tikz/pattern color contains code and line 14 of tikzlibrarypatterns.code.tex (\tikzoption{pattern color}{\edef\tikz@pattern@color{#1}}) to your answer, I'd safely remove my otherwise redundant answer. –  Qrrbrbirlbel Nov 25 '12 at 9:54

In my solution, I appended \def\patterncolor{#1} to the original pattern color style and added \patterncolor to the variables of \pgfdeclarepatternformonly alongside of \slope and used it with \pgfsetstrokecolor{\patterncolor}.

percusse's answer uses basically the same approach, but with the actual internal name of the /tikz/pattern color/\tikz@pattern@color which I faked with \patterncolor.

## Code

\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
\tikzset{
slope/.store in=\slope,
%    patternkolor/.store in=\patterncolor,% with the next line changed to:
% pattern color/.append style={patternkolor=#1}
pattern color/.append code={\def\patterncolor{#1}}
}

\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}
}

\pgfdeclarepatternformonly[\slope,\patterncolor]{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{\patterncolor}
\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, slope=0.7,pattern color=blue] (0,0) rectangle (5,5);
\end{tikzpicture}
\begin{tikzpicture}
\draw[pattern=slant lines, slope=0.7,pattern color=green] (0,0) rectangle (5,5);
\tikzset{every path/.append style={xshift=6cm}}
\draw[pattern=slant lines, slope=0.2,pattern color=green] (0,0) rectangle (5,5);
\end{tikzpicture}
\end{document}


## Output

-
While I will wait to see if there is a solution that does not involve using color commands within the declaration of a form-only pattern, this definitely appears to be a viable workaround. –  Charles Staats Nov 25 '12 at 2:49