diff options
Diffstat (limited to 'Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex')
-rw-r--r-- | Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex | 1298 |
1 files changed, 648 insertions, 650 deletions
diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex index 15926efe567..b26efb1b87c 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex @@ -11,64 +11,61 @@ \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. +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: +|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}; + \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 @@ -88,434 +85,431 @@ Here, by comparison, are the same arrows when they are simply ``resized'': \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. +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. +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'': - +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$};; + \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. +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 form 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. + \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 form 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. +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. +\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} ornot. -\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{drawin 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. + \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{drawin 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. +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 fist 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 unambiuously.) - - 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 aribtrarily 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 + 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 fist 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} +\pgfarrowssettipend{1cm} \end{codeexample} - Note that for efficience 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: + % + 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} +\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 + % + 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} +\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 + % + 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} + \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. - \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 + 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 + % + 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. + % + 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} - - \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 partiular 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 examlpe. 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: + + 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, @@ -534,17 +528,19 @@ a reasonably fast arrow tip management. \pgfarrowssavethe\pgfarrowlength }, drawing code = { - \pgfpathmoveto{.25\pgfarrowlength}{0pt} - \pgfpathlineto{-.75\pgfarrowlength}{.5\pgfarrowlength} - \pgfpathlineto{-.5\pgfarrowlength}{0pt} - \pgfpathlineto{-.75\pgfarrowlength}{-.5\pgfarrowlength} + \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: + % + We can now use it: + % \pgfdeclarearrow{ name = foo, parameters = { \the\pgfarrowlength }, @@ -570,306 +566,305 @@ a reasonably fast arrow tip management. \pgfusepathqfill }, defaults = { length = 4cm } -} +} \begin{codeexample}[] -\tikz \draw [-foo] (0,0) -- (8,0); +\tikz \draw [-foo] (0,0) -- (8,0); \end{codeexample} \begin{codeexample}[] -\tikz \draw [-{foo[length=2cm,bend]}] (0,0) to [bend left] (3,0); +\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 + + \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] } +\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} + % + 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. +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. +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'|. + \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. +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: - +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}. + \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 +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} + \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. +% +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. +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. - +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| + \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 introcue a new fictive arrow -key |depth|. In such cases, you must do two things: - +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 + \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. + % + \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 temping to write something like +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 the 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 +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. +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: +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: + 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: + % + 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: + % + 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. + 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: +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. + 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. + 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: - \makeatletter - \def\showvalueofmacro#1{% - \texttt{\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@gobble\expandafter\expandafter\expandafter\string\expandafter\csname#1\endcsname} - } +\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: + % + \makeatletter + \def\showvalueofmacro#1{% + \texttt{\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@gobble\expandafter\expandafter\expandafter\string\expandafter\csname#1\endcsname} + } \begin{codeexample}[] \pgfarrowsthreeparameters{2pt 1} -\showvalueofmacro\pgfarrowstheparameters +\showvalueofmacro\pgfarrowstheparameters \end{codeexample} + % \end{command} +\begin{command}{\pgfarrowslinewidthdependent\marg{dimension}\marg{line width factor}\marg{outer factor}} + This command take 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|. -\begin{command}{\pgfarrowslinewidthdependent\marg{dimension}\marg{line - width factor}\marg{outer factor}} - This command take 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: + 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}% @@ -877,16 +872,18 @@ of this using the following key: \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 take 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|. + This command take 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: + You can setup length dependent keys using code like the following: + % \begin{codeexample}[code only] \pgfkeys{/pgf/arrow keys/depth'/.code={% \pgfarrowsthreeparameters{#1}% @@ -894,8 +891,9 @@ of this using the following key: \expandafter\pgfarrowslengthdependent\pgfarrowstheparameters% compute... \pgfarrowdepth\pgf@x% ... and store. }% -} +} \end{codeexample} + % \end{command} |