diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex | 1318 |
1 files changed, 969 insertions, 349 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex index 19e73e0b44e..d0fdab957aa 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex @@ -1,4 +1,4 @@ -% Copyright 2006 by Till Tantau +% Copyright 2006, 2013 by Till Tantau % % This file may be distributed and/or modified % @@ -7,406 +7,1061 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorearrows.code.tex,v 1.11 2008/04/23 14:59:01 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorearrows.code.tex,v 1.40 2013/11/07 15:45:46 tantau Exp $ -% Sets the end arrow + +% Define a new (meta) arrow or a shorthand % -% #1 = An arrow name +% #1 = key--value pairs % -% Example: +% Description: % -% \pgfsetarrowsend{stealth} - -\def\pgfsetarrowsend#1{\pgf@arrowset{end}{#1}} -\def\pgf@arrowset#1#2{% - \pgfutil@ifundefined{pgf@arrow@code@#2} - {\PackageError{pgf}{Arrow #1 type ``#2'' unknown}{}} - {% - \edef\pgf@arrow@temp{#2}% - \ifx\pgf@arrow@temp\pgfutil@empty% ah. clear! - \expandafter\let\csname pgf@#1arrow\endcsname=\pgfutil@empty% - \expandafter\let\csname pgf@shorten@#1\endcsname=\pgfutil@empty% +% This command is used to define a new arrow tip kind. For more +% details on the description of the keys, please see the pgfmanual. +% +% name = Name of the arrow. If the name contains a dash +% (hyphen), the text before the hyphen is the start name +% and the text behind it the end name. +% +% means = If set, none of the below options may be +% given. The effect is that whenever the arrow is +% used, it gets replaced by this "text", which is +% parsed by the parser. +% +% setup code = Code that does "precomputations". These will be +% executed only once for each combination of the +% dependencies. At the end of this code, you can use +% \savethe and \save to "save" computed values, which +% will then be available inside the "code". Values needed +% only for the "... end" keys and the convex hull do not +% need to be saved since these are also executed only +% once. +% drawing code = Code for drawing the arrow. When the cache key is set to +% true, which is the default, the code will be protocolled +% and the resulting code is inserted using \pgflowlevelobj. +% cache = Boolean that decides whether the arrow can be cached. The +% default is true, so you have to say cache=false to switch +% caching off. In this case, each time the arrow is drawn, +% its code is simply executed. This allows you to put things +% like text or shadings in arrow tips. +% bending mode = Can be set to "orthogonal", "polar", or +% "none". Defaults to "orthogonal". +% defaults = A list of "default" options for the arrow tip. These +% are executed as if they were given to the arrow tip in +% brackets. This is useful for setting up default values. +% parameters = A list of comma-separated macro names on whose values +% the appearance of the arrow tip depends. When an arrow +% tip is used, these macros are expanded. If an +% arrow tip was already installed with the same macro +% names (and caching is true), the cached code is +% used. Note that when you use dimensions here, add \the. +% +% Inside the setup code, the following macros are available: +% +% \pgfarrowsettipend +% The code should draw an arrow pointing "right along the x +% axis". The "tip" key specifies how far the arrow goes +% along the x axis, that is, it should be the x coordinate +% of the very tip of the arrow. In previous versions this +% was called the "right extend". The value passed to this +% key should be some code that sets the dimension +% "\pgfarrowresult", which is \let to be equal to +% \pgf@x. A \relax will be added after the code provided +% here, so you can write things like "\pgfarrowresult=1pt". +% \pgfarrowsetbackend +% The leftmost x-coordinate that is still part of the +% arrow tip (the "back end" of the arrow"). This coordinate +% will be used when multiple arrow tips are +% composed. Defaults to 0pt. +% \pgfarrowsetlineend +% The x-coordinate where a line should stop inside the arrow +% tip so that it gets "obscured" by the arrow. Defaults to 0pt. +% \pgfarrowsetvisualtipend +% When the arrow tip is drawn in flex mode, it is rotated +% such that the x-coordinates of "visual tip end" and "visual +% back end" lie on the path. Defaults to \pgfarrowsettipend. +% \pgfarrowsetvisualbackend +% See above. Defaults to \pgfarrowsetbackend + +\def\pgfdeclarearrow#1{% + \let\pgf@decl@arrow@defaults\pgfutil@empty% + \let\pgf@decl@arrow@means\relax% + \let\pgf@decl@arrow@code\relax% + \pgfkeys{/pgf/@arrows decl/.cd, + name=, + setup code=, + cache=true, + bending mode=orthogonal, + parameters=,% + #1% + }% + \ifx\pgf@decl@arrow@name@end\pgfutil@empty% + \pgferror{Declaring unnamed arrow}% + \else% + \pgf@arrow@letter{name@end}% + \pgf@arrow@letter{name@start}% + \expandafter\let\csname pgf@ar@start@\pgf@decl@arrow@name@start\endcsname\pgf@decl@arrow@name@end% + \expandafter\let\expandafter\pgf@old@code\csname pgf@ar@code@\pgf@decl@arrow@name@end\endcsname% + \expandafter\let\expandafter\pgf@old@means\csname pgf@ar@means@\pgf@decl@arrow@name@end\endcsname% + \ifx\pgf@decl@arrow@code\relax% + \ifx\pgf@decl@arrow@means\relax% + \pgferror{You must set either the 'means' or the drawing code' keys for arrow tip '\pgf@decl@arrow@name@end'}% + \else% + \ifx\pgf@old@code\relax% + \let\pgf@arrow@tip@sequence\pgfutil@empty% + \let\pgf@arrow@translate\relax% + \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@end@\pgf@decl@arrow@means\endcsname% + \ifx\pgf@arrows@direct\relax% + \let\pgf@arrows@options\pgfutil@empty% + \expandafter\pgfarrows@initial@parser\pgf@decl@arrow@means[]\pgf@stop% + \else% + \let\pgf@arrow@tip@sequence\pgf@arrows@direct% + \fi% + \pgf@arrow@letter@\pgf@arrow@tip@sequence{means}% + \expandafter\let\csname pgf@ar@code@\pgf@decl@arrow@name@end\endcsname\relax% + \else% + \pgferror{Arrow tip '\pgf@decl@arrow@name@end' was already + defined with key 'drawing code' previously and you cannot change this}% + \fi% + \fi% \else% - %\pgf@arrow@prepare{#2}% - \expandafter\def\csname pgf@#1arrow\endcsname{\pgf@arrow@call{#2}}% - \expandafter\edef\csname pgf@shorten@#1\endcsname{\expandafter\noexpand\csname pgf@arrow@right@#2\endcsname}% + \ifx\pgf@decl@arrow@means\relax% + \ifx\pgf@old@means\relax% + \pgf@arrow@letter{code}% + \pgf@arrow@letter{defaults}% + \pgf@arrow@letter{setup}% + \pgf@arrow@letter{bending@mode}% + \pgf@arrow@letter{par}% + \expandafter\let\csname pgf@ar@do@cache@\pgf@decl@arrow@name@end\endcsname\pgf@decl@arrow@cache% + \else% + \pgferror{Arrow tip '\pgf@decl@arrow@name@end' was already + defined with key 'means' previously and you cannot change this}% + \fi% + \else% + \pgferror{You cannot set both the 'means' and also the 'drawing code' + keys for arrow tip '\pgf@decl@arrow@name@end'}% + \fi% \fi% + \fi% +} + +\def\pgf@arrow@letter#1{% + \expandafter\pgf@arrow@letter@\expandafter{\csname pgf@decl@arrow@#1\endcsname}{#1}% +} +\def\pgf@arrow@letter@#1#2{% + \expandafter\let\csname pgf@ar@#2@\pgf@decl@arrow@name@end\endcsname#1% +} + +\pgfkeys{ + /pgf/@arrows decl/.cd, + name/.code={% + \pgfutil@in@-{#1}% + \ifpgfutil@in@% + \pgf@arrows@name@decomp#1\pgf@stop% + \else% + \def\pgf@decl@arrow@name@end{#1}\let\pgf@decl@arrow@name@start\pgf@decl@arrow@name@end% + \fi}, + means/.store in=\pgf@decl@arrow@means, + setup code/.store in=\pgf@decl@arrow@setup, + drawing code/.store in=\pgf@decl@arrow@code, + cache/.store in=\pgf@decl@arrow@cache, + bending mode/.is choice, + bending mode/none/.code=\let\pgf@decl@arrow@bending@mode\pgfutil@empty, + bending mode/orthogonal/.code=\def\pgf@decl@arrow@bending@mode{\pgfpointcurvilinearbezierorthogonal}, + bending mode/polar/.code=\def\pgf@decl@arrow@bending@mode{\pgfpointcurvilinearbezierpolar}, + parameters/.store in=\pgf@decl@arrow@par, + defaults/.code={% + \let\pgf@arrows@options\pgfutil@empty% + \pgfkeys{/pgf/arrow keys/.cd,#1}% + \let\pgf@decl@arrow@defaults\pgf@arrows@options% + } +} + +\def\pgf@arrows@name@decomp#1-#2\pgf@stop{% + \def\pgf@decl@arrow@name@start{#1}% + \def\pgf@decl@arrow@name@end{#2}% +} + + +% Handler for defining arrow tips: +% +% Description: +% +% When you write "my name/.tip = arrow spec", this has the same +% effect as writeing \pgfdeclarearrow{name = my name, means = arrow spec}. + +\pgfkeys{/handlers/.tip/.code=% + \expandafter\expandafter\expandafter\pgf@arrows@unravel\pgfkeyscurrentpath/\pgf@stop% + \expandafter\pgf@arrows@key@call\expandafter{\pgf@arrows@unravelled}{#1}} +\def\pgf@arrows@unravel#1/{\pgfutil@ifnextchar\pgf@stop{\def\pgf@arrows@unravelled{#1}\pgfutil@gobble}{\pgf@arrows@unravel}} +\def\pgf@arrows@key@call#1#2{\pgfdeclarearrow{name={#1},means={#2}}} + + + + +% Draw an arrow +% +% #1 = arrow specification +% +% Description: +% +% Draws the arrow in the given specification (and "end" +% specification). The arrow will be drawn such that it touches the +% origin "from the left", that is, the arrow will lie completely in +% the half plane with negative $x$ values and the tip will end exactly +% at the origin. + +\def\pgfarrowdraw#1{% + {% + \pgfsetarrowsend{#1}% + \pgf@arrow@compute@shortening\pgf@end@tip@sequence% + \pgf@arrow@draw@arrow\pgf@end@tip@sequence\pgf@xb% }% } -% Sets the start arrow -% -% #1 = An arrow name -% -% Example: -% -% \pgfsetarrowsstart{stealth} -\def\pgfsetarrowsstart#1{\pgf@arrowset{start}{\csname pgf@arrows@invert#1\endcsname}} +% Compute the length of an arrow +% +% #1 = arrow specification +% +% Description: +% +% In \pgf@x, this will return the total length of the arrow given as +% #1, in \pgf@xa it will return the distance from the tip to the line +% end. + +\def\pgfarrowtotallength#1{% + {% + \pgfsetarrowsend{#1}% + \pgf@arrow@compute@shortening\pgf@end@tip@sequence% + \expandafter\expandafter\expandafter% + }% + \expandafter\expandafter\expandafter\pgf@x\expandafter\the\expandafter\pgf@xb\expandafter\pgf@xa\the\pgf@xa% +} -\def\pgf@arrows@invname#1#2{\expandafter\def\csname pgf@arrows@invert#1\endcsname{#2}} -\pgf@arrows@invname{}{} -% Sets arrows +% Sets the end arrow tip % -% #1 = An arrow specification of the form ``left''-``right''. The last -% and right should be arrow types that have been defined using -% the \pgfarrowsdef command +% #1 = An arrow specification % -% Example: +% Description: +% +% An "arrow specification" is a sequence of names of meta arrow tips +% together with options in brackets. In detail: +% +% In #1, consider the text from the start up to the first bracket. If +% this text is the name of a (meta) arrow tip, we use this arrow tip +% with the provided options. If it is the name of a arrow tip +% shorthand, this shorthand is expanded and the options are applied to +% each arrow tip inside the shorthand. If the text is neither or the +% above, the first letter of text is treated as a shorthand without +% options. +% +% The special arrow tip "." is used to indicate the end of the line. % -% \pgfsetarrows{-to} +% \pgfsetarrowsend{stealth[reversed]} +% \pgfsetarrowsend{stealth[length=1pt] . stealth[length=2pt]} +% \pgfsetarrowsend{>>>} +% \pgfsetarrowsend{>.>} + +\def\pgfsetarrowsend#1{% + \let\pgf@arrow@tip@sequence\pgfutil@empty% + \pgf@arrows@translatefalse% + \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@end@#1\endcsname% + \ifx\pgf@arrows@direct\relax% + \edef\pgf@marshal{\noexpand\pgfarrows@initial@parser#1[]\noexpand\pgf@stop}% + \pgf@marshal% + \else% + \let\pgf@arrow@tip@sequence\pgf@arrows@direct% + \fi% + \let\pgf@end@tip@sequence\pgf@arrow@tip@sequence% +} -\def\pgfsetarrows#1{\pgf@arrows#1\pgf@stop} -\def\pgf@arrows#1-#2\pgf@stop{% - \pgfsetarrowsstart{#1} - \pgfsetarrowsend{#2} +\newif\ifpgf@arrows@translate + +\def\pgfarrows@initial@parser{% + \pgfutil@ifnextchar[\pgfarrows@initial@parser@{\pgfarrows@initial@parser@[]}}%} + +\def\pgfarrows@initial@parser@[#1]{% + \let\pgf@arrows@options\pgfutil@empty% + \pgfkeys{/pgf/arrow keys/.cd,#1}% + \let\pgf@arrows@options@initial\pgf@arrows@options% + \pgfarrows@parser% } -\def\pgf@arrows@checked#1#2#3{% - \pgfutil@ifundefined{pgf@arrow@code@#2}% - {% - \PackageError{pgf}{Arrow end type ``#2'' unknown}{}}% - {% - \pgfutil@ifundefined{pgf@arrow@code@\csname pgf@arrows@invert#1\endcsname} - {\PackageError{pgf}{Arrow start type ``#1'' unknown}{}}% - {#3}% - }% +\def\pgfarrows@parser#1[{% + \pgfkeys@spdef\pgf@temp{#1}% + \ifx\pgf@temp\pgfutil@empty% + \let\pgf@next\pgf@arrows@empty% + \else% + \ifx\pgf@temp\pgf@dot@text% + \let\pgf@next\pgf@arrows@dot@parsed% + \else% + \let\pgf@untranslated\pgf@temp% + \ifpgf@arrows@translate% + \pgf@arrow@swapper% + \fi% + % Now, let's see what we do with this... + \expandafter\ifx\csname pgf@ar@code@\pgf@temp\endcsname\relax + \expandafter\ifx\csname pgf@ar@means@\pgf@temp\endcsname\relax + % #1 should start with a single-char shorthands + \let\pgf@next\pgf@arrows@single@char@parser% + \let\pgf@temp\pgf@untranslated% + \else% + % #1 is a shorthand! + \let\pgf@next\pgf@arrows@shorthand@parsed% + \fi% + \else% + % #1 is a meta arrow! + \let\pgf@next\pgf@arrows@meta@parsed% + \fi% + \fi% + \fi% + \expandafter\pgf@next\pgf@temp[% +} + +\def\pgf@arrows@empty[#1]{% + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% +} + +\def\pgf@arrows@single@char@parser#1{% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@dot@text% + \let\pgf@next\pgf@arrows@dot@parsed% + \else% + \let\pgf@untranslated\pgf@temp% + \ifpgf@arrows@translate% + \pgf@arrow@swapper% + \fi% + \expandafter\ifx\csname pgf@ar@code@\pgf@temp\endcsname\relax + \expandafter\ifx\csname pgf@ar@means@\pgf@temp\endcsname\relax + \let\pgf@temp\pgf@untranslated% + \let\pgf@next\pgf@arrows@unknown% + \else% + \let\pgf@next\pgf@arrows@shorthand@parsed% + \fi% + \else% + \let\pgf@next\pgf@arrows@meta@parsed% + \fi + \fi + \expandafter\pgf@next\pgf@temp[]% +} +\def\pgf@arrows@unknown#1[]#2[#3]{% + \pgferror{Unknown arrow tip kind '#1#2'}% } -\def\pgf@arrows@check@already#1#2#3{% - \pgfutil@ifundefined{pgf@arrow@code@#2} - {#3}% - {\PackageError{pgf}{Arrow end type ``#2'' already defined}{}}% +\def\pgf@arrows@meta@parsed#1[#2]{% + % Ok, run the keys #2. This will add commands to \pgf@arrows@options: + % + \let\pgf@arrows@options\pgf@arrows@options@initial% + \pgfkeys{/pgf/arrow keys/.cd,#2}% + % Append the arrow and its options to the arrow tip sequence: + \expandafter\pgf@arrows@meta@set\expandafter{\pgf@arrows@options}{#1}{\pgf@arrow@handle}% + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% } +\def\pgf@arrows@parser@done#1{% +} -% Called when an arrow needs to be rendered +\def\pgf@arrows@dot@parsed#1[#2]{% + \pgf@arrows@append@to@tips{\pgf@arrow@handle@dot}% + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% +} -\def\pgf@arrow@call#1{% - \expandafter\ifx\csname\pgf@arrow@full@name{#1}\endcsname\relax% - \pgfsysprotocol@getcurrentprotocol\pgf@arrow@temp% - {% - \pgfinterruptpath% - \let\pgfusepath=\pgf@nousepath@here% - \pgf@relevantforpicturesizefalse% - \pgftransformreset% - \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% - \pgfsysprotocol@bufferedtrue% - \pgfsys@beginscope% - \csname pgf@arrow@code@#1\endcsname% - \pgfsys@endscope% - \pgfsysprotocol@getcurrentprotocol\pgf@@arrow@temp% - \global\let\pgf@@arrow@temp=\pgf@@arrow@temp% - \endpgfinterruptpath% - \expandafter\def\expandafter\pgf@temp\expandafter{\expandafter\pgfsys@invoke\expandafter{\pgf@@arrow@temp}}% - \expandafter\global\expandafter\let\csname\pgf@arrow@full@name{#1}\endcsname=\pgf@temp% - }% - \pgfsysprotocol@setcurrentprotocol\pgf@arrow@temp% +\def\pgf@arrows@meta@set#1#2#3{% + \pgf@arrows@append@to@tips{#3{#2}{#1}}% +} +\def\pgf@arrows@append@to@tips#1{% + \let\pgf@tempa\pgf@arrow@tip@sequence% + \def\pgf@tempb{#1}% + \ifpgf@arrows@translate% + \let\pgf@tempa\pgf@tempb% + \let\pgf@tempb\pgf@arrow@tip@sequence% + \fi% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrow@tip@sequence% + \expandafter\expandafter\expandafter{\expandafter\pgf@tempa\pgf@tempb}% +} + +\def\pgf@arrows@shorthand@parsed#1[#2]{% + \let\pgf@arrows@options\pgf@arrows@options@initial% + \pgfkeys{/pgf/arrow keys/.cd,#2}% + \ifx\pgf@arrows@options\pgfutil@empty% + \expandafter\pgf@arrows@append@to@tips\expandafter{% + \expandafter\pgf@arrow@handle@shorthand@empty\expandafter{\csname pgf@ar@means@#1\endcsname}}% + \else% + \expandafter\expandafter\expandafter\pgf@arrows@meta@set\expandafter\expandafter\expandafter{% + \expandafter\pgf@arrows@options\expandafter}\expandafter{\csname pgf@ar@means@#1\endcsname}{\pgf@arrow@handle@shorthand}% \fi% - \csname\pgf@arrow@full@name{#1}\endcsname% -} + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% +} + -\def\pgf@arrow@full@name#1{pgf@arrow@prot@#1@\the\pgflinewidth @\pgfinnerlinewidth @\pgfgetarrowoptions{#1}} +% General handler: -\def\pgf@arrow@code@{} % dummy +\def\pgf@arrow@handle@shorthand@empty#1{#1} -\def\pgf@nousepath@here#1{% - \PackageError{pgf}{The definition of an arrow may not use \string\pgfusepath}{} +\def\pgf@arrow@handle@shorthand#1#2{% + \def\pgf@temp@opt{#2}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrows@nested@options@temp% + \expandafter\expandafter\expandafter{\expandafter\pgf@temp@opt\pgf@arrows@nested@options}% + \expandafter\let\expandafter\pgf@arrows@nested@options\expandafter\pgf@arrows@nested@options@temp% + \expandafter#1% all these expandafters to avoid creating groups, but having the options nest + \expandafter\def\expandafter\pgf@arrows@nested@options\expandafter{\pgf@arrows@nested@options}% } +\let\pgf@arrows@nested@options\pgfutil@empty + + -% Get options for an arrow + +% Sets the start arrow tip % -% #1 = arrow tip name +% #1 = An arrow specification % % Description: +% +% This works like \pgfsetarrowsend, only the order of the tips in the +% arrow specification is reversed and the "reversed names" are used. % -% For every arrow tip certain options can be set, which may influence -% the appearance of the arrow tip. How the options are used is up the -% arrow tip code. This command will expand to the current value of -% the options for this tip. The default is 0. +% \pgfsetarrowsend{<<} +% \pgfsetarrowsend{>.>} + +\def\pgfsetarrowsstart#1{% + \let\pgf@arrow@tip@sequence\pgfutil@empty% + \pgf@arrows@translatetrue% + \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@start@#1\endcsname% + \ifx\pgf@arrows@direct\relax% + \edef\pgf@marshal{\noexpand\pgfarrows@initial@parser#1[]\noexpand\pgf@stop}% + \pgf@marshal% + \else% + \let\pgf@arrow@tip@sequence\pgf@arrows@direct% + \fi% + \let\pgf@start@tip@sequence\pgf@arrow@tip@sequence% +} -\def\pgfgetarrowoptions#1{% - \expandafter\ifx\csname pgf@arrow@opt@#1\endcsname\relax0\else\csname pgf@arrow@opt@#1\endcsname\fi% +\def\pgf@arrow@swapper{% + \expandafter\let\expandafter\pgf@temp\csname pgf@ar@start@\pgf@temp\endcsname% + \ifx\pgf@temp\relax% + \def\pgf@temp{undefined}% + \fi% } +\let\pgf@start@tip@sequence\pgfutil@empty +\let\pgf@end@tip@sequence\pgfutil@empty + + +\expandafter\def\csname pgf@arrows@direct@name@start@\endcsname{} +\expandafter\def\csname pgf@arrows@direct@name@end@\endcsname{} + + +% Predefined lengths and ifs + +\newdimen\pgfarrowsep + +\newif\ifpgfarrowswap +\newif\ifpgfarrowreversed +\newif\ifpgfarrowharpoon +\newif\ifpgfarrowopen + +\let\pgf@arrows@stroke@color\pgfutil@empty +\let\pgf@arrows@fill@color\pgfutil@empty + +\def\pgfarrows@length@scale{1} +\def\pgfarrows@width@scale{1} +\def\pgfarrows@slant{0} + +\let\pgfarrows@scale@list\pgfutil@empty +\def\pgfarrowsaddtolengthscalelist#1{\expandafter\def\expandafter\pgfarrows@scale@list\expandafter{\pgfarrows@scale@list#1\pgfarrows@length@scale#1}} +\def\pgfarrowsaddtowidthscalelist#1{\expandafter\def\expandafter\pgfarrows@scale@list\expandafter{\pgfarrows@scale@list#1\pgfarrows@width@scale#1}} + +\pgfkeys{ + /pgf/arrow keys/.cd, + scale/.code={% + \pgfmathparse{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@length@scale\expandafter{\pgfmathresult}}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@width@scale\expandafter{\pgfmathresult}}% + }, + scale length/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@length@scale\expandafter{\pgfmathresult}}}, + scale width/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@width@scale\expandafter{\pgfmathresult}}}, + slant/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@slant\expandafter{\pgfmathresult}}}, + sep/.code={ + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowsep\pgf@x}% + }, + sep/.default=0.88pt .3 1, + % + swap/.code=\pgfarrowsaddtooptions{\ifpgfarrowswap\pgfarrowswapfalse\else\pgfarrowswaptrue\fi}, + reversed/.code=\pgfarrowsaddtooptions{\ifpgfarrowreversed\pgfarrowreversedfalse\else\pgfarrowreversedtrue\fi}, + harpoon/.is choice, + harpoon/.default=true, + harpoon/true/.code=\pgfarrowsaddtooptions{\pgfarrowharpoontrue}, + harpoon/false/.code=\pgfarrowsaddtooptions{\pgfarrowharpoonfalse}, + left/.style={harpoon}, + right/.style={harpoon,swap}, + % + color/.code=\pgfarrowsaddtooptions{\def\pgf@arrows@stroke@color{#1}}, + fill/.code={% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@nonetext% + \pgfarrowsaddtooptions{\pgfarrowopentrue} + \else + \pgfarrowsaddtooptions{\pgfarrowopenfalse\def\pgf@arrows@fill@color{#1}} + \fi + }, + fill/.value required, + open/.style={fill=none}, + .unknown/.code={ + \expandafter\pgfutil@in@\expandafter!\expandafter{\pgfkeyscurrentname}% + \ifpgfutil@in@% + % this is a color! + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgf@arrows@stroke@color\expandafter{\pgfkeyscurrentname}}% + \else% + \pgfutil@doifcolorelse{\pgfkeyscurrentname} + {% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgf@arrows@stroke@color\expandafter{\pgfkeyscurrentname}}% + } + {% + \edef\pgf@temp{\pgfkeyscurrentname}% + \pgfkeys{/errors/unknown key/.expand once=\expandafter{\pgf@temp}{#1}}% + } + \fi + } +} +\def\pgf@nonetext{none} -% Set options for an arrow -% -% #1 = arrow tip name -% #2 = options -% -% Description: -% -% Sets the arrow tip options for an arrow. The options should be a -% normal string and will be used to detect whether an arrow should be -% recached. For instance, when you set the arrow tip options of -% "myarrow" to "1", the arrow will be rendered in a certain way. Then, -% when you set the options to "2", the arrow will be rerendered. +\def\pgfarrowsaddtooptions#1{\expandafter\def\expandafter\pgf@arrows@options\expandafter{\pgf@arrows@options#1}} +\def\pgfarrowsaddtolateoptions#1{\expandafter\def\expandafter\pgf@arrows@options\expandafter{\pgf@arrows@options\pgf@arrows@add@to@late@options{#1}}} +\def\pgf@arrows@add@to@late@options#1{\expandafter\def\expandafter\pgf@arrows@late@options\expandafter{\pgf@arrows@late@options#1}} -\def\pgfsetarrowoptions#1#2{% - \expandafter\def\csname pgf@arrow@opt@#1\endcsname{#2}% + + +\def\pgfarrowsthreeparameters#1{% + \pgfarrowsthreeparameters@#1 +0 +0 +0 \pgf@stop% +} +\def\pgfarrowsthreeparameters@#1 #2 #3 #4\pgf@stop{% + \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetmacro\pgf@temp@a{#2}% + \pgfmathsetmacro\pgf@temp@b{#3}% + \edef\pgfarrowstheparameters{{\the\pgf@x}{\pgf@temp@a}{\pgf@temp@b}}% } +\def\pgfarrowsfourparameters#1{% + \pgfarrowsfourparameters@#1 +0 +0 +0 \pgf@stop% +} +\def\pgfarrowsfourparameters@#1:#2 #3 #4 #5\pgf@stop{% + \pgfmathsetmacro\pgf@temp@z{#1}% + \pgfmathsetlength\pgf@x{#2}% + \pgfmathsetmacro\pgf@temp@a{#3}% + \pgfmathsetmacro\pgf@temp@b{#4}% + \edef\pgfarrowstheparameters{{\pgf@temp@z}{\the\pgf@x}{\pgf@temp@a}{\pgf@temp@b}}% +} +\def\pgfarrows@angle@setup#1#2#3#4{% + \pgfarrowslinewidthdependent{#2}{#3}{#4} + \pgf@xc\pgf@x + \pgf@yc#1 pt% + \pgf@yc.5\pgf@yc% + \pgfpointpolar{\pgf@yc}{\pgf@xc} + \pgfarrowlength\pgf@x% + \pgf@y2\pgf@y% + \expandafter\pgf@arrows@add@to@late@options\expandafter{\expandafter\pgfarrowwidth\the\pgf@y}% +} +\def\pgfarrows@angle@setup@prime#1{% + \pgf@yc#1 pt% + \pgfmathtan@{.5\pgf@yc}% + \pgfarrowwidth\pgfmathresult\pgfarrowlength% + \pgfarrowwidth2\pgfarrowwidth% +} -% Define an arrow type. -% -% #1 = name or mnemonic for arrow when used at the start (examples: ``to'' or ``<'') -% #2 = name or mnemonic for arrow when used at the end (examples: ``to'' or ``>'') -% #3 = code to setup the left and right extend of the arrow. To set -% the left extend, call \pgfarrowsleftextend, for the right \pgfarrowsrightextend. -% #4 = protocolable code -% -% Description: -% -% When you define an arrow using this command, you must give two -% names. The first is used for the arrow when it is ``at the start'', -% the other when it is at the end. For example, a simple arrow might -% have the names ``<'' and ``>'', though these particular names are -% not used by pgf and left for the user. -% -% The code should be ``protocolable'' code. This means that it uses -% only pretty simple commands. -% -% The arrow code will be protocolled once for each line width at which -% the arrow is used. Thus, the code can (and often should) depend on -% the line width. -% -% The arrow should ``point right'' in the coordinate system. The end -% of the line at which the arrow should be drawn will be at the origin -% of the coordinate system. The coordinate system will be scaled and -% rotated appropriately before the arrow is drawn. -% -% The right extend of the arrow should be set to how much the arrow -% ``protrudes over the right''. Prior to drawing the arrow, the line -% will be shortened by this amount so that the arrow tip will exactly -% touch the original right end of the unshortened line. -% -% The left extend specifies the leftmost point of the arrow. This is -% important only if you use the swapping command, when this end is -% used to compute the shortening. -% -% The definition of an arrow should normally take care of the fact -% that the line cap of the main line may be a butt cap, a round cap or -% a rect cap. In all cases, the arrow should ``cover'' the cap -% completely or not at all. -% -% Example: -% -% \pgfarrowsdeclare{stealth}{stealth} -% { -% \pgfarrowsleftextend{-6\pgflinewidth} -% \pgfarrowsrightextend{2\pgflinewidth} -% { -% \pgfpathmoveto{\pgfpoint{2\pgflinewidth}{0pt}} -% \pgfpathlineto{\pgfpoint{-6\pgflinewidth}{4\pgflinewidth}} -% \pgfpathlineto{\pgfpoint{-3\pgflinewidth}{0pt}} -% \pgfpathlineto{\pgfpoint{-6\pgflinewidth}{-4\pgflinewidth}} -% \pgfusepathqfill -% } +\def\pgfarrowslinewidthdependent#1#2#3{% + \pgf@x#1% + \ifdim\pgfinnerlinewidth>0pt% + \pgf@arrows@inner@line@width@dep{#2}{#3}% + \else% + \advance\pgf@x by#2\pgflinewidth% + \fi% +} +\def\pgf@arrows@inner@line@width@dep#1#2{% + % #1*((1-#2/2)*full line width - (#2/2) * inner line width) + % Compute "real" line width + \pgf@xa\pgflinewidth% + \pgf@xb-.5\pgflinewidth% + \pgf@xb#2\pgf@xb% + \advance\pgf@xa by\pgf@xb% + \pgf@xb\pgfinnerlinewidth% + \pgf@xb-.5\pgf@xb + \advance\pgf@xa by#2\pgf@xb% + \advance\pgf@x by#1\pgf@xa% +} -\def\pgfarrowsdeclare#1#2#3#4{% - \pgf@arrows@check@already{#1}{#2} - {% - \expandafter\def\csname pgf@arrow@code@#2\endcsname{#4}% - \expandafter\def\csname pgf@arrow@left@#2\endcsname{#3\advance\pgf@x by-\pgf@xa}% - \expandafter\def\csname pgf@arrow@right@#2\endcsname{#3\advance\pgf@x by\pgf@xb}% - \pgf@arrows@invname{#1}{#2}% - }% + +\def\pgfarrowslengthdependent#1#2#3#4{% + #4#1% + \advance#4by#2\pgfarrowlength% + \advance#4by#3\pgflinewidth% } -\def\pgfarrowsleftextend#1{\pgfmathsetlength\pgf@xa{#1}} -\def\pgfarrowsrightextend#1{\pgfmathsetlength\pgf@xb{#1}} -\def\pgf@arrows@repeat#1#2{% - \edef\pgf@arrows@marshal{\noexpand\let\expandafter\noexpand\csname#2\endcsname=\expandafter\noexpand\csname#1\endcsname}% - \pgf@arrows@marshal} +% Build the full name: +\def\pgf@arrow@fullname#1{pgf@@ar@#1@\the\pgflinewidth @\pgfinnerlinewidth @\ifpgfarrowreversed r\fi @\pgf@arrows@stroke@color @\pgf@arrows@fill@color @\csname pgf@ar@par@#1\endcsname} +\def\pgf@arrow@id@count{0}% -% Declare a new arrow type to be the same as another one. -% -% #1 = name of new start -% #2 = name or new end -% #3 = name or old start -% #4 = name or old end -% -% Example: -% -% \pgfarrowsdeclarealias{<}{>}{to}{to} +% Compute the arrow id of an arrow +% +% #1 = arrow name +% #2 = options +% +% Description: +% +% Returns the an id in \pgf@arrow@id that identifies the instantiation +% of the given arrow. If the arrow was not instantiated, this happens now. + +\def\pgfarrows@getid#1#2{% + % Execute options: + \let\pgf@arrows@late@options\pgfutil@empty% + % 1. Defaults: + \csname pgf@ar@defaults@#1\endcsname% + % 2. Scope: + \pgf@arrows@options@scope + % 3. Local: + #2\relax% + % 4. Nested: + \pgf@arrows@nested@options% + % 5. Last options: + \pgf@arrows@late@options% + % 6. Scaling: + \pgfarrows@scale@list% + % Now, test: + \expandafter\global\expandafter\let\expandafter\pgf@arrow@id\csname\pgf@arrow@fullname{#1}\endcsname\relax% + \ifx\pgf@arrow@id\relax% + \pgf@arrows@instantiate{#1} + \fi% +} -\def\pgfarrowsdeclarealias#1#2#3#4{% - \pgf@arrows@check@already{#1}{#2} +\def\pgf@arrows@instantiate#1{% + % Not defined. Rats! + % Allocate new id: + \pgfutil@tempcnta\pgf@arrow@id@count\relax% + \advance\pgfutil@tempcnta by1\relax% + \xdef\pgf@arrow@id@count{\the\pgfutil@tempcnta}% + \expandafter\global\expandafter\let\csname\pgf@arrow@fullname{#1}\endcsname\pgf@arrow@id@count% + \global\let\pgf@arrow@id\pgf@arrow@id@count% {% - \pgf@arrows@checked{#3}{#4}% - {% - \pgf@arrows@repeat{pgf@arrow@code@#4}{pgf@arrow@code@#2}% - \pgf@arrows@repeat{pgf@arrow@left@#4}{pgf@arrow@left@#2}% - \pgf@arrows@repeat{pgf@arrow@right@#4}{pgf@arrow@right@#2}% - \pgf@arrows@invname{#1}{#2}% + \csname pgf@ar@setup@#1\endcsname% + % Handle reversal + \ifpgfarrowreversed% + % Compute transformation: + \pgf@arrows@handle@reverse% + \fi% + % Save computed values + \expandafter\global\expandafter\let\csname pgf@ar@saves@\pgf@arrow@id\endcsname\pgf@arrows@saves% + \expandafter\global\expandafter\let\csname pgf@ar@hull@\pgf@arrow@id\endcsname\pgf@arrows@convexhull% + \expandafter\xdef\csname pgf@ar@ends@\pgf@arrow@id\endcsname{{\pgf@arrows@the@tipend}{\pgf@arrows@the@backend}{\pgf@arrows@the@lineend}}% + \expandafter\xdef\csname pgf@ar@visual@\pgf@arrow@id\endcsname{{\pgf@arrows@the@visualtipend}{\pgf@arrows@the@visualbackend}{}}% + % Save code (needed for bending) + \edef\pgf@arrow@code{% + \ifpgfarrowreversed\noexpand\pgftransformxscale{-1}\fi% + \expandafter\noexpand\csname pgf@ar@code@#1\endcsname% }% + \expandafter\global\expandafter\let\csname pgf@ar@inst@code@\pgf@arrow@id\endcsname\pgf@arrow@code% + % Should we cache? + \expandafter\ifx\csname pgf@ar@do@cache@#1\endcsname\pgf@truetext% + \pgfsysprotocol@getcurrentprotocol\pgf@arrow@temp% + {% + \pgfinterruptpath% + \let\pgfusepath=\pgf@nousepath@here% + \pgf@relevantforpicturesizefalse% + \pgftransformreset% + \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% + \pgfsysprotocol@bufferedtrue% + \pgfscope% + \pgf@arrow@code% + \endpgfscope% + \pgfsysprotocol@getcurrentprotocol\pgf@@arrow@temp% + \expandafter\gdef\expandafter\pgf@arrow@code\expandafter{\expandafter\pgfsysprotocol@literal\expandafter{\pgf@@arrow@temp}}% + \endpgfinterruptpath% + }% + \pgfsysprotocol@setcurrentprotocol\pgf@arrow@temp% + \fi% + \expandafter\global\expandafter\let\csname pgf@ar@cache@\pgf@arrow@id\endcsname\pgf@arrow@code% }% } +\def\pgf@truetext{true} + +% Ok, now run setup: +\def\pgf@arrows@copy@tipend{\pgf@arrows@the@tipend} +\def\pgf@arrows@copy@backend{\pgf@arrows@the@backend} +\def\pgf@arrows@copy@lineend{\pgf@arrows@the@lineend} +\def\pgf@arrows@zeropt{0pt}% + +\let\pgf@arrows@saves\pgfutil@empty% +\let\pgf@arrows@convexhull\pgfutil@empty% +\let\pgf@arrows@the@tipend\pgf@arrows@zeropt% +\let\pgf@arrows@the@backend\pgf@arrows@zeropt% +\let\pgf@arrows@the@lineend\pgf@arrows@zeropt% +\let\pgf@arrows@the@visualtipend\pgf@arrows@copy@tipend% +\let\pgf@arrows@the@visualbackend\pgf@arrows@copy@backend% + + +\def\pgf@arrows@handle@reverse{% + \pgf@x\pgf@arrows@the@visualtipend\pgf@x-\pgf@x% + \pgf@y\pgf@arrows@the@visualbackend\pgf@y-\pgf@y + \edef\pgf@arrows@the@visualtipend{\the\pgf@y}% + \edef\pgf@arrows@the@visualbackend{\the\pgf@x}% + \pgf@x\pgf@arrows@the@tipend\pgf@x-\pgf@x% + \pgf@y\pgf@arrows@the@backend\pgf@y-\pgf@y + \edef\pgf@arrows@the@tipend{\the\pgf@y}% + \edef\pgf@arrows@the@backend{\the\pgf@x}% + \pgf@x\pgf@arrows@the@lineend\pgf@x-\pgf@x\edef\pgf@arrows@the@lineend{\the\pgf@x}% + \let\pgf@temp\pgf@arrows@convexhull% + \let\pgf@arrows@convexhull\pgfutil@empty% + \let\pgf@arrow@hull@point\pgf@arrow@hull@point@reverse% + \pgf@temp% +} +\def\pgf@arrow@hull@point@reverse#1#2{% + \pgf@x#1% + \pgfarrowshullpoint{-\pgf@x}{#2}% +} + +\def\pgf@nousepath@here#1{\pgferror{The definition of an arrow may not use \string\pgfusepath}} + +\def\pgfarrowssavethe#1{% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrows@saves% + \expandafter\expandafter\expandafter{\expandafter\pgf@arrows@saves\expandafter#1\the#1\relax} +} +\def\pgfarrowssave#1{% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrows@saves% + \expandafter\expandafter\expandafter{\expandafter\pgf@arrows@saves\expandafter\def\expandafter#1\expandafter{#1}} +} +\def\pgfarrowshullpoint#1#2{% + \pgf@x#1\relax% + \pgf@y#2\relax% + \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@arrows@convexhull\expandafter\expandafter\expandafter{\pgf@arrows@temp}% +} +\def\pgfarrowsupperhullpoint#1#2{% + \pgf@x#1\relax% + \pgf@y#2\relax% + \ifdim\pgf@y>0pt + \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}\ifpgfarrowharpoon\else\noexpand\pgf@arrow@hull@point{\the\pgf@x}{-\the\pgf@y}\fi}% + \else + \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}}% + \fi + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@arrows@convexhull\expandafter\expandafter\expandafter{\pgf@arrows@temp}% +} -% Creates a new arrows by ``swapping'' an existing arrow. -% -% #1 = name of new start -% #2 = name of new end -% #3 = name of old start -% #4 = name of old end -% -% Example: -% -% \pgfarrowsdeclarealias{]}{[}{[}{]} +\def\pgfarrowssettipend#1{\pgf@x#1\edef\pgf@arrows@the@tipend{\the\pgf@x}} +\def\pgfarrowssetbackend#1{\pgf@x#1\edef\pgf@arrows@the@backend{\the\pgf@x}} +\def\pgfarrowssetlineend#1{\pgf@x#1\edef\pgf@arrows@the@lineend{\the\pgf@x}} +\def\pgfarrowssetvisualtipend#1{\pgf@x#1\edef\pgf@arrows@the@visualtipend{\the\pgf@x}} +\def\pgfarrowssetvisualbackend#1{\pgf@x#1\edef\pgf@arrows@the@visualbackend{\the\pgf@x}} -\def\pgfarrowsdeclarereversed#1#2#3#4{% - \pgf@arrows@check@already{#1}{#2}% - {% - \pgf@arrows@checked{#3}{#4}% - {% - \expandafter\def\csname pgf@arrow@code@#2\endcsname{% - \pgflowlevel{\pgftransformxscale{-1}}% - \csname pgf@arrow@code@#4\endcsname}% - \pgf@arrows@repeat{pgf@arrow@right@#4}{pgf@arrow@left@#2}% - \pgf@arrows@repeat{pgf@arrow@left@#4}{pgf@arrow@right@#2}% - \pgf@arrows@invname{#1}{#2}% - }% - }% + +% Internal computatin of the line end (shortening) for an arrow +% +% #1 = arrow tip list +% +% Description: +% +% \pgf@xa will contain the necessary path shortening for the given +% arrow tip list, \pgf@xb will contain the total length of the arrow +% tip list (sum of the differences between tip end and back end plus +% the seps). + +\def\pgf@arrow@compute@shortening#1{% + \let\pgf@arrow@handle\pgf@arrow@compute@shortening@ + \let\pgf@arrow@handle@dot\pgf@arrow@after@line@endtrue% + \pgf@arrow@after@line@endfalse% + \pgf@xa0pt% + \pgf@xb0pt% + #1% +} +\newif\ifpgf@arrow@after@line@end + +\def\pgf@arrow@compute@shortening@#1#2{% + {\pgfarrows@getid{#1}{#2}\ifnum\pgf@arrow@flex@mode>0\relax\global\pgf@precise@shorteningtrue\fi\expandafter}\expandafter\pgf@x\the\pgfarrowsep% + \expandafter\expandafter\expandafter\pgf@arrow@cont@short\csname pgf@ar@ends@\pgf@arrow@id\endcsname% +} +\def\pgf@dot@text{.} + +\def\pgf@arrow@cont@short#1#2#3{% tip end, back end, line end, sep + \advance\pgf@xb by#1% + \pgf@xc#2% + \advance\pgf@xb by-\pgf@xc% + \advance\pgf@xb by\pgf@x% + \ifpgf@arrow@after@line@end% + \advance\pgf@xa by#1% + \advance\pgf@xa by\pgf@x% + \pgf@xc#2% + \advance\pgf@xa by-\pgf@xc% + \else% + \pgf@xa#1% + \advance\pgf@xa by\pgf@x% + \pgf@xc#3% + \advance\pgf@xa by-\pgf@xc% + \fi% } -% Creates new arrows by combining two existing arrows. -% -% #1 = optional additional space -% #2 = name of new start -% #3 = name of new end -% #4 = name of second (innermost) start -% #5 = name of second end -% #6 = name of first (outermost) start -% #7 = name of first end -% -% In the star form, the line will end at the innermost arrows, -% otherwise the line will end at the outermost arrows. -% -% Example: -% -% \pgfarrowsdeclarecombine*{|<}{>|}{|}{|}{<}{>} -% \pgfarrowsdeclarecombine{<<}{>>}{<}{>}{<}{>} -\def\pgfarrowsdeclarecombine{\pgfutil@ifnextchar*{\pgfarrowsdeclarecombine@star}{\pgf@@arrowsdeclarecombine}} +% Draw an arrow +% +% #1 = arrow tip list +% #2 = total length of the arrow (the value of \pgf@xb computed by +% \pgf@arrow@compute@shortening) +% +% Description: +% +% Draws an arrow tip list. The coordinate system must have been +% transformed so that the to-be-drawn arrow points right and should +% "end" at the origin. -\def\pgf@@arrowsdeclarecombine{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine}{\pgf@arrowsdeclarecombine[0pt]}} -\def\pgf@arrowsdeclarecombine[#1]#2#3#4#5#6#7{% - \pgf@arrows@check@already{#2}{#3}% +\def\pgf@arrow@draw@arrow#1#2{% {% - \pgf@arrows@checked{#4}{#5}% - {% - \pgf@arrows@checked{#6}{#7}% - {% - \expandafter\edef\csname pgf@arrow@code@#3\endcsname{% - \noexpand\pgfscope% - {\expandafter\noexpand\csname pgf@arrow@code@#7\endcsname}% - \noexpand\endpgfscope% - {% - \noexpand\pgfmathsetlength\pgf@x{#1}% - \noexpand\pgf@process{\expandafter\noexpand\csname pgf@arrow@left@#7\endcsname}% - \noexpand\pgf@process{\expandafter\noexpand\csname pgf@arrow@right@#5\endcsname}% - \pgf@x=-\pgf@x% - \noexpand\pgflowlevel{\noexpand\pgftransformxshift{\pgf@x}}% - \expandafter\noexpand\csname pgf@arrow@code@#5\endcsname}% - }% - \pgf@arrows@repeat{pgf@arrow@right@#7}{pgf@arrow@right@#3}% - \expandafter\def\csname pgf@arrow@left@#3\endcsname{% - \pgf@process{% - \pgfmathsetlength\pgf@y{#1}% - \advance\pgf@x by\pgf@y% - \pgf@process{\csname pgf@arrow@left@#7\endcsname}% - \pgf@process{\csname pgf@arrow@right@#5\endcsname}% - \pgf@process{\csname pgf@arrow@left@#5\endcsname}% - }% - }% - \pgf@arrows@invname{#2}{#3}% - }% - }% + \pgf@xb=#2% + \pgftransformxshift{-\pgf@xb}% + \let\pgf@arrow@handle\pgf@arrow@drawer + \let\pgf@arrow@handle@dot\relax% + #1% }% } -\def\pgfarrowsdeclarecombine@star*{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine@star}{\pgf@arrowsdeclarecombine@star[0pt]}} -\def\pgf@arrowsdeclarecombine@star[#1]#2#3#4#5#6#7{% - \pgf@arrows@check@already{#2}{#3}% + +\def\pgf@arrow@drawer#1#2{% + % Prepare: {% - \pgf@arrows@checked{#4}{#5}% + \pgfarrows@getid{#1}{#2}% + % Do shift: + \expandafter\expandafter\expandafter\pgf@arrow@drawer@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname% + % Do slant: + \ifdim\pgfarrows@slant pt=0pt% + \else% + \pgftransformxslant{\pgfarrows@slant}% + \fi% + % do swap: + \ifpgfarrowswap% + \pgftransformyscale{-1}% + \fi% {% - \pgf@arrows@checked{#6}{#7}% - {% - \expandafter\edef\csname pgf@arrow@code@#3\endcsname{% - \noexpand\pgfscope% - {% - \noexpand\pgfmathsetlength\pgf@x{#1}% - \pgf@process{\expandafter\noexpand\csname pgf@arrow@left@#7\endcsname}% - \pgf@process{\expandafter\noexpand\csname pgf@arrow@right@#5\endcsname}% - \noexpand\pgflowlevel{\noexpand\pgftransformxshift{\pgf@x}}% - }% - {\expandafter\noexpand\csname pgf@arrow@code@#7\endcsname}% - \noexpand\endpgfscope% - \expandafter\noexpand\csname pgf@arrow@code@#5\endcsname% - }% - \pgf@arrows@repeat{pgf@arrow@left@#7}{pgf@arrow@left@#3}% - \expandafter\def\csname pgf@arrow@right@#3\endcsname{% - \pgf@process{% - \pgfmathsetlength\pgf@y{#1}% - \advance\pgf@x by\pgf@y% - \pgf@process{\csname pgf@arrow@left@#7\endcsname}% - \pgf@process{\csname pgf@arrow@right@#5\endcsname}% - \pgf@process{\csname pgf@arrow@right@#7\endcsname}% - }% - }% - \pgf@arrows@invname{#2}{#3}% - }% - }% - }% + \csname pgf@ar@saves@\pgf@arrow@id\endcsname% + \pgfscope% + \pgf@arrows@color@setup% + \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname% + \endpgfscope% + \pgf@arrows@rigid@hull% + }% + \expandafter}% + % Transform to next tip: + \expandafter\pgftransformxshift\expandafter{\the\pgf@xc}% +} + +\def\pgf@arrows@color@setup{% + \ifx\pgf@arrows@stroke@color\pgfutil@empty\else\pgfsetstrokecolor{\pgf@arrows@stroke@color}\fi% + \ifx\pgf@arrows@fill@color\pgfutil@empty% + \expandafter\expandafter\expandafter\ifx% + \expandafter\csname\expandafter\string\expandafter\color@pgfstrokecolor\expandafter\endcsname\csname\string\color@pgffillcolor\endcsname% + \else + \pgfsetfillcolor{pgfstrokecolor}% + \fi% + \else% + \pgfsetfillcolor{\pgf@arrows@fill@color}% + \fi% +} + +\def\pgf@arrow@drawer@shift#1#2#3{% tip end, back end, line end, sep + \pgf@xb#2\pgftransformxshift{-\pgf@xb}% + \pgf@xc#1% + \advance\pgf@xc by\pgfarrowsep% + \advance\pgf@xc by-\pgf@xb% +} + +\def\pgf@arrows@rigid@hull{% + \ifpgf@relevantforpicturesize% + % Do bb update: + \expandafter\let\expandafter\pgf@temp\csname pgf@ar@hull@\pgf@arrow@id\endcsname% + \ifx\pgf@temp\pgfutil@empty\else% + \let\pgf@arrow@hull@point\pgf@arrow@hull@point@first% + \pgf@temp% + \pgf@arrow@update@bb% + \fi% + \fi +} + + +% Convex hull stuff: + +\def\pgf@arrow@hull@point@first#1#2{% +% {\pgfsys@beginscope\pgfpathcircle{\pgfqpoint{#1}{#2}}{0.5pt}\pgfusepathqfill\pgfsys@endscope}% + \pgf@x#1\pgf@y#2% + \pgf@xa\pgf@pt@aa\pgf@x% + \advance\pgf@xa by\pgf@pt@ba\pgf@y% + \pgf@ya\pgf@pt@ab\pgf@x% + \advance\pgf@ya by\pgf@pt@bb\pgf@y% + \pgf@xb\pgf@xa\pgf@yb\pgf@ya% + \let\pgf@arrow@hull@point\pgf@arrow@hull@point@other% +} +\def\pgf@arrow@hull@point@other#1#2{% +% {\pgfsys@beginscope\pgfpathcircle{\pgfqpoint{#1}{#2}}{0.5pt}\pgfusepathqfill\pgfsys@endscope}% + \pgfutil@tempdima#1\pgfutil@tempdimb#2% + \pgf@x\pgf@pt@aa\pgfutil@tempdima% + \advance\pgf@x by\pgf@pt@ba\pgfutil@tempdimb% + \pgf@y\pgf@pt@ab\pgfutil@tempdima% + \advance\pgf@y by\pgf@pt@bb\pgfutil@tempdimb% + \ifdim\pgf@x<\pgf@xa\pgf@xa\pgf@x\else\ifdim\pgf@x>\pgf@xb\pgf@xb\pgf@x\fi\fi% + \ifdim\pgf@y<\pgf@ya\pgf@ya\pgf@y\else\ifdim\pgf@y>\pgf@yb\pgf@yb\pgf@y\fi\fi% } +\def\pgf@arrow@update@bb{% + \advance\pgf@xa by\pgf@pt@x% + \advance\pgf@ya by\pgf@pt@y% + \advance\pgf@xb by\pgf@pt@x% + \advance\pgf@yb by\pgf@pt@y% + \ifdim\pgf@picmaxx=-16000pt\relax% + \global\pgf@picminx\pgf@xa% + \global\pgf@picmaxx\pgf@xb% + \global\pgf@picminy\pgf@ya% + \global\pgf@picmaxy\pgf@yb% + \else% + \ifdim\pgf@xa<\pgf@picminx\global\pgf@picminx\pgf@xa\fi% + \ifdim\pgf@ya<\pgf@picminy\global\pgf@picminy\pgf@ya\fi% + \ifdim\pgf@xb>\pgf@picmaxx\global\pgf@picmaxx\pgf@xb\fi% + \ifdim\pgf@yb>\pgf@picmaxy\global\pgf@picmaxy\pgf@yb\fi% + \fi% +} -% Creates new arrows by doubling/tripling existing arrows. +% Sets arrows % -% #1 = optional additional space in multiples of line width -% #2 = name of new start -% #3 = name of new end -% #4 = name of old start -% #5 = name of old end +% #1 = An arrow specification of the form +% <start spec>-<end spec>. This will call \pgfsetstartarrow{start +% spec} and \pgfsetendarrow{end spec}. +% +% Alternatively, it may be of the form [options]. In this case, +% the arrow options are set for the local scope and all arrows in +% the current scope will have these options set. % % Example: % -% \pgfarrowsdeclaredouble{<<}{>>}{<}{>} +% \pgfsetarrows{-to} -\def\pgfarrowsdeclaredouble{\pgfutil@ifnextchar[{\pgf@arrowsdeclaredouble}{\pgf@arrowsdeclaredouble[0pt]}} -\def\pgf@arrowsdeclaredouble[#1]#2#3#4#5{\pgfarrowsdeclarecombine[#1]{#2}{#3}{#4}{#5}{#4}{#5}} -\def\pgfarrowsdeclaretriple{\pgfutil@ifnextchar[{\pgf@arrowsdeclaretriple}{\pgf@arrowsdeclaretriple[0pt]}} -\def\pgf@arrowsdeclaretriple[#1]#2#3#4#5{% - \pgfarrowsdeclarecombine[#1]{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}{#4}{#5}% - \pgfarrowsdeclarecombine[#1]{#2}{#3}{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}% +\def\pgfsetarrows#1{\pgf@arrows#1\pgf@stop} +\def\pgf@arrows{\pgfutil@ifnextchar[\pgf@arrows@test@opt\pgf@arrows@}%} +\def\pgf@arrows@#1-#2\pgf@stop{% + \pgfsetarrowsstart{#1}% + \pgfsetarrowsend{#2}% +} +\def\pgf@arrows@test@opt[{% + \pgfutil@ifnextchar-{\pgf@arrows@[}%} go back to normal reading for compat. reasons. + \pgf@arrows@test@opt@% +} +\def\pgf@arrows@test@opt@#1]{% + \pgfutil@ifnextchar\pgf@stop{% + \let\pgf@arrows@options\pgf@arrows@options@scope% + \pgfkeys{/pgf/arrow keys/.cd,#1}% + \let\pgf@arrows@options@scope\pgf@arrows@options% + % Ok, setup the options + \pgfutil@gobble% + }{% + \pgf@arrows@[#1]% Oops: go back to normal mode + }% } +\let\pgf@arrows@options@scope\pgfutil@empty + + + + -% A stealth-fighter-like pointed arrow -% -% Example: % -% \pgfsetarrows{-stealth} +% Predefined arrows: +% + + +% A dot is used to indicate the end of the line: + +\pgfdeclarearrow{ + name = ., + drawing code = +} + + +% An underscore adds a space as in >_> or >_ >. However, it will be +% faster to say ">[sep] >" or ">[sep=2pt] >". + +\pgfdeclarearrow{ + name = _, + defaults = {sep}, + drawing code = +} + + + +% Default shorthands: + +\pgfdeclarearrow{ name = To, means = } % forward declaration +\pgfdeclarearrow{ name = Bar, means = } % forward declaration +\pgfkeys{ + <-> /.tip = {To}, + >-< /.tip = {>[reversed]}, + | /.tip = {Bar} +} + + + +% Compatibility with old arrow system: + +\pgfkeys {} + +\def\pgf@arrows@direct@def#1#2{\expandafter\pgf@arrows@direct@def@\expandafter{\csname pgf@ar@means@#2\endcsname}{#1}} +\def\pgf@arrows@direct@def@#1#2{\expandafter\def\csname pgf@arrows@direct@name@#2\endcsname{\pgf@arrow@handle@shorthand@empty{#1}}} +\pgf@arrows@direct@def{start@[}{]} +\pgf@arrows@direct@def{start@]}{[} +\pgf@arrows@direct@def{start@spaced [}{spaced ]} +\pgf@arrows@direct@def{start@spaced ]}{spaced [} +\pgf@arrows@direct@def{end@[}{[} +\pgf@arrows@direct@def{end@]}{]} +\pgf@arrows@direct@def{end@spaced [}{spaced [} +\pgf@arrows@direct@def{end@spaced ]}{spaced ]} + +\def\pgfsetarrowoptions#1#2{\expandafter\def\csname pgf@arrow@compat@opt@#1\endcsname{#2}} +\def\pgfgetarrowoptions#1{\csname pgf@arrow@compat@opt@#1\endcsname} +\def\pgfarrowsdeclare#1#2#3#4{% + \pgfdeclarearrow{ name ={#1}-{#2}, setup code ={#3}, drawing code={#4}, parameters/.expand once={\csname pgf@arrow@compat@opt@#2\endcsname}} + \expandafter\def\csname pgf@arrow@compat@opt@#2\endcsname{0}} +\def\pgfarrowsleftextend#1{\pgfmathsetlength\pgf@xa{#1}\pgfarrowssetbackend{\pgf@xa}} +\def\pgfarrowsrightextend#1{\pgfmathsetlength\pgf@xb{#1}\pgfarrowssettipend{\pgf@xb}} +\def\pgfarrowsdeclarealias#1#2#3#4{\pgfdeclarearrow{ name ={#1}-{#2}, means ={#4} } } +\def\pgfarrowsdeclarereversed#1#2#3#4{\pgfdeclarearrow{ name ={#1}-{#2}, means={{#4}[reversed]}}} +\def\pgfarrowsdeclarecombine{\pgfutil@ifnextchar*{\pgfarrowsdeclarecombine@star}{\pgf@@arrowsdeclarecombine}} +\def\pgf@@arrowsdeclarecombine{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine}{\pgf@arrowsdeclarecombine[0pt]}} +\def\pgf@arrowsdeclarecombine[#1]#2#3#4#5#6#7{\def\pgf@@temp{#1}\ifx\pgf@@temp\pgf@linewidthtext\def\pgf@@temp{+0pt 1}\fi% + \pgfdeclarearrow{name ={#2}-{#3}, means={#5[sep/.expand once=\pgf@@temp]#6}}} +\def\pgf@linewidth@text{\pgflinewidth} +\def\pgfarrowsdeclarecombine@star*{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine@star}{\pgf@arrowsdeclarecombine@star[0pt]}} +\def\pgf@arrowsdeclarecombine@star[#1]#2#3#4#5#6#7{\def\pgf@@temp{#1}\ifx\pgf@@temp\pgf@linewidthtext\def\pgf@@temp{+0pt 1}\fi% + \pgfdeclarearrow{name ={#2}-{#3}, means={#5[sep/.expand once=\pgf@@temp].#6}}} +\def\pgfarrowsdeclaredouble{\pgfutil@ifnextchar[{\pgf@arrowsdeclaredouble}{\pgf@arrowsdeclaredouble[0pt]}} +\def\pgf@arrowsdeclaredouble[#1]#2#3#4#5{\pgfarrowsdeclarecombine[#1]{#2}{#3}{#4}{#5}{#4}{#5}} +\def\pgfarrowsdeclaretriple{\pgfutil@ifnextchar[{\pgf@arrowsdeclaretriple}{\pgf@arrowsdeclaretriple[0pt]}} +\def\pgf@arrowsdeclaretriple[#1]#2#3#4#5{ \pgfarrowsdeclarecombine[#1]{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}{#4}{#5}% + \pgfarrowsdeclarecombine[#1]{#2}{#3}{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}} +\def\pgf@linewidthtext{\pgflinewidth} \pgfarrowsdeclare{stealth}{stealth} { @@ -432,16 +1087,7 @@ \pgfpathlineto{\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}} \pgfusepathqfill } - \pgfarrowsdeclarereversed{stealth reversed}{stealth reversed}{stealth}{stealth} - - -% An arrow similar to the $\to$ arrow -% -% Example: -% -% \pgfsetarrow{-to} - \pgfarrowsdeclare{to}{to} { \pgfutil@tempdima=-0.84pt% @@ -469,7 +1115,7 @@ {\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}} \pgfusepathqstroke } - +\pgfkeys{To /.tip = to} \pgfarrowsdeclare{to reversed}{to reversed} { \pgfutil@tempdima=-0.21pt% @@ -497,15 +1143,6 @@ {\pgfqpoint{3.5\pgfutil@tempdima}{-4\pgfutil@tempdima}} \pgfusepathqstroke } - - - -% LaTeX's orginal arrow type -% -% Example: -% -% \pgfsetarrows{-latex} - \pgfarrowsdeclare{latex}{latex} { \pgfutil@tempdima=0.28pt% @@ -537,16 +1174,7 @@ \pgfusepathqfill } \pgfarrowsdeclarereversed{latex reversed}{latex reversed}{latex}{latex} - - - -% A bar shaped arrow -% -% Example: -% -% \pgfsetarrows{-|} - -\pgfarrowsdeclare{|}{|} +\pgfarrowsdeclare{@bar}{@bar} { \pgfarrowsleftextend{+-0.25\pgflinewidth} \pgfarrowsrightextend{+.75\pgflinewidth} @@ -560,17 +1188,7 @@ \pgfpathlineto{\pgfqpoint{0.25\pgflinewidth}{\pgfutil@tempdima}} \pgfusepathqstroke } - - -% A space arrow -% -% This arrow can be combined with other arrows to add "space" around -% them. -% -% Example: -% -% \pgfarrowsdeclarecombine{my<}{my>}{<}{>}{space}{space} - +\pgfkeys{Bar /.tip = @bar} \pgfarrowsdeclare{space}{space} { \pgfutil@tempdima=0.88pt% @@ -583,3 +1201,5 @@ \endinput + + |