% Copyright 2019 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.


\section{Pattern Library}
\label{section-library-patterns}

\begin{pgflibrary}{patterns}
    The package defines patterns for filling areas.
\end{pgflibrary}


\newcommand\patternindex[1]{%
  \index{#1@\protect\texttt{#1} pattern}%
  \index{Patterns!#1@\protect\texttt{#1}}%
  \texttt{#1}&
  \begin{tikzpicture}[baseline=.5ex]

    % Background
    \pattern [path fading=west,pattern=checkerboard light gray]
      (0,0) rectangle (5cm,2em);

    \pattern [pattern=#1,pattern color=black] (0,0)    rectangle +(1.5cm,2em);
    \pattern [pattern=#1,pattern color=blue]  (1.75,0) rectangle +(1.5cm,2em);
    \pattern [pattern=#1,pattern color=red]   (3.5,0)  rectangle +(1.5cm,2em);
  \end{tikzpicture} \\[1ex]
}

\newcommand\patternindexinherentlycolored[1]{%
  \index{#1@\protect\texttt{#1} pattern}%
  \index{Patterns!#1@\protect\texttt{#1}}%
  \texttt{#1}&
  \begin{tikzpicture}[baseline=.5ex]

    % Background
    \pattern [path fading=west,pattern=checkerboard light gray]
      (0,0) rectangle (5cm,2em);

    \pattern [pattern=#1,pattern color=blue] (0,0) rectangle +(5cm,2em);
  \end{tikzpicture} \\[1ex]
}


\subsection{Form-Only Patterns}

\begin{tabular}{ll}
    \emph{Pattern name}
        & \emph{Example (pattern in black, blue, and red on faded checkerboard)} \\
    \patternindex{horizontal lines}
    \patternindex{vertical lines}
    \patternindex{north east lines}
    \patternindex{north west lines}
    \patternindex{grid}
    \patternindex{crosshatch}
    \patternindex{dots}
    \patternindex{crosshatch dots}
    \patternindex{fivepointed stars}
    \patternindex{sixpointed stars}
    \patternindex{bricks}
    \patternindex{checkerboard}
\end{tabular}


\subsection{Inherently Colored Patterns}

\begin{tabular}{ll}
    \emph{Pattern name} & \emph{Example} \\
    \patternindexinherentlycolored{checkerboard light gray}
    \patternindexinherentlycolored{horizontal lines light gray}
    \patternindexinherentlycolored{horizontal lines gray}
    \patternindexinherentlycolored{horizontal lines dark gray}
    \patternindexinherentlycolored{horizontal lines light blue}
    \patternindexinherentlycolored{horizontal lines dark blue}
    \patternindexinherentlycolored{crosshatch dots gray}
    \patternindexinherentlycolored{crosshatch dots light steel blue}
\end{tabular}


\subsection{User-Defined Patterns}
\label{section-library-patterns-meta}

\noindent\emph{by Mark Wibrow}

\begin{pgflibrary}{patterns.meta}
    Define your own patterns with a syntax similar to |arrows.meta|.
\end{pgflibrary}

\emph{Caveat:} This library is currently experimental and might change without
notice. There are some known shortcomings that will hopefully be fixed in the
future.

\begin{command}{\pgfdeclarepattern\marg{config}}
    This command is used to declare a new pattern. In contrast to the normal
    patterns and in the spirit of |arrows.meta| this command takes a list of
    keys and values to define the pattern. The following keys are available:
    %
    \begin{key}{/pgf/patterns/name=\meta{name}}
        The name of the pattern by which it can be used later on.
    \end{key}
    %
    \begin{key}{/pgf/patterns/type=\meta{type} (default uncolored)}
        The type of the pattern maps to what was called ``form only'' and
        ``inherently colored'' in the language of the normal patterns. The
        available choices are:
        %
        \begin{itemize}
            \item |uncolored| the pattern will obey the surrounding color.
            \item |colored| the pattern will have an intrinsic color.
            \item |form only| synonym for |uncolored|
            \item |inherently colored| synonym for |colored|
        \end{itemize}
    \end{key}
    %
    \begin{key}{/pgf/patterns/x=\meta{dimension} (default 1cm)}
        Unit vector of the coordinate system in the $x$-direction.
    \end{key}
    %
    \begin{key}{/pgf/patterns/y=\meta{dimension} (default 1cm)}
        Unit vector of the coordinate system in the $y$-direction.
    \end{key}
    %
    \begin{key}{/pgf/patterns/parameters=\meta{comma separated list} (default empty)}
        A list of parameters that are passed to the pattern. This is usually a
        list of \TeX\ macros. It is very important that these macros are fully
        expandable because the values they hold are being used for
        deduplication in the PDF file.
    \end{key}
    %
    \begin{key}{/pgf/patterns/defaults=\meta{comma separated list} (default empty)}
        This list holds default assignments to the parameters passed to the
        pattern. The default keys can then be found under the
        |/pgf/pattern keys/| prefix.
    \end{key}
    %
    \begin{key}{/pgf/patterns/bottom left=\meta{pgfpoint}}
        Bottom left corner of the pattern's bounding box, e.g.\
        |\pgfqpoint{-.1pt}{-.1pt}|.
    \end{key}
    %
    \begin{key}{/pgf/patterns/top right=\meta{pgfpoint}}
        Top right corner of the pattern's bounding box, e.g.\
        |\pgfqpoint{3.1pt}{3.1pt}|.
    \end{key}
    %
    \begin{key}{/pgf/patterns/tile size=\meta{pgfpoint}}
        Width and height of a single of the pattern as a \pgfname\ point
        specification, i.e. the $x$ coordinate is the width and the $y$
        specification, i.e.\ the $x$ coordinate is the width and the $y$
        coordinate is the height, e.g.\ |\pgfqpoint{3pt}{3pt}|.
    \end{key}
    %
    \begin{key}{/pgf/patterns/tile transformation=\meta{pgftransformation} (default empty)}
        A \pgfname\ transformation, e.g.\ |\pgftransformrotate{30}|.
    \end{key}
    %
    \begin{key}{/pgf/patterns/code=\meta{code}}
        The code should be \pgfname\ code that can be protocolled. It should not
        contain any color code or nodes.
    \end{key}
    %
    \begin{key}{/pgf/patterns/set up code=\meta{code} (default empty)}
        This code can be set if parameters have to be preprocessed before the
        actual pattern code can be run.
    \end{key}
\end{command}

\begin{codeexample}[preamble={\usetikzlibrary{patterns.meta}}]
\pgfdeclarepattern{
  name=hatch,
  parameters={\hatchsize,\hatchangle,\hatchlinewidth},
  bottom left={\pgfpoint{-.1pt}{-.1pt}},
  top right={\pgfpoint{\hatchsize+.1pt}{\hatchsize+.1pt}},
  tile size={\pgfpoint{\hatchsize}{\hatchsize}},
  tile transformation={\pgftransformrotate{\hatchangle}},
  code={
    \pgfsetlinewidth{\hatchlinewidth}
    \pgfpathmoveto{\pgfpoint{-.1pt}{-.1pt}}
    \pgfpathlineto{\pgfpoint{\hatchsize+.1pt}{\hatchsize+.1pt}}
    \pgfpathmoveto{\pgfpoint{-.1pt}{\hatchsize+.1pt}}
    \pgfpathlineto{\pgfpoint{\hatchsize+.1pt}{-.1pt}}
    \pgfusepath{stroke}
  }
}

\tikzset{
  hatch size/.store in=\hatchsize,
  hatch angle/.store in=\hatchangle,
  hatch line width/.store in=\hatchlinewidth,
  hatch size=5pt,
  hatch angle=0pt,
  hatch line width=.5pt,
}

\begin{tikzpicture}
\foreach \r in {1,...,4}
  \draw [pattern=hatch, pattern color=red]
    (\r*3,0) rectangle ++(2,2);

\foreach \r in {1,...,4}
  \draw [pattern=hatch, pattern color=green, hatch size=2pt]
    (\r*3,3) rectangle ++(2,2);

\foreach \r in {1,...,4}
  \draw [pattern=hatch, pattern color=blue, hatch size=10pt, hatch angle=21]
    (\r*3,6) rectangle ++(2,2);

\foreach \r in {1,...,4}
  \draw [pattern=hatch, pattern color=orange, hatch line width=2pt]
    (\r*3,9) rectangle ++(2,2);
\end{tikzpicture}
\end{codeexample}

There are a couple of predefined \pgfname\ patterns which are similar
to their normal counterparts.  For all of these the |xshift| and |yshift| are
applied \emph{before} the rotation.  If you want to rotate before shifting,
just rotate in the drawing code.

\begin{pattern}{Lines}
    The |Lines| pattern replaces the |horizontal lines|, |vertical lines|,
    |north east lines|, and |north west lines| patterns. Unfortunately, due to
    the way the old patterns are constructed, namely that they are not simply
    related to each other by rotation, the |Lines| pattern cannot be used as a
    drop-in replacement.

    However, the pattern options can be tuned to resemble the other versions
    closely. The available parameters are:
    %
    \begin{key}{/pgf/pattern keys/distance (initially 3pt)}
        Distance between lines.
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/angle (initially 0)}
        By default the lines are horizontal. The whole pattern is rotated by
        this angle. The rotation angle is measured in the mathematically
        positive sense.
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/xshift (initially 0pt)}
        Shifts the whole pattern in $x$-direction (before applying the
        rotation).
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/yshift (initially 0pt)}
        Shifts the whole pattern in $y$-direction (before applying the
        rotation).
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/line width (initially \string\the\string\pgflinewidth)}
        Thickness of the lines.
    \end{key}
    %
    The following settings can be used to reproduce the other |... lines|
    patterns.
    %
\begin{codeexample}[preamble={\usetikzlibrary{patterns,patterns.meta}}]
\begin{tikzpicture}
  \draw[pattern={horizontal lines},pattern color=orange]
    (0,0) rectangle +(1,1);
  \draw[pattern={Lines[yshift=.5pt]},pattern color=blue]
    (0,0) rectangle +(1,1);

  \draw[pattern={vertical lines},pattern color=orange]
    (1,0) rectangle +(1,1);
  \draw[pattern={Lines[angle=90,yshift=-.5pt]},pattern color=blue]
    (1,0) rectangle +(1,1);

  \draw[pattern={north east lines},pattern color=orange]
    (0,1) rectangle +(1,1);
  \draw[pattern={Lines[angle=45,distance={3pt/sqrt(2)}]},pattern color=blue]
    (0,1) rectangle +(1,1);

  \draw[pattern={north west lines},pattern color=orange]
    (1,1) rectangle +(1,1);
  \draw[pattern={Lines[angle=-45,distance={3pt/sqrt(2)}]},pattern color=blue]
    (1,1) rectangle +(1,1);
\end{tikzpicture}
\end{codeexample}
    %
\end{pattern}

\begin{pattern}{Hatch}
    The |Hatch| pattern replaces the |grid| and |crosshatch| patterns.
    The |Hatch| pattern without options is a drop-in replacement for the
    |grid| pattern.
    %
    \begin{key}{/pgf/pattern keys/distance (initially 3pt)}
        Distance between crosses.
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/angle (initially 0)}
        By default the lines are horizontal and vertical. The whole pattern is
        rotated by this angle. The rotation angle is measured in the
        mathematically positive sense.
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/xshift (initially 0pt)}
        Shifts the whole pattern in $x$-direction (before applying the
        rotation).
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/yshift (initially 0pt)}
        Shifts the whole pattern in $y$-direction (before applying the
        rotation).
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/line width (initially \string\the\string\pgflinewidth)}
        Thickness of the lines.
    \end{key}
    %
    The following settings can be used to reproduce the |grid| and
    |crosshatch| patterns.
    %
\begin{codeexample}[preamble={\usetikzlibrary{patterns,patterns.meta}}]
\begin{tikzpicture}
  \draw[pattern={grid},pattern color=orange]
    (0,0) rectangle +(1,1);
  \draw[pattern={Hatch},pattern color=blue]
    (0,0) rectangle +(1,1);

  \draw[pattern={crosshatch},pattern color=orange]
    (1,0) rectangle +(1,1);
  \draw[pattern={Hatch[angle=45,distance={3pt/sqrt(2)},xshift=.1pt]},
    pattern color=blue] (1,0) rectangle +(1,1);
\end{tikzpicture}
\end{codeexample}
    %
\end{pattern}

\begin{pattern}{Dots}
    The |Dots| pattern replaces the |dots| and |crosshatch dots| patterns. The
    |Dots| pattern without options is a drop-in replacement for the |dots|
    pattern.
    %
    \begin{key}{/pgf/pattern keys/distance (initially 3pt)}
        Distance between dots.
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/angle (initially 0)}
        By default the lines are arranged on a regular grid. The whole pattern
        is rotated by this angle. The rotation angle is measured in the
        mathematically positive sense.
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/xshift (initially 0pt)}
        Shifts the whole pattern in $x$-direction (before applying the
        rotation).
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/yshift (initially 0pt)}
        Shifts the whole pattern in $y$-direction (before applying the
        rotation).
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/radius (initially 0.5pt)}
        Radius of the dots.
    \end{key}
    %
    The following settings can be used to reproduce the |dots| and
    |crosshatch dots| patterns.
    %
\begin{codeexample}[preamble={\usetikzlibrary{patterns,patterns.meta}}]
\begin{tikzpicture}
  \draw[pattern={dots},pattern color=orange]
    (0,0) rectangle +(1,1);
  \draw[pattern={Dots},pattern color=blue]
    (0,0) rectangle +(1,1);

  \draw[pattern={crosshatch dots},pattern color=orange]
    (1,0) rectangle +(1,1);
  \draw[pattern={Dots[angle=45,distance={3pt/sqrt(2)}]},
    pattern color=blue] (1,0) rectangle +(1,1);
\end{tikzpicture}
\end{codeexample}
    %
\end{pattern}

\begin{pattern}{Stars}
    The |Stars| pattern replaces the |fivepointed stars| and |sixpointed stars|
    patterns. However, the stars of the |Stars| pattern are constructed in a
    fundamentally different fashion, so it can't be used as a drop-in
    replacement.
    %
    \begin{key}{/pgf/pattern keys/distance (initially 3mm)}
        Distance between stars.
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/angle (initially 0)}
        By default the stars are arranged on a regular grid. The whole pattern
        is rotated by this angle. The rotation angle is measured in the
        mathematically positive sense.
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/xshift (initially 0pt)}
        Shifts the whole pattern in $x$-direction (before applying the
        rotation).
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/yshift (initially 0pt)}
        Shifts the whole pattern in $y$-direction (before applying the
        rotation).
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/radius (initially 1mm)}
        Outer radius of the enclosing circle of the stars.
    \end{key}
    %
    \begin{key}{/pgf/pattern keys/points (initially 5)}
        Number of pointy ends of the stars.
    \end{key}
    %
\begin{codeexample}[preamble={\usetikzlibrary{patterns,patterns.meta}}]
\begin{tikzpicture}
  \draw[pattern={fivepointed stars},pattern color=orange]
    (0,0) rectangle +(1,1);
  \draw[pattern={Stars},pattern color=blue]
    (0,0) rectangle +(1,1);

  \draw[pattern={sixpointed stars},pattern color=orange]
    (1,0) rectangle +(1,1);
  \draw[pattern={Stars[points=6]},pattern color=blue]
    (1,0) rectangle +(1,1);
\end{tikzpicture}
\end{codeexample}
    %
\end{pattern}


\begin{command}{\tikzdeclarepattern\marg{config}}
    A pattern declared with |\pgfdeclarepattern| can only execute \pgfname\
    code. This command extends the functionality to also allow \tikzname\
    code. All the same keys of |\pgfdeclarepattern| are valid, but some of
    them have been overloaded to give a more natural \tikzname\ syntax.
    %
    \begin{key}{/tikz/patterns/bottom left=\meta{point}}
        Instead of a \pgfname\ name point, this key takes a \tikzname\ point,
        e.g.\ |(-.1,-.1)|.
    \end{key}
    %
    \begin{key}{/tikz/patterns/top right=\meta{point}}
        Instead of a \pgfname\ name point, this key takes a \tikzname\ point,
        e.g.\ |(3.1,3.1)|.
    \end{key}
    %
    \begin{key}{/tikz/patterns/tile size=\meta{point}}
        Instead of a \pgfname\ name point, this key takes a \tikzname\ point,
        e.g.\ |(3,3)|.
    \end{key}
    %
    \begin{key}{/tikz/patterns/tile transformation=\meta{transformation}}
        Instead of a \pgfname\ transformation, this key takes a list of keys
        and value and extracts the resulting transformation from them, e.g.\
        |rotate=30|.
    \end{key}

    In addition to the overloaded keys, some new keys have been added.
    %
    \begin{key}{/tikz/patterns/bounding box=\meta{point} and \meta{point}}
        This is a shorthand to set the bounding box. It will assign the first
        point to |bottom left| and the second point to |top right|.
    \end{key}
    %
    \begin{key}{/tikz/patterns/infer tile bounding box=\meta{dimension} (default 0pt)}
        Instead of specifying the bounding box by hand, you can ask \tikzname\
        to infer the size of the bounding box for you. The \meta{dimension}
        parameter is padding that is added around the bounding box.
    \end{key}
\end{command}

\begin{codeexample}[preamble={\usetikzlibrary{patterns.meta}}]
\tikzdeclarepattern{
  name=flower,
  type=colored,
  bottom left={(-.1pt,-.1pt)},
  top right={(10.1pt,10.1pt)},
  tile size={(10pt,10pt)},
  code={
    \tikzset{x=1pt,y=1pt}
    \path [draw=green] (5,2.5) -- (5, 7.5);
    \foreach \i in {0,60,...,300}
      \path [fill=pink, shift={(5,7.5)}, rotate=-\i]
        (0,0) .. controls ++(120:4) and ++(60:4) .. (0,0);
    \path [fill=red] (5,7.5) circle [radius=1];
    \foreach \i in {-45,45}
      \path [fill=green, shift={(5,2.5)}, rotate=-\i]
        (0,0) .. controls ++(120:4) and ++(60:4) .. (0,0);
  }
}

\tikz\draw [pattern=flower] circle [radius=1];
\end{codeexample}

\begin{codeexample}[preamble={\usetikzlibrary{patterns.meta}}]
\tikzdeclarepattern{
  name=mystars,
  type=uncolored,
  bounding box={(-5pt,-5pt) and (5pt,5pt)},
  tile size={(\tikztilesize,\tikztilesize)},
  parameters={\tikzstarpoints,\tikzstarradius,\tikzstarrotate,\tikztilesize},
  tile transformation={rotate=\tikzstarrotate},
  defaults={
    points/.store in=\tikzstarpoints,points=5,
    radius/.store in=\tikzstarradius,radius=3pt,
    rotate/.store in=\tikzstarrotate,rotate=0,
    tile size/.store in=\tikztilesize,tile size=10pt,
  },
  code={
    \pgfmathparse{180/\tikzstarpoints}\let\a=\pgfmathresult
    \fill (90:\tikzstarradius) \foreach \i in {1,...,\tikzstarpoints}{
      -- (90+2*\i*\a-\a:\tikzstarradius/2) -- (90+2*\i*\a:\tikzstarradius)
    } -- cycle;
  }
}

\begin{tikzpicture}
 \draw[pattern=mystars,pattern color=blue]               (0,0) rectangle +(2,2);
 \draw[pattern={mystars[points=7,tile size=15pt]}]       (2,0) rectangle +(2,2);
 \draw[pattern={mystars[rotate=45]},pattern color=red]   (0,2) rectangle +(2,2);
 \draw[pattern={mystars[rotate=30,points=4,radius=5pt]}] (2,2) rectangle +(2,2);
\end{tikzpicture}
\end{codeexample}

Instead of macros you can also use \pgfname\ keys as parameters, if that is
what you prefer.
%
\begin{codeexample}[preamble={\usetikzlibrary{patterns.meta}}]
\tikzdeclarepattern{
  name=mylines,
  parameters={
      \pgfkeysvalueof{/pgf/pattern keys/size},
      \pgfkeysvalueof{/pgf/pattern keys/angle},
      \pgfkeysvalueof{/pgf/pattern keys/line width},
  },
  bounding box={
    (0,-0.5*\pgfkeysvalueof{/pgf/pattern keys/line width}) and
    (\pgfkeysvalueof{/pgf/pattern keys/size},
     0.5*\pgfkeysvalueof{/pgf/pattern keys/line width})},
  tile size={(\pgfkeysvalueof{/pgf/pattern keys/size},
              \pgfkeysvalueof{/pgf/pattern keys/size})},
  tile transformation={rotate=\pgfkeysvalueof{/pgf/pattern keys/angle}},
  defaults={
    size/.initial=5pt,
    angle/.initial=45,
    line width/.initial=.4pt,
  },
  code={
      \draw [line width=\pgfkeysvalueof{/pgf/pattern keys/line width}]
        (0,0) -- (\pgfkeysvalueof{/pgf/pattern keys/size},0);
  },
}

\begin{tikzpicture}
  \draw[pattern={mylines[size=10pt,line width=.8pt,angle=10]},
        pattern color=red]    (0,0) rectangle ++(2,2);
  \draw[pattern={mylines[size= 5pt,line width=.8pt,angle=40]},
        pattern color=blue]   (2,0) rectangle ++(2,2);
  \draw[pattern={mylines[size=10pt,line width=.4pt,angle=90]},
        pattern color=green]  (0,2) rectangle ++(2,2);
  \draw[pattern={mylines[size= 2pt,line width= 1pt,angle=70]},
        pattern color=orange] (2,2) rectangle ++(2,2);
\end{tikzpicture}
\end{codeexample}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "pgfmanual-pdftex-version"
%%% End:
