[Tex/LaTex] Using patterns inside pgf shapes

colorpgf-coretikz-pgf

Is it possible to (correctly) use patterns inside a pgf shape definition ? For example, I try to define a shape as a rectangle filled with a pattern, like this

\usetikzlibrary{patterns}

\pgfdeclareshape{test shape}
{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}

  \backgroundpath
  {
    \pgfsetfillpattern{north east lines}{.}
    \pgfpathrectanglecorners{\pgfpoint{0}{0}}{\pgfpoint{1cm}{1cm}}
    \pgfusepath{fill}
  }
}

the problem is that \pgfsetfillpattern needs a color argument :

\pgfsetfillpattern{pattern name}{pattern color}

I want this color to be the color used to draw paths, so I tried to use . (the current color in the xcolor package). It doesn't work as expected :

\begin{tikzpicture}
\node[draw=red,test shape] at (0,0) {};
\node[fill=red,test shape] at (2cm,0) {};
\node[color=red,test shape] at (4cm,0) {};
\end{tikzpicture}

produces two black shapes and a red one :

two rectangles filled with a black north east lines pattern and then a red one

I would expect the first one to be red too. So I have two questions

  • is it an easy solution to do it ?
  • is it a good idea to use patterns inside a pgf shape ? (And if the answer is no, well, why and what to do instead ?)

Best Answer

I don't see a way to get the stroke colour from PGF itself (\pgfgetsstrokecolor isn't a defined macro) but fortunately TikZ stores the colour in its own memory space and so it is possible to use that to get the colour. There are three such storage places:

\tikz@strokecolor
\tikz@fillcolor
tikz@color
.

The first two are macros, the last two are colours. The draw=colour option sets the first, the fill=colour option sets the second, and the color=colour options sets both of the last two.

So one solution is to set the colour to be . unless \tikz@strokecolor is set, whereupon we use that. One way of doing this is the following:

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{patterns}

\makeatletter
\pgfdeclareshape{test shape}
{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}

  \backgroundpath
  {
    \def\my@color{.}%
    \ifx\tikz@strokecolor\pgfutil@empty
    \else
    \let\my@color\tikz@strokecolor
    \fi
    \pgfsetfillpattern{north east lines}{\my@color}
    \pgfpathrectanglecorners{\pgfpoint{0}{0}}{\pgfpoint{1cm}{1cm}}
    \pgfusepath{fill}
  }
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[draw=red,test shape] at (0,0) {};
\node[fill=red,test shape] at (2cm,0) {};
\node[color=red,test shape] at (4cm,0) {};
\end{tikzpicture}
\end{document}

which results in:

coloured patterns

If you want a different combination then you need to adjust the choices.