% 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{Defining New Arrow Tip Kinds}
\label{section-arrows}

\subsection{Overview}

In present section we have a look at how you can define new arrow tips for use
in \pgfname. The low-level commands for selecting which arrow tips are to be
used have already been described in Section~\ref{section-tips}, the general
syntax rules for using arrows are detailed in
Section~\ref{section-tikz-arrows}. Although Section~\ref{section-tikz-arrows}
describes the use of arrows in \tikzname, in reality, \tikzname\ itself does
not actually do anything about arrow tips; all of the functionality is
implemented on the \pgfname\ level in the commands described in
Section~\ref{section-tikz-arrows}. Indeed, even the |/.tip| key handler
described in Section~\ref{section-tikz-arrows} is actually implemented on the
\pgfname\ layer.

What has \emph{not} yet been covered is how you can actually define a complete
new arrow tip. In \pgfname, arrows are ``meta-arrows'' in the same way that
fonts in \TeX\ are ``meta-fonts''. When a meta-arrow is resized, it is not
simply scaled, but a possibly complicated transformation is applied to the
size.

A meta-font is not one particular font at a specific size with a specific
stroke width (and with a large number of other parameters being fixed). Rather,
it is a ``blueprint'' (actually, more like a program) for generating such a
font at a particular size and width. This allows the designer of a meta-font to
make sure that, say, the font is somewhat thicker and wider at very small
sizes. To appreciate the difference: Compare the following texts: ``Berlin''
and ``\tikz{\node [scale=2,inner sep=0pt,outer sep=0pt]{\tiny Berlin};}''. The
first is a ``normal'' text, the second is the tiny version scaled by a factor
of two. Obviously, the first look better. Now, compare ``\tikz{\node
[scale=.5,inner sep=0pt,outer sep=0pt]{Berlin};}'' and ``{\tiny Berlin}''. This
time, the normal text was scaled down, while the second text is a ``normal''
tiny text. The second text is easier to read.

\pgfname's meta-arrows work in a similar fashion: The shape of an arrow tip can
vary according to a great number of parameters, the line width of the arrow tip
being one of them. Thus, an arrow tip drawn at a line width of 5pt will
typically \emph{not} be five times as large as an arrow tip of line width 1pt.
Instead, the size of the arrow will get bigger only slowly as the line width
increases.

To appreciate the difference, here are the |Latex| and
|Classical TikZ Rightarrow| arrows, as drawn by \pgfname\ at four different
sizes:

\medskip
\begin{tikzpicture}[1/.tip=Latex, 2/.tip=Classical TikZ Rightarrow]
    \draw[-1, line width=0.1pt] (0pt,0ex) -- +(3,0)  node[thin,right] {line width is 0.1pt};
    \draw[-1, line width=0.4pt] (0pt,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt};
    \draw[-1, line width=1.2pt] (0pt,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt};
    \draw[-1, line width=5pt]   (0pt,-6em) -- +(3,0) node[thin,right] {line width is 5pt};

    \draw[-2, line width=0.1pt] (6cm,0ex) -- +(3,0)  node[thin,right] {line width is 0.1pt};
    \draw[-2, line width=0.4pt] (6cm,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt};
    \draw[-2, line width=1.2pt] (6cm,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt};
    \draw[-2, line width=5pt]   (6cm,-6em) -- +(3,0) node[thin,right] {line width is 5pt};
\end{tikzpicture}

\medskip
Here, by comparison, are the same arrows when they are simply ``resized'':

\medskip
\begin{tikzpicture}[1/.tip=Latex, 2/.tip=Classical TikZ Rightarrow]
  \draw[-{1[length=1pt]}, line width=0.1pt] (0pt,0ex) -- +(3,0)  node[thin,right] {line width is 0.1pt};
  \draw[-{1[length=4pt]}, line width=0.4pt] (0pt,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt};
  \draw[-{1[length=12pt]}, line width=1.2pt] (0pt,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt};
  \draw[-{1[length=32pt]}, line width=5pt]   (0pt,-6em) -- +(3,0) node[thin,right] {line width is 5pt};

  \draw[-{2[length=0.455pt]}, line width=0.1pt] (6cm,0ex) -- +(3,0)  node[thin,right] {line width is 0.1pt};
  \draw[-{2[length=1.82pt]}, line width=0.4pt] (6cm,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt};
  \draw[-{2[length=5.46pt]}, line width=1.2pt] (6cm,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt};
  \draw[-{2[length=14.56pt]}, line width=5pt]   (6cm,-6em) -- +(3,0) node[thin,right] {line width is 5pt};
\end{tikzpicture}

\bigskip
As can be seen, simple scaling produces arrow tips that are way too large at
larger sizes and way too small at smaller sizes.

In addition to the line width, other options may also influence the appearance
of an arrow tip. In particular, the width of the inner line (the line used to
create the effect of a double line) influences arrow tips as well as other
options that are specific to the arrow tip.


\subsection{Terminology}
\label{section-arrow-terminology}

Before we have a look at the exact commands used for defining arrow tips, we
need to fix some terminology. Consider the following drawing of an arrow tip
where the arrow tip is drawn transparently so that we can see what is
``happening behind it'':
%
\begin{tikzpicture}
    \draw [red!50, ,line width=1cm] (0,0) -- (4,0);
    \path [tips, opacity=.25,line width=1cm, -{Stealth[black,line width=0pt,length=4cm, width=4cm, inset=1cm]}] (0,0) -- (6,0);

    \draw [->,thick] (1,0) -- (8,0) node [right] {$x$-axis};
    \draw [->,thick] (5,-2.25) -- (5,2.25) node [above] {$y$-axis};

    \foreach \i in {-3,-2,-1,1,2} \draw (\i+5,-1mm) -- (\i+5,1mm) node [above] {\small$\i$};
    \foreach \i in {-2,-1,1,2} \draw (49mm,\i) -- (51mm,\i) node [right] {\small$\i$};;
\end{tikzpicture}

I have also added a coordinate system. The code for drawing an arrow tip always
draws it in the way shown above: Pointing right along the $x$-axis.

We will use the following terminology:
%
\begin{itemize}
    \item The point where tip of the arrow ends is called the \emph{tip end}.
        It is at $(1,0)$ in our example and we always assume it to lie on the
        $x$-axis, so we just treat it as a distance, 1 in this case. This is
        the position where the original path was supposed to end (so if the
        arrow tip had not been added to the red path, it would have ended
        here).
    \item The \emph{back end} of the arrow is where a vertical line just to the
        left of the arrow intersects the $x$-axis. In our case, this is the
        point $(-3,0)$ and again we treat it as a distance, $-3$ in this case.
    \item The \emph{line end} is the position where the path now ends. This
        should be a position inside the arrow head that gets ``covered'' by the
        path. Note that a path may have a round or a rect head and should still
        be covered. Clearly, necessary shortening of the path will be the
        difference between the tip end and the line end.
    \item The \emph{visual back end} is the position where the path and the the
        arrow head ``meet last'' on the path. In our case, because of the
        inset, the visual back end is not the same as the back end: The arrow
        ends ``visually'' at $(-2,0)$. The difference between the back end and
        the visual back end is important when the arrow tip is flexed, see
        Section~\ref{section-arrow-flex} for an explanation of flexing.
    \item There is also a \emph{visual tip end}, the counterpart of the visual
        back end for the front. In our case, the visual tip end and the tip end
        obviously coincide, but if we were to reverse the arrow tip, the visual
        tip end would be different from the tip end (while the visual back end
        would then coincide with the new back end).
    \item There are four points that make up the \emph{convex hull} of the
        arrow tip: $(1,0)$, $(-3,2)$, and $(-3,-2)$.

        Normally, \pgfname\ automatically keeps track of a bounding box of
        everything you draw. However, since arrow tips are drawn so often,
        \pgfname\ caches the code needing for drawing arrow tips internally and
        because of this cache it cannot determine the size of the arrow tip
        just based on the drawing commands used for drawing the tip. Instead, a
        convex hull of the arrow tip must be explicitly provided in the
        definition.
\end{itemize}

When you design a new arrow tip, all of the above parameters must be defined.


\subsection{Caching and Rendering of Arrows}

As a last preparation for the description of the commands for declaring arrows,
it is important to understand the exact process by which \pgfname\ draws
arrows.
%
\begin{enumerate}
    \item First, you have to define an arrow tip kind using
        |\pgfdeclarearrow{name=foo,...|. This will tell \pgfname\ that |foo| is %}
        now the name of an arrow tip. In particular, the parser for arrow tip
        specifications will now treat |foo| as the name of an arrow tip and
        will not try to consider |f|, |o|, and |o| as the names of single-char
        shorthands.

        Other than storing the definitions in the declaration internally, this
        command has little other effect. In particular, no drawing or other
        processing takes place.
    \item Now assume that at some point the arrow tip |foo| is actually used.
        In this case, certain options may have been set, for instance the user
        may have requested the arrow tip |foo[length=5pt,open]|. What happens
        next depends on whether it is the first time the arrow tip |foo| is
        used with \emph{these exact options} or not.
    \item Assume that is the first time |foo| is requested at a length of 5pt
        and in an ``open'' version. \pgfname\ now retrieves the definition of
        the arrow tip kind that it stored in the first step and executes the
        so-called \emph{setup} code. When this code is executed, all the
        options will be in force (for instance, |\pgfarrowlength| will equal
        |5pt| in our case). The job of the setup code is two-fold: First, it
        needs to compute all of the parameters listed in
        Section~\ref{section-arrow-terminology}, that is, it has to compute
        where the tip end will lie in the arrow tip's coordinate system
        \emph{at the particular size of 5pt}, where the back end will be, where
        the convex hull points lie, and so on. Second, the setup code should
        precompute values that will be important for constructing the path of
        the arrow. In our example, there is little to do in this regard, but
        for more complicated arrows, all time-consuming preparations are done
        now.

        It is \emph{not} the job of the setup to actually draw the arrow tip,
        only to ``prepare'' this as much as possible.

        The setup code will always be executed only once for each arrow tip
        kind for a given set of options. Thus, when a user uses
        |foo[length=5pt,open]| once more later anywhere in the document, the
        setup code will not be executed again.
    \item The next thing that happens is that we have a look at the
        \emph{drawing code} stored in the |code| field of the arrow. In our
        example, the drawing code would consist of creating a filled path with
        four straight segments.

        In most cases, what happens now is that the drawing code is executed in
        a special sandbox in which the low-level driver commands that do the
        actual drawing are intercepted and stored away in a so-called
        \emph{cache}. Once such a cache has been created, its contents will be
        reused whenever |foo[length=5pt,open]| is requested by a user and just
        like the setup code, the drawing code will not be executed again.

        There are, however, two cases in which the drawing code gets executed
        each time the arrow is used: First, an arrow tip kind can specify that
        this should always happen by saying |cachable=false| in its definition.
        This is necessary if the drawing code contains low-level drawing
        commands that cannot be intercepted such as a use of |\pgftext| for
        arrow tips that ``contain text''. Second, when the |bend| option is
        used, the same arrow tip will look different each time it is used,
        namely in dependence on the exact curvature of the path to which it is
        added.

        Because the drawing code may be executed several times, while the setup
        code may not, we must find a way to ``communicate'' the values computed
        by the setup code to the drawing code. This is done by explicitly
        calling |\pgfarrowssave| inside the setup code. Whatever is ``saved''
        in this way is restored each time before the drawing code is executed.
\end{enumerate}

As can be seen, the process is a bit involved, but it leads to a reasonably
fast arrow tip management.


\subsection{Declaring an Arrow Tip Kind}

\begin{command}{\pgfdeclarearrow\marg{config}}
    This command is both used to define a new arrow tip kind and to to declare
    a so-called shorthand. We have a look at the case that a complete new arrow
    tip kind is created and then have a look how the command can be used to
    create shorthands.


    \medskip
    \noindent\textbf{Defining a Complete New Arrow Tip Kind.}
    The \meta{config} is a key--value list in which different keys are used to
    setup the to-be defined arrow. The following keys can be given:
    %
    \begin{itemize}
        \item \declare{|name|}|=|\meta{name} or |name=|\meta{start
            name}|-|\meta{end name}

            This defines the name of the arrow tip. It is legal to define an
            arrow tip a second time, in this case the previous definition will
            be overwritten in the current \TeX\ scope. It is customary to use a
            name with an uppercase first letter for a ``complete'' arrow tip
            kind. Short names and lower case names should be used for
            shorthands that change their meaning inside a document, while arrow
            tips with uppercase first letters should not be redefined.

            If the name contains a hyphen, the second syntax is assumed and
            everything before the hyphen will be the name used in start arrow
            specifications, while the text after the hyphen is the name used in
            end specifications.
        \item \declare{|parameters|}|=|\marg{list of macros}

            As explained earlier, an arrow tip typically needs to be redrawn
            each time an option like |length| or |inset| is changed. However,
            for some arrow tips, the |inset| has no influence, while for other
            it is important whether the arrow is reversed or not. (How keys
            like |length| actually set \TeX\ dimensions like |\pgfarrowlength|
            is explained in Section~\ref{section-arrow-options}.)

            The job of the |parameters| key is to specify which dependencies
            the arrow tip has. Everything that will influence any of the
            parameters computed in the setup code or used in the drawing code
            should be listed here.

            The \meta{list of macros} will be used inside a
            |\csname|-|\endcsname| pair and should expand to the current values
            of the relevant parameters have. For example, if the arrow tip
            depends on the current value of |\pgfarrowlength| and
            |\pgfarrowwidth| only, then \meta{list of macros} should be set to
            |\the\pgfarrowlength,\the\pgfarrowwidth|. (Actually, the comma is
            optional, the \meta{list of macros} does not really have to be a
            list, just something that can be expanded unambiguously.)

            Note that the line width (|\pgflinewidth|) and the inner line width
            (|\pgfinnerlinewidth|) are always parameters and need not be
            specified in the |parameters|.

            It is important to get this parameter right. Otherwise, arrow tips
            may look wrong because \pgfname\ thinks that it can reuse some code
            when, in reality, this code actually depends on a parameter not
            listed here.
        \item \declare{|setup code|}|=|\marg{code}

            When an arrow tip is used, the value stored in |parameters| is
            expanded and it is tested whether the result was encountered
            before. If not, the \meta{code} gets executed (only this once). The
            code can now do arbitrarily complicated computations the prepare
            the later drawing of the arrow tip. Also the \meta{code} must
            specify the different tip and back ends and the convex hull points.
            This is done by calling the following macros inside the
            \meta{code}:
            %
            \begin{command}{\pgfarrowssettipend\marg{dimension}}
                When this command is called inside the setup code of an arrow
                tip, it specifies that the tip of the drawn arrow will end
                exactly at \meta{dimension}. For example, for our earlier
                example of the large arrow tip, where the tip end was at 1cm,
                we would call
                %
\begin{codeexample}[code only]
\pgfarrowssettipend{1cm}
\end{codeexample}
                %
                Note that for efficiency reasons, the \meta{dimension} is not
                passed through |\pgfmathsetlength|; rather what happens is that
                |\pgf@x=|\meta{dimension} gets executed. In particular, you can
                pack further computations into the \meta{dimension} by simply
                starting it with a number and then appending some code that
                modifies |\pgf@x|. Here is an example where instead of 1cm we
                use $1\mathrm{cm} - \frac12\mathrm{linewidth}$ as the tip end:
                %
\begin{codeexample}[code only]
\pgfarrowssettipend{1cm\advance\pgf@x by-.5\pgflinewidth}
\end{codeexample}
                %
                If the command is not called at all inside the setup code, the
                tip end is set to |0pt|.
            \end{command}

            \begin{command}{\pgfarrowssetbackend\marg{dimension}}
                Works like the command for the tip end, only it sets the back
                end. In our example we would call
                %
\begin{codeexample}[code only]
\pgfarrowssettipend{-3cm}
\end{codeexample}
                %
                Defaults to |0pt|.
            \end{command}

            \begin{command}{\pgfarrowssetlineend\marg{dimension}}
                Sets the line end, so in the example we have
                |\pgfarrowssettipend{-1cm}|. Default to |0pt|.
            \end{command}

            \begin{command}{\pgfarrowssetvisualbackend\marg{dimension}}
                Sets the visual back end, |\pgfarrowssetvisualbackend{-2cm}| in
                our example. Default to the value of the normal back end.
            \end{command}

            \begin{command}{\pgfarrowssetvisualtipend\marg{dimension}}
                Sets the visual tip end. Default to the value of the normal tip
                end and, thus, we need not set it in our example.
            \end{command}

            \begin{command}{\pgfarrowshullpoint\marg{x dimension}\marg{y dimension}}
                Adds a point to the convex hull of the arrow tip. As for the
                previous commands, no math parsing is done; instead \pgfname\
                says |\pgf@x=|\meta{x dimension} and then |\pgf@y=|\meta{y
                dimension}. Thus, both ``dimensions'' can contain code for
                advancing and thus modifying |\pgf@x| and |\pgf@y|.

                In our example we would write
                %
\begin{codeexample}[code only]
\pgfarrowshullpoint{1cm}{0pt}
\pgfarrowshullpoint{-3cm}{2cm}
\pgfarrowshullpoint{-3cm}{-2cm}
\end{codeexample}
            \end{command}

            \begin{command}{\pgfarrowsupperhullpoint\marg{x dimension}\marg{y dimension}}
                This command works like the previous command, only it normally
                adds \emph{two} points to the convex hull: First, the point
                $(\meta{x dimension},\meta{y dimension})$ and, secondly, the
                point $(\meta{x dimension},-\meta{y dimension})$. However, the
                second point is only added if the arrow is not a harpoon.

                Thus, in our example we could simplify the convex hull to
                %
\begin{codeexample}[code only]
\pgfarrowshullpoint{1cm}{0pt}
\pgfarrowsupperhullpoint{-3cm}{2cm}
\end{codeexample}
                %
                If the \meta{y dimension} is zero or less, only one point,
                namely $(\meta{x dimension},\meta{y dimension})$, is added to
                the hull. Thus, we could also have used the upper convex hull
                command in the first of the two of the above commands.
            \end{command}

            \begin{command}{\pgfarrowssave\marg{macro}}
                As explained earlier, the setup code needs to ``communicate''
                with the drawing code via ``saved values''. This command get
                the name of a macro and will store the value this macro had
                internally. Then, each time drawing code is executed, the value
                of this macro will be restored.
            \end{command}

            \begin{command}{\pgfarrowssavethe\marg{register}}
                Works like |\pgfarrowssave|, only the parameter must be a
                register and |\the|\meta{register} will be saved. Typically,
                you will write something like
                %
\begin{codeexample}[code only]
\pgfarrowssavethe{\pgfarrowlength}
\pgfarrowssavethe{\pgfarrowwidth}
\end{codeexample}
                %
                To ensure that inside the drawing code the the dimension
                registers |\pgfarrowlength| and |\pgfarrowwidth| are setup with
                the values they had during the setup.
            \end{command}
        \item \declare{|drawing code|}|=|\marg{code}

            This code will be executed at least once for each setting of the
            parameters when the time arrow tip is actually drawn. Usually, this
            one execution will be all and the low-level commands generated
            inside the \meta{code} will we stored in a special cache; but in
            some cases the \meta{code} gets executed each time the arrow tip is
            used, so do not assume anything about it. Inside the \meta{code},
            you have access to all values that were saved in the setup code as
            well as to the line width.

            The \meta{code} should draw the arrow tip ``going right along the
            $x$-axis''. \pgfname\ will take care of setting up a  canvas
            transformation beforehand to a rotation such that when the drawing
            is rendered, the arrow tip that is  actually drawn points in the
            direction of the line. Alternatively, when bending is switched on,
            even more complicated low-level transformations will be done
            automatically.

            The are some special considerations concerning the \meta{code}:
            %
            \begin{itemize}
                \item In the \meta{code} you may \emph{not} use |\pgfusepath|
                    since this would try to add arrow tips to the arrow tip and
                    lead to a recursion. Use the ``quick'' versions
                    |\pgfusepathqstroke| and so on instead, which never try to
                    add arrow tips.
                \item If you stroke the path that you construct, you should
                    first set the dashing to solid and set up fixed joins and
                    caps, as needed. This will ensure that the arrow tip will
                    always look the same.
                \item When the arrow tip code is executed, it is automatically
                    put inside a low-level scope, so nothing will ``leak out''
                    from the scope.
                \item The high-level coordinate transformation matrix will be
                    set to the identity matrix when the code is executed for
                    the first time.
            \end{itemize}
        \item \declare{|cache|}|=|\meta{true or false}

            When set to |true|, which is the default, the \meta{code} will be
            executed only once for a particular value of parameters and the
            low-level commands created by the drawing code (using the system
            layer protocol subsystem, see Section~\ref{section-protocols}) will
            be cached and reused later on. However, when the drawing code
            contains ``uncachable'' code like a call to |\pgftext|, caching
            must be switched off by saying |cache=false|.
        \item \declare{|bending mode|}|=|\meta{mode}

            This key is important only when the |bend| option is used with an
            arrow, see Section~\ref{section-arrow-flex} for an introduction to
            this option. The |bend| option asks us to, well, bend the arrow
            head. For some arrow head this is not possible or leads to very
            strange drawings (for instance, when the |\pgftext| command is
            used) and then it is better to switch bending off for the arrow
            head (|flex| will then be used instead). To achieve this, set
            \meta{mode} to |none|.

            For most arrow tips it does, however, make sense to bend them.
            There are (at least) two different mathematical ways of doing so,
            see Section~\ref{section-library-curvilinear} for details. Which of
            these ways is use can be configured by setting \meta{mode} to
            either |orthogonal| or to |polar|. It is best to try simply try out
            both when designing an arrow tip to see which works better. Since
            |orthogonal| is quicker and often gives good oder even better
            results, it is the default. Some arrow tips, however, profit from
            saying |bending mode=polar|.
        \item \declare{|defaults|}|=|\meta{arrow keys}

            The \meta{arrow keys} allow you to configure the default values for
            the parameters on which an arrow tip depends. The \meta{arrow keys}
            will be executed first before any other arrow tip options are
            executed, see Section~\ref{section-arrow-scopes} for the exact
            sequence. Also see Section~\ref{section-arrow-options} below for
            more details on arrow options.
    \end{itemize}

    This concludes the description of the keys you provide for the declaration
    of an arrow. Let us now have a look at a simple example that uses these
    features: We want to define an arrow tip kind |foo| that produces the arrow
    tip we used as our running example. However, to make things a bit more
    interesting, let us make it ``configurable'' insofar as the length of the
    arrow tip can be configured using the |length| option, which sets the
    |\pgfarrowlength|. By default, this length should be the gigantic 4cm we
    say in the example, but uses should be able to set it to anything they
    like. We will not worry about the arrow width or insets, of arrow line
    width, or harpoons, or anything else in this example to keep it simple.

    Here is the code:
    %
\begin{codeexample}[code only]
\pgfdeclarearrow{
  name = foo,
  parameters = { \the\pgfarrowlength },
  setup code = {
    % The different end values:
    \pgfarrowssettipend{.25\pgfarrowlength}
    \pgfarrowssetlineend{-.25\pgfarrowlength}
    \pgfarrowssetvisualbackend{-.5\pgfarrowlength}
    \pgfarrowssetbackend{-.75\pgfarrowlength}
    % The hull
    \pgfarrowshullpoint{.25\pgfarrowlength}{0pt}
    \pgfarrowshullpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}
    \pgfarrowshullpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}
    % Saves: Only the length:
    \pgfarrowssavethe\pgfarrowlength
  },
  drawing code = {
    \pgfpathmoveto{\pgfqpoint{.25\pgfarrowlength}{0pt}}
    \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}}
    \pgfpathlineto{\pgfqpoint{-.5\pgfarrowlength}{0pt}}
    \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}}
    \pgfpathclose
    \pgfusepathqfill
  },
  defaults = { length = 4cm }
}
\end{codeexample}
    %
    We can now use it:
    %
\pgfdeclarearrow{
  name = foo,
  parameters = { \the\pgfarrowlength },
  setup code = {
    % The different end values:
    \pgfarrowssettipend{.25\pgfarrowlength}
    \pgfarrowssetlineend{-.25\pgfarrowlength}
    \pgfarrowssetvisualbackend{-.5\pgfarrowlength}
    \pgfarrowssetbackend{-.75\pgfarrowlength}
    % The hull
    \pgfarrowshullpoint{.25\pgfarrowlength}{0pt}
    \pgfarrowshullpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}
    \pgfarrowshullpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}
    % Saves: Only the length:
    \pgfarrowssavethe\pgfarrowlength
  },
  drawing code = {
    \pgfpathmoveto{\pgfqpoint{.25\pgfarrowlength}{0pt}}
    \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}}
    \pgfpathlineto{\pgfqpoint{-.5\pgfarrowlength}{0pt}}
    \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}}
    \pgfpathclose
    \pgfusepathqfill
  },
  defaults = { length = 4cm }
}
\begin{codeexample}[
    preamble={\usetikzlibrary{arrows.meta}},
    pre={\pgfdeclarearrow{
  name = foo,
  parameters = { \the\pgfarrowlength },
  setup code = {
    % The different end values:
    \pgfarrowssettipend{.25\pgfarrowlength}
    \pgfarrowssetlineend{-.25\pgfarrowlength}
    \pgfarrowssetvisualbackend{-.5\pgfarrowlength}
    \pgfarrowssetbackend{-.75\pgfarrowlength}
    % The hull
    \pgfarrowshullpoint{.25\pgfarrowlength}{0pt}
    \pgfarrowshullpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}
    \pgfarrowshullpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}
    % Saves: Only the length:
    \pgfarrowssavethe\pgfarrowlength
  },
  drawing code = {
    \pgfpathmoveto{\pgfqpoint{.25\pgfarrowlength}{0pt}}
    \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}}
    \pgfpathlineto{\pgfqpoint{-.5\pgfarrowlength}{0pt}}
    \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}}
    \pgfpathclose
    \pgfusepathqfill
  },
  defaults = { length = 4cm }
}},
]
\tikz \draw [-foo] (0,0) -- (8,0);
\end{codeexample}
\begin{codeexample}[
    preamble={\usetikzlibrary{arrows.meta,bending}},
    pre={\pgfdeclarearrow{
  name = foo,
  parameters = { \the\pgfarrowlength },
  setup code = {
    % The different end values:
    \pgfarrowssettipend{.25\pgfarrowlength}
    \pgfarrowssetlineend{-.25\pgfarrowlength}
    \pgfarrowssetvisualbackend{-.5\pgfarrowlength}
    \pgfarrowssetbackend{-.75\pgfarrowlength}
    % The hull
    \pgfarrowshullpoint{.25\pgfarrowlength}{0pt}
    \pgfarrowshullpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}
    \pgfarrowshullpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}
    % Saves: Only the length:
    \pgfarrowssavethe\pgfarrowlength
  },
  drawing code = {
    \pgfpathmoveto{\pgfqpoint{.25\pgfarrowlength}{0pt}}
    \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}}
    \pgfpathlineto{\pgfqpoint{-.5\pgfarrowlength}{0pt}}
    \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}}
    \pgfpathclose
    \pgfusepathqfill
  },
  defaults = { length = 4cm }
}},
]
\tikz \draw [-{foo[length=2cm,bend]}] (0,0) to [bend left] (3,0);
\end{codeexample}


    \medskip
    \noindent\textbf{Defining a Shorthand.}
    The |\pgfdeclarearrow| command can also used to define
    \emph{shorthands}. This works as follows:
    \begin{itemize}
        \item First, you must provide a |name| just in the same way as when you
            define a full-flung new arrow tip kind.
        \item Second, instead of all of the other options listed above, you
            just use one more option:

            \smallskip
            \declare{|means|}|=|\meta{end arrow specification}

            This sets up things so that whenever \meta{name} is now used in an
            arrow specification, it will be replaced by the \meta{end arrow
            specification} (the problems resulting form the \meta{name} begin
            used in a start arrow  specification are taken care of
            automatically). See also Section~\ref{section-arrow-tip-macro} for
            details on the order in which options get executed in such cases.

            Note that the \meta{end arrow specification} will be executed
            immediately to build the so-called arrow option caches, a concept
            explored in more detail in
            Section~\ref{section-arrow-option-cache}. In practice, this has
            mainly two effects: First, all arrow tips referred to in the
            specification must already exist (at least as ``dummy'' versions).
            Second, all dimensions mentioned in options of the \meta{end arrow
            specification} will be evaluated immediately. For instance, when
            you write
            %
\begin{codeexample}[code only]
\pgfdeclarearrow{ name=foo, means = bar[length=2cm+\mydimen] }
\end{codeexample}
            %
            The value |2cm+\mydimen| is evaluated immediately. When |foo| is
            used later on and |\mydimen| has changed, this has no effect.
    \end{itemize}
\end{command}


\subsection{Handling Arrow Options}
\label{section-arrow-options}

When you declare an arrow tip, your drawing code should take into account the
different arrow keys set for it (like the arrow tip length, width, or
harpooning). The different arrow keys that are available have been described in
detail in Section~\ref{section-arrow-config}; but how do we access the values
set by an option like |length| or |harpoon| or |bend| in the drawing code? In
the present section we have a look at how this works.


\subsubsection{Dimension Options}

Most arrow keys, like |length| or |width'|, simple set a \TeX\ dimension
register to a certain value. For example, |length| sets the value of the \TeX\
dimension register |\pgfarrowlength|. Note that |length| takes several values
as input with a complicated semantics as explained for the |length| key on
page~\pageref{length-arrow-key}. All of these settings are not important for
the setup code: When it gets executed, the code behind the |length| key will
have computed a simple number that is stored in |\pgfarrowlength|. Indeed,
inside the setup code you do not have access to the exact value given to the
|length| key; just to the final computed value.

The following \TeX\ dimensions are available to the setup code:
%
\begin{itemize}
    \item |\pgfarrowslength|. It gets set by the arrow keys |length| and
        |angle|.
    \item |\pgfarrowswidth|. It gets set by |width|, |width'|, and |angle|.
    \item |\pgfarrowsinset|. It gets set by |inset| and |inset'|.
    \item |\pgfarrowslinewidth|. It gets set by |line width| and |line width'|.
\end{itemize}

If your setup code depends on any of them, add them to the |parameters| key of
the arrow tip.


\subsubsection{True--False Options}

A number of arrow keys just do a yes/no switch, like |reversed|. All of them
setup a \TeX-if that you can access in the setup code:
%
\begin{itemize}
    \item |\ifpgfarrowreversed| is setup by |reversed|.
    \item |\ifpgfarrowswap| is setup by |swap| and also |right|.
    \item |\ifpgfarrowharpoon| is setup by |harpoon| and also |left| and
        |right|.
    \item |\ifpgfarrowroundcap| is set to true by |line cap=round| and set to
        false by |line cap=butt|. It also gets (re)set by  |round| and |sharp|.
    \item |\ifpgfarrowroundjoin| is set to true by |line join=round| and set to
        false by |line join=miter|. It also gets (re)set by  |round| and
        |sharp|.
    \item |\ifpgfarrowopen| is set to true by |fill=none| and by |open| (which
        is a shorthand for |fill=none|) and set to false by |color| and all
        other |fill=|\meta{color}.
\end{itemize}

If you code depends on any of these, you must add them to the |parameters| in
such a way that the parameters are different when the \TeX-if is set from when
it is not set. An easy way to achieve this is to write something like
%
\begin{codeexample}[code only]
  parameters = { \the\pgfarrowlength,...,
                 \ifpgfarrowharpoon h\fi\
                 \ifpgfarrowroundjoin j\fi}
\end{codeexample}
%
In other words, for each set parameter on which the arrow tip depends, a
specific letter is added to the parameters, making them unique.

The first two of the above keys are a bit special: Reversing and swapping an
arrow tip can be done just by fiddling with the transformation matrix: a
reverse is a ``flip'' along the $y$-axis and a swap is a flip along the
$x$-axis. This is done automatically by \pgfname.

Nevertheless, you may wish to modify you code in dependence especially of the
|reverse| key: When |\ifpgfarrowreverse| is true, \pgfname\ will flip the
coordinate system along the $y$-axis, will negate all end values (like line
end, tip end, and so on) and will exchange the meaning of back end and tip end
as well as of visual back end and visual back end. Usually, this is exactly
what one need; \emph{except} that the line end may no longer be appropriate.
After all, the line end should be chosen so that it is completely covered by
the arrow. Now, when the arrow tip is open, a reversed arrow should no longer
have the line end near the old visual back end, but near to the old visual tip
end.

For these reasons, you may need to make the computation of the line end
dependent on whether the arrow is reversed or not. Note that when you specify a
different line end for a reversed arrow tip, the transformation and inverting
of the coordinate system will still be done, meaning that if |reverse| is true,
you need to specify a line end in the ``old'' coordinate system that is at the
position where, after everything is inverted, it will be at the correct
position. Usually that means that if the |reverse| option is set, you need to
\emph{increase} the line end.


\subsubsection{Inaccessible Options}

There are some options that influence the way an arrow tip looks, but that you
cannot access inside the setup code. Handling these options lies entirely with
\pgfname. If you wish your setup code to handle these options, you have to
setup your own ``parallel'' options.
%
\begin{itemize}
    \item |quick|, |flex|, |flex'|, and |bend| are all handled automatically.
        You can, however, set the |bending mode| to avoid bending of your arrow
        tip.
    \item The colors set by |color| and |fill|. You can, however, access them
        indirectly, namely through the current stroke and fill colors.
    \item |sep|
\end{itemize}


\subsubsection{Defining New Arrow Keys}
\label{section-arrow-option-cache}

The set of predefined options is already quite long and most arrow tips will
not need more than the predefined options. However, sometimes an arrow tip may
need to introduce a new special-purpose option. For instance, suppose we wish
to introduce a new fictive arrow key |depth|. In such cases, you must do two
things:
%
\begin{enumerate}
    \item Introduce a new dimension register or macro that will hold the
        configuration value and which will be accessed by the setup code. The
        could be achieved by saying
        %
\begin{codeexample}[code only]
\newdimen\pgfarrowdepth
\end{codeexample}
        %
    \item Introduce a new arrow key option |/pgf/arrow keys/depth| that allows
        users to configure the new macro or register.
\end{enumerate}

When an arrow is selected via for instance |foo[depth=5pt]|, the key--value
pairs between the square brackets are executed with the path prefix
|/pgf/arrow keys|. Thus, in the example, our depth key would get executed.
Thus, it is tempting to write something like
%
\begin{codeexample}[code only]
\pgfkeys{/pgf/arrow keys/depth/.code = \pgfmathsetlength{\pgfarrowdepth}{#1}}
\end{codeexample}

Sadly, this will not work. The reason is that there is yet another level of
caching involved when \pgfname\ processes arrow tips: The option cache! The
problem is each time an arrow tip is used, even when the drawing code of the
arrow tip is nicely cached, we still need to process the options in
|foo[length=5pt]| to find out which version in the cache we would like to
access. To make matters worse, |foo| might be a shorthand that calls other
arrow tips, which add more options, and so on. Unfortunately, executing keys is
quite an expensive operation (\pgfname's key--value parser is powerful, but
that power comes at a price). So, whenever possible, we do \emph{not} want the
key--value parser to be started.

For these reasons, when something like |foo[|\meta{options}|]| is encountered
inside a shorthand, the \meta{options} are executed only once. They should now
setup the \emph{arrow option cache}, which is some code that, when executed,
should setup the values that the \meta{options} configure. In our example, the
|depth| key should add something to the arrow option cache that sets
|\pgfarrowdepth| to the given value.

Adding something to the arrow option cache is done using the following command:

\begin{command}{\pgfarrowsaddtooptions\marg{code}}
    This command should be called by keys with the prefix |/pgf/arrow keys| to
    add code to the arrow option cache. For our |depth| key example, we could
    use this key as follows:
    %
\begin{codeexample}[code only]
\pgfkeys{/pgf/arrow keys/depth/.code=
  \pgfarrowsaddtooptions{\pgfmathsetlength{\pgfarrowdepth}{#1}}
\end{codeexample}
    %
    Actually, this is still not optimal since the expensive |\pgfmathsetlength|
    command is now called each time an arrow tip is used with the |depth|
    option set. The trick is to do the expensive operation only once and then
    store only very quick code in the arrow option cache:
    %
\begin{codeexample}[code only]
\pgfkeys{/pgf/arrow keys/depth/.code=
  \pgfmathsetlength{\somedimen}{#1}
  \pgfarrowsaddtooptions{\pgfarrowdepth=\somedimen} % buggy
\end{codeexample}
    %
    The above code will not (yet) work since |\somedimen| will surely have a
    different value when the cache is executed. The trick is to use some
    |\expandafter|s:
    %
\begin{codeexample}[code only]
\pgfkeys{/pgf/arrow keys/depth/.code=
  \pgfmathsetlength{\somedimen}{#1}
  \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrowdepth\expandafter=\the\somedimen}
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfarrowsaddtolateoptions\marg{code}}
    This command works like |\pgfarrowsaddtooptions|, only the \meta{code} will
    be executed ``later'' than the code added by the normal version of the
    command. This is useful for keys that depend on the length of an arrow:
    Keys like |width'| want to define the arrow width as a multiple of the
    arrow length, but when the |width'| key is given, the length may not yet
    have been specified. By making the computation of the width a ``late''
    option, we ensure that |\pgfarrowlength| will have been setup correctly.
\end{command}

If you define a new option that sets a dimensions and if that dimension should
change in accordance to the setting of either |scale length| or |scale width|,
you need to make \pgfname\ ``aware'' of this using the following key:

\begin{command}{\pgfarrowsaddtolengthscalelist\marg{dimension register}}
    Each time an arrow tip is used, the given \meta{dimension register} will be
    multiplied by the |scale length| factor prior to the actual drawing. You
    call this command only once in the preamble somewhere.
\end{command}

\begin{command}{\pgfarrowsaddtowidthscalelist\marg{dimension register}}
    Works like |\pgfarrowsaddtolengthscalelist|, only for width parameters.
\end{command}


\begin{command}{\pgfarrowsthreeparameters\marg{line-width dependent size specification}}
    This command is useful for parsing the values given to keys like |length|
    or |width| the expect a dimension followed optionally for some numbers.
    This command converts the \meta{line-width dependent size specification},
    which may consist of one, two, or three numbers, into a triple of three
    numbers in curly braces, which gets stored in the macro
    |\pgfarrowstheparameters|. Here is an example, where |\showvalueofmacro| is
    used in this example to show the value stored in a macro:
    %
\begin{codeexample}[setup code,hidden]
    \makeatletter
    \def\showvalueofmacro#1{%
        \texttt{\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@gobble\expandafter\expandafter\expandafter\string\expandafter\csname#1\endcsname}
    }%
\end{codeexample}
%
\begin{codeexample}[]
\pgfarrowsthreeparameters{2pt 1}
\showvalueofmacro\pgfarrowstheparameters
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfarrowslinewidthdependent\marg{dimension}\marg{line width factor}\marg{outer factor}}
    This command takes three parameters and does the ``line width dependent
    computation'' described on page~\pageref{length-arrow-key} for the |length|
    key. The result is returned in |\pgf@x|.

    The idea is that you can setup line-width dependent keys like |length| or
    |width| using code like the following:
    %
\begin{codeexample}[code only]
\pgfkeys{/pgf/arrow keys/depth/.code={%
  \pgfarrowsthreeparameters{#1}%
  \expandafter\pgfarrowsaddtolateoptions\expandafter{%
    \expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters% compute...
    \pgfarrowdepth\pgf@x% ... and store.
  }%
}
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfarrowslengthdependent\marg{dimension}\marg{length factor}\marg{dummy}}
    This command takes three parameters, of which the last one is ignored, and
    does the ``length dependent computation'' described for the |width'| and
    |inset'| keys. The result is returned in |\pgf@x|.

    You can setup length dependent keys using code like the following:
    %
\begin{codeexample}[code only]
\pgfkeys{/pgf/arrow keys/depth'/.code={%
  \pgfarrowsthreeparameters{#1}%
  \expandafter\pgfarrowsaddtolateoptions\expandafter{%
    \expandafter\pgfarrowslengthdependent\pgfarrowstheparameters% compute...
    \pgfarrowdepth\pgf@x% ... and store.
  }%
}
\end{codeexample}
    %
\end{command}


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