diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex | 1946 |
1 files changed, 1946 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex new file mode 100644 index 00000000000..739a28395c2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex @@ -0,0 +1,1946 @@ +% Copyright 2008 by Mark Wibrow +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +% The following naming conventions are (more or less) observed: +% +% `decorated' : the path that is being decorated. +% `decoration' : any path created/left by the automaton +% `decorate' : generic use where distinction is probably unimportant +% (e.g. internal macros). + + + +% These should be moved. +% +\def\pgfgetpath#1{\pgfsyssoftpath@getcurrentpath{#1}} +\def\pgfsetpath#1{\pgfsyssoftpath@setcurrentpath{#1}} + + +% Required registers. +% +\newdimen\pgfdecoratedcompleteddistance +\newdimen\pgfdecoratedremainingdistance +\newdimen\pgfdecoratedinputsegmentcompleteddistance +\newdimen\pgfdecoratedinputsegmentremainingdistance +\newdimen\pgf@decorate@distancetomove + +\newcount\pgf@decorate@repeatstate + + +% Extra options used in all libraries + +\newdimen\pgfdecorationsegmentamplitude +\newdimen\pgfdecorationsegmentlength +\pgfdecorationsegmentamplitude2.5pt +\pgfdecorationsegmentlength10pt +\def\pgfdecorationsegmentangle{45} +\def\pgfdecorationsegmentaspect{0.5} +\def\pgfmetadecorationsegmentamplitude{2.5pt} +\def\pgfmetadecorationsegmentlength{1cm} + +\pgfkeys{% + /pgf/decoration/.code={\pgfkeys{/pgf/decoration/.cd,#1}}, + /pgf/decoration/.cd, + amplitude/.code={\pgfmathsetlength\pgfdecorationsegmentamplitude{#1}}, + meta-amplitude/.store in=\pgfmetadecorationsegmentamplitude, + segment length/.code={\pgfmathsetlength\pgfdecorationsegmentlength{#1}}, + meta-segment length/.store in=\pgfmetadecorationsegmentlength, + angle/.code={\pgfmathparse{#1}\let\pgfdecorationsegmentangle\pgfmathresult}, + aspect/.code={\pgfmathparse{#1}\let\pgfdecorationsegmentaspect\pgfmathresult}, + start radius/.initial=2.5pt, + end radius/.initial=2.5pt, + radius/.style={start radius=#1,end radius=#1}, + path has corners/.is if=pgfdecoratepathhascorners +} +\newif\ifpgfdecoratepathhascorners + + +% Declare a decoration +% +% #1 = name of the decoration +% #2 = initial state +% #3 = states +% +% This command declares a new decoration for later use. +% Inside the code of #3 the command \state may be used. This command +% will only be defined while #3 is executed. +% +% Example: +% +% \pgfdeclaredecoration{zigzag}{q} +% { +% \state{q}[width=10pt] +% { +% \pgfpathlineto{\pgfpoint{2.5pt}{2.5pt}} +% \pgfpathlineto{\pgfpoint{7.5pt}{-2.5pt}} +% \pgfpathlineto{\pgfpoint{10pt}{0pt}} +% } +% \state{final} +% { +% \pgfpathlineto{\pgfpointdecoratedpathlast} +% } +% } + +\long\def\pgfdeclaredecoration#1#2#3{% + \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone% + \pgfifmetadecoration{#1}{% + \PackageError{pgf}{You cannot declare a decoration of the same + name as a meta-decoration}{}% + \let\pgf@mod@dec@next=\pgfutil@gobble% + }{}% + \pgf@mod@dec@next + {% + \def\pgf@decorate@name{#1}% + \pgfutil@namedef{pgf@decorate@@#1@initial}{#2}% + \let\pgf@orig@state\state% + \let\state\pgf@decorate@state + #3% + \let\state\pgf@orig@state% + }% +} + +\def\pgf@decorate@state#1{\pgfutil@ifnextchar[{\pgf@decorate@@start#1}{\pgf@decorate@@start#1[]}}%} +\def\pgf@decorate@@start#1[#2]#3{% + \pgfutil@namedef{pgf@decorate@@\pgf@decorate@name @#1@options}{#2}% + \pgfutil@namedef{pgf@decorate@@\pgf@decorate@name @#1@code}{#3}% +} +\long\def\pgf@mod@dec@firstofone#1{#1} + + +% Test whether something is a decoration +% +% #1 = name +% #2 = if-code +% #3 = else-code +% +% Example: +% +% \pgfifdecoration{zigzag}{Exists}{Does not exist} + +\def\pgfifdecoration#1#2#3{\pgfutil@ifundefined{pgf@decorate@@#1@initial}{#3}{#2}} + + + +% Declare a meta decoration +% +% #1 = name of the meta decoration +% #2 = initial state +% #3 = states +% +% This command declares a new meta decoration for later use. +% Inside the code of #3 the command \state may be used. + +\long\def\pgfdeclaremetadecoration#1#2#3{% + \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone% + \pgfifdecoration{#1}{% + \PackageError{pgf}{You cannot declare a meta-decoration of the + same name as a decoration}{}% + \let\pgf@mod@dec@next=\pgfutil@gobble% + }{}% + \pgf@mod@dec@next{% + \def\pgf@metadecoration@name{#1}% + \pgfutil@namedef{pgf@metadecoration@@#1@initial}{#2}% + \let\pgf@orig@state\state% + \let\state\pgf@metadecoration@state + #3% + \let\state\pgf@orig@state% + }% +} + +\def\pgf@metadecoration@state#1{\pgfutil@ifnextchar[{\pgf@metadecoration@@state#1}{\pgf@metadecoration@@state#1[]}}%} +\def\pgf@metadecoration@@state#1[#2]#3{% + \pgfutil@namedef{pgf@metadecoration@@\pgf@metadecoration@name @#1@options}{#2}% + \pgfutil@namedef{pgf@metadecoration@@\pgf@metadecoration@name @#1@code}{#3}% +} + + +% Test whether something is a meta-decoration +% +% #1 = name +% #2 = if-code +% #3 = else-code +% +% Example: +% +% \pgfifmetadecoration{zigzag}{Exists}{Does not exist} + +\def\pgfifmetadecoration#1#2#3{\pgfutil@ifundefined{pgf@metadecoration@@#1@initial}{#3}{#2}} + + + + + +\let\pgfdecoratebeforecode\pgfutil@empty +\let\pgfdecorateaftercode\pgfutil@empty + +% \pgfdecoratepath +% +% Decorate a path. +% +% \pgfdecoratebeforecode and \pgfdecorateaftercode can be used to +% execute code before and after the decoration. +% +% #1 - the name of the decoration. +% #2 - a (non-empty) path specification. +% +% Example: +% +% \pgfdeclaredecoration{circles}{red circles}{ +% \state{red circles}[width=10pt, repeat state=2, next state=blue circles] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetstrokecolor{red!\pgfmathresult!brown} +% \pgfsetfillcolor{orange!\pgfmathresult!yellow} +% \pgfpathcircle{\pgfpointorigin}{2.5pt} +% \pgfusepath{stroke,fill} +% } +% \state{blue circles}[width=10pt, repeat state=1, next state=red circles] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetstrokecolor{blue!\pgfmathresult!gray} +% \pgfsetfillcolor{blue!\pgfmathresult!white} +% \pgfpathcircle{\pgfpointorigin}{2.5pt} +% \pgfusepath{stroke,fill} +% } +% \state{final}{} +% } +% +% \pgfpicture +% \pgfdecoratepath{circles} +% { +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{3cm}}{\pgfpoint{4cm}{0cm}}{\pgfpoint{4cm}{3cm}} +% } +% \endpgfpicture +% +\long\def\pgfdecoratepath#1#2{% + \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% + #2% + \endpgfdecoration} + + + + +% \pgfdecoratecurrentpath +% +% Decorate the current/existing path, but (unavoidably) destroys it. +% +% \pgfdecoratebeforecode and \pgfdecorateaftercode can be used to +% execute code before and after the decoration. +% +% #1 - the name of the decoration. +% +% Example: +% +% \pgfdeclaredecoration{stars}{move}{ +% \state{move}[width=7.5pt, next state=star]{} +% \state{star}[width=7.5pt, next state=move] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetfillcolor{yellow!\pgfmathresult!orange} +% \pgfsetstrokecolor{yellow!\pgfmathresult!red} +% \pgfmathparse{rnd*.75+.25} +% \pgftransformscale{\pgfmathresult} +% \pgfnode{star}{center}{}{}{\pgfusepath{stroke,fill}} +% } +% \state{final} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathlast} +% } +% } +% +% \pgfpicture +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} +% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} +% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} +% \pgfdecoratecurrentpath{stars} +% \endpgfpicture +% +\def\pgfdecoratecurrentpath#1{% + \pgfgetpath\pgf@decorate@currentpath% + \pgfsetpath\pgfutil@empty% + \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% + \pgfsetpath\pgf@decorate@currentpath% + \endpgfdecoration} + + + + +% Environment \pgfdecoration \endpgfdecoration +% +% Decorates a path with multiple decorations. +% +% Definitions: +% +% `existing path' +% - any unsed path exsiting prior to the environment. +% +% `decorated path' +% - the path that is being decorated. +% +% `decoration path' +% - any unused path left by the decoration automaton. +% +% The action of the environment is as follows: +% +% 1. Any existing path is saved. +% 2. Construction commands are executed forming the decorated path. +% 3. If the first command in the decorated path is not a `move to', +% the last known position from the exisiting path is inserted. +% 4. The saved existing path is reinstalled. +% 5. The decoration automaton is executed along the decorated path. +% +% Parameters: +% +% #1 - a comma separated list of decoration specifications. +% +% A decoration specification takes the format: +% +% {<name>}{<distance>}{<before code>}{<after code>} +% +% The decoration <name> is applied to a section of the decorated +% path from the last point on the decorated path the decoration +% automaton reached to <distance> from that point. +% +% When <distance>} is parsed, the dimension +% \pgfdecoratedreminingdistance holds the distance remaining on the +% entire decorated path, and the macro \pgfdecoratedpathlength holds +% the total length of the entire decorated path. +% After <distance> is parsed, both are set to to the value of +% <distance> for the automaton to decorate current section of the +% decorated path. +% +% <before code> is executed just before the decoration automaton +% starts and <after code> is executed just after the automaton stops. +% If <before code> or <after code> are empty, they can be omitted. +% The macros \pgfdecoratedpathfirst and \pgfdecoratedpathlast +% will be set up as the first and last points on the current section +% of the decorated path. +% +% When the environment exits, the following macros will be set up: +% +% \pgfdecorateexistingpath +% - the existing path. +% +% \pgfdecoratedpath +% - the decorated path. +% +% \pgfdecorationpath +% - any unused decoration path. +% +% \pgfpointdecoratedpathlast +% - the last point on the decorated path. +% +% Examples (require pgfdecorations library): +% +% \pgfpicture +% \pgfdecoration +% { +% {lineto}{\pgfdecoratedpathlength/3}, +% {zigzag}{\pgfdecoratedpathlength/3}, +% {lineto}{\pgfdecoratedpathlength/3} +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% \pgfusepath{stroke} +% \endpgfpicture +% +% +% \pgfpicture +% \pgfdecoration +% { +% {lineto}{\pgfdecoratedpathlength/5}{}{\pgfusepath{stroke}}, +% {zigzag}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% }, +% {lineto}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% }, +% {zigzag}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% }, +% {lineto}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% +% \endpgfpicture +% +% +% +% \pgfdeclaredecoration{polygons}{move}{ +% \state{move}[width=7.5pt, next state=polygon]{} +% \state{polygon}[width=7.5pt, next state=move] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetfillcolor{green!\pgfmathresult!yellow} +% \pgfsetstrokecolor{green!\pgfmathresult!brown} +% \pgfnode{regular polygon}{center}{}{}{\pgfusepath{stroke,fill}} +% } +% \state{final} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathlast} +% } +% } +% +% \pgfpicture +% \pgfdecoration +% { +% {polygons}{45pt}, +% {lineto}{30pt} +% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% { +% \pgfsetstrokecolor{yellow!50!orange} +% \pgfusepath{stroke} +% }, +% {polygons}{45pt}, +% {lineto}{30pt} +% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% { +% \pgfsetstrokecolor{green!50!blue} +% \pgfusepath{stroke} +% }, +% {polygons}{\pgfdecoratedremainingdistance} +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% \endpgfpicture +% +% +% \pgfpicture +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \pgfgetpath\temppath +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% +% \pgfset{decoration text={Here is some text all the way along this curve!}} +% \pgfdecoration{{text}{\pgfdecoratedremainingdistance}} +% \pgfsetpath\temppath +% \endpgfdecoration +% \endpgfpicture +% +\def\pgfdecoration#1{% + \begingroup% + \def\pgf@decorate@decorationlist{#1}% + \pgf@decoration@env% +} + +\def\endpgfdecoration{% + \pgf@decoration@endenv% + \ifx\pgfdecoratedpath\pgfutil@empty% + \else% + % + % Perform the decoration(s). + % + \pgf@decorate@for\pgf@temp:=\pgf@decorate@decorationlist\do{% + \ifx\pgf@temp\pgfutil@empty% + \else% + \expandafter\pgf@decorate@invoke\expandafter{\pgf@temp}% + \fi% + }% + \fi% + \pgfgetpath\pgfdecorationpath% + % + % Take stuff outside the group. + % + \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath% + \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath% + \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath% + \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast% + \endgroup% + % + % Are we in LaTeX? + % + \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}% + {\pgf@decorate@installmacrosatend}% +} + + +% Enviroment \pgfmetadecoration \endpgfmetadecoration +% +% Decorate a path with decoration automatons! +% +% Example: +% +% \pgfdeclaremetadecoration{fancy line}{line to}{ +% \state{line to}[width=1cm, next state=zigzag] +% { +% \decoration{lineto} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% \state{zigzag}[width=2cm, next state=line to] +% { +% \decoration{zigzag} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% } +% } +% \state{final} +% { +% \decoration{lineto} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% } +% +% \pgfpicture +% \pgfmetadecoration{fancy line} +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} +% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} +% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} +% \endpgfmetadecoration +% \endpgfpicture +% +\def\pgfmetadecoration#1{% + \begingroup% + \let\decoration\pgf@metadecoration@decoration% + \let\beforedecoration\pgf@metadecoration@beforedecoration% + \let\afterdecoration\pgf@metadecoration@afterdecoration% + \def\pgf@metadecoration@name{#1}% + \pgf@decoration@env% +} + +\def\endpgfmetadecoration{% + \pgf@decoration@endenv% + \ifx\pgfdecoratedpath\pgfutil@empty% + \else% + \let\pgfmetadecoratedpathlength\pgf@decorate@totalpathlength% + \def\pgfmetadecoratedinputsegmentremainingdistance{\pgfdecoratedremainingdistance}% + \def\pgfmetadecoratedinputsegmentcompleteddistance{\pgfdecoratedcompleteddistance}% + % + % Perform the meta decoration... + % + \expandafter\let\expandafter\pgf@metadecoration@current@state% + \csname pgf@metadecoration@@\pgf@metadecoration@name @initial\endcsname% + \pgf@metadecoration@run% + % + % ..until the final state. + % + \let\pgf@decorate@tempname\pgfutil@empty% + \let\pgf@decorate@tempbefore\pgfutil@empty% + \let\pgf@decorate@tempafter\pgfutil@empty% + \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% + \ifx\pgf@decorate@tempname\pgfutil@empty% + \def\pgf@decorate@tempname{moveto} + \fi% + \pgf@decorate@invoke{% + {\pgf@decorate@tempname}{\pgfdecoratedremainingdistance}% + {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% + }% + \fi% + \pgfgetpath\pgfdecorationpath% + % + % Take stuff outside the group. + % + \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath% + \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath% + \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath% + \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast% + \endgroup% + % + % Are we in LaTeX? + % + \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}% + {\pgf@decorate@installmacrosatend}% +} + + + + + + +% Internal macro for the decoration enironment. +% +\def\pgf@decoration@env{% + \pgfgetpath\pgfdecorateexistingpath% + \pgfsetpath\pgfutil@empty% + \let\pgfdecorationpath\pgfutil@empty% + \let\pgfdecoratedpath\pgfutil@empty% + \let\pgfpoint@decorated@pathlast\pgfpointorigin% + \edef\pgfpoint@decorate@existingpathlast{\pgf@x\the\pgf@path@lastx\pgf@y\the\pgf@path@lasty}% + % + % Begin a group so transformations don't mess things up. + % + \bgroup% +} + +\def\pgf@decoration@endenv{% + \egroup% + \pgftransformreset% + % + % Save the existing soft path and restore the existing path. + % + \pgfgetpath\pgfdecoratedpath% + \pgfsetpath\pgfdecorateexistingpath% + % + \ifx\pgfdecoratedpath\pgfutil@empty% + \PackageError{PGF}{I cannot decorate an empty path}{}% + \else% + % + % Remove special round tokens and get points. + % + \pgfprocessround{\pgfdecoratedpath}{\pgfdecoratedpath}% + % + % Parse the soft path into a series of decorated input segment objects. + % + \pgf@decorate@parsesoftpath{\pgfdecoratedpath}{\pgf@decorate@inputsegmentobjects}% + % + \let\pgf@decorated@remainingdistance\pgf@decorate@totalpathlength% + % + \let\pgfpoint@decorated@totalpathfirst\pgfpoint@decorated@firstparsed% + \let\pgfpoint@decorated@totalpathlast\pgfpoint@decorate@lastnonmovetoparsed% + % + \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@totalpathfirst + \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast% + % + % Set up the first input segment. + % + \let\pgf@decorate@currentinputsegmentobjects\pgf@decorate@inputsegmentobjects% + \let\pgf@decorate@transformtoinputsegment\pgfutil@empty% + \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@processnextinputsegmentobject% + \pgf@decorate@distancetomove0pt\relax% + % + % Setup further options + % + \pgfkeys{/pgf/every decoration/.try}% + \fi% +}% + + + + + +\def\pgf@decorate@installmacrosatend{% + \let\pgfdecorationpath\pgf@decorate@decorationpathtemp% + \let\pgfdecoratedpath\pgf@decorate@decoratedpathtemp% + \let\pgfdecorateexistingpath\pgf@decorate@existingpathtemp% + \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@pathlasttemp% +} + +\let\pgfdecorationpath\pgfutil@empty +\let\pgfdecoratedpath\pgfutil@empty +\let\pgfdecorateexisitingpath\pgfutil@empty + +\let\pgfpoint@decorated@pathlast\pgfpointorigin + + + +% A version of \pgfutil@for which doesn't expand each value in #3. +% +\def\pgf@decorate@for#1:=#2\do#3{% + \def\pgf@decorate@for@var{#1}% + \def\pgf@decorate@for@action{#3}% + \expandafter\pgf@decorate@@for#2,\pgf@stop,} + +\def\pgf@decorate@@for#1,{% + \ifx#1\pgf@stop% + \expandafter\let\pgf@decorate@for@var\pgfutil@empty% + \else% + \expandafter\def\pgf@decorate@for@var{#1}% + \pgf@decorate@for@action% + \expandafter\pgf@decorate@@for% + \fi% +} + + +% Invoke a decoration. +% +% #1 - {<name>}{<distance>}{<before code>}{<after code>} +% +\def\pgf@decorate@invoke#1{% + \pgf@decorate@@invoke#1\pgf@decorate@invoke\pgf@decorate@invoke\pgf@decorate@invoke\pgf@stop} + +\def\pgf@decorate@@invoke#1#2#3#4#5\pgf@stop{% + \pgfutil@ifundefined{pgf@decorate@@#1@initial}% + {% + \PackageError{PGF}{Unknown decoration `#1'}{}% + }% + {% + \def\pgf@decorate@name{#1}% + \ifx\pgf@decorate@invoke#3% + \let\pgf@decorate@beforecode\pgfutil@empty% + \else% + \def\pgf@decorate@beforecode{#3}% + \fi% + \ifx\pgf@decorate@invoke#4% + \let\pgf@decorate@aftercode\pgfutil@empty% + \else% + \def\pgf@decorate@aftercode{#4}% + \fi% + % + % Make remaining distance and the decorated path length `public'. + % + \pgfdecoratedremainingdistance\pgf@decorated@remainingdistance\relax% + \let\pgfdecoratedpathlength\pgf@decorate@totalpathlength% + % + \pgfmathsetlength\pgf@xa{#2}% + \ifdim\pgf@xa>\pgf@decorated@remainingdistance\relax% + \pgf@xa\pgf@decorated@remainingdistance\relax% + \fi% + \edef\pgf@decorate@currentpathlength{\the\pgf@xa}% + % + % Calculate the distance remaining to the end of the entire path. + % + \pgf@xa-\pgf@decorate@currentpathlength\relax% + \advance\pgf@xa\pgf@decorated@remainingdistance\relax% + \edef\pgf@decorated@remainingdistance{\the\pgf@xa}% + % + % Set up the macros and distances for the current section + % of the decorated path. + % + \let\pgfdecoratedpathlength\pgf@decorate@currentpathlength% + \pgfdecoratedremainingdistance\pgfdecoratedpathlength\relax% + \pgfdecoratedcompleteddistance0pt\relax% + % + % Execute user-defined code beore decoration. + % + \pgf@decorate@beforecode% + % + % Run the decoration... + % + \expandafter\let\expandafter\pgf@decorate@current@state% + \csname pgf@decorate@@\pgf@decorate@name @initial\endcsname% + \pgf@decorate@run% + % + % ...until the final state. + % + \ifdim\pgf@decorated@remainingdistance<1pt\relax% Should be =0pt, but need to control for inaccuracies. + \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast% + \else% + % + % Set up \pgfpoint@decorated@pathlast if the end of + % the total decorated path has not been reached. + % + {% + \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% + \pgf@decorate@transformtoinputsegment% + \pgfpointorigin% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% + \edef\pgfpoint@decorated@pathlast{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}% + \fi% + {% + \pgftransformreset% + \pgf@decorate@transformtoinputsegment% + \pgf@decorate@additionaltransform% + \csname pgf@decorate@@\pgf@decorate@name @final@code\endcsname% + }% + \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% + % + % Execute user-defined code after decoration. + % + \pgf@decorate@aftercode% + % + % Update the input segment objects. + % + \let\pgf@decorate@additionaltransform\pgfutil@empty% + \let\pgf@decorate@inputsegmentobjects\pgf@decorate@inputsegmentobjects@aftersplit% + \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@pathlast% + }% +} + + + +\let\pgf@decorate@transformtoinputsegment\pgfutil@empty% +\let\pgf@decorate@additionaltransform\pgfutil@empty% + + +% \pgfpointdecoratedpathfirst +% +\def\pgfpointdecoratedpathfirst{% + {% + \pgftransforminvert% + \pgfpoint@decorated@pathfirst% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% +}% + +% \pgfpointdecoratedpathlast +% +\def\pgfpointdecoratedpathlast{% + {% + \pgftransforminvert% + \pgfpoint@decorated@pathlast% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% +}% + +% \pgfpointdecoratedinputsegmentfirst +% +% The first point of the current sub-path. +% +\def\pgfpointdecoratedinputsegmentfirst{% + {% + \pgftransforminvert% + \pgf@decorate@inputsegment@first% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% +}% + +% \pgfpointdecoratedinputsegmentlast +% +% The final point of the current sub-path. +% +\def\pgfpointdecoratedinputsegmentlast{% + {% + \pgftransforminvert% + \pgf@decorate@inputsegment@last% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% +}% + + +\def\pgf@final@text{final} + +% Run a normal decoration. +% +\def\pgf@decorate@run{% + \let\pgf@decorate@next\pgf@decorate@do@state% + \ifx\pgf@decorate@current@state\pgf@final@text% + \let\pgf@decorate@next\relax% + \fi% + \pgf@decorate@next% +} + +\def\pgf@decorate@do@state{% + \let\pgf@decorate@next\relax% + \let\pgf@decorate@next@state\pgf@decorate@current@state% + % + % Get the options. + % + \let\pgf@decorate@persistent@pre=\relax% + \let\pgf@decorate@persistent@post=\relax% + \expandafter\expandafter\expandafter\pgf@decorate@setter + \expandafter\expandafter\expandafter{\csname pgf@decorate@@\pgf@decorate@name @\pgf@decorate@current@state @options\endcsname}% + \ifx\pgf@decorate@next\relax% + \let\pgf@decorate@next\pgf@decorate@do@code% + \fi% + \pgf@decorate@next% +} + +\def\pgf@decorate@setter{\pgfqkeys{/pgf/decoration automaton}} + +\pgf@decorate@repeatstate-1\relax + +\def\pgf@decorate@do@code{% + % + % Execute code. + % + \pgf@decorate@persistent@pre% + {% + \pgftransformreset% + \pgf@decorate@transformtoinputsegment% + \pgf@decorate@additionaltransform% + \csname pgf@decorate@@\pgf@decorate@name @\pgf@decorate@current@state @code\endcsname% + }% + \pgf@decorate@persistent@post% + \pgf@decorate@movealongpath{\pgf@decorate@width}% + % + % Next iteration. + % + \ifnum\pgf@decorate@repeatstate>0\relax% + \advance\pgf@decorate@repeatstate-1\relax% + \else% + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@current@state\pgf@decorate@next@state% + \fi% + \pgf@decorate@run% +} + +\pgfkeys{ + /pgf/decoration automaton/width/.code=\def\pgf@decorate@width{#1}\pgf@decorate@switch@if#1 to final\pgf@stop,% + /pgf/decoration automaton/switch if less than/.code=\pgf@decorate@switch@if#1\pgf@stop,% + /pgf/decoration automaton/switch if input segment less than/.code=\pgf@decorate@switch@ifinputsegment#1\pgf@stop,% + /pgf/decoration automaton/next state/.store in=\pgf@decorate@next@state,% + /pgf/decoration automaton/persistent precomputation/.store in=\pgf@decorate@persistent@pre,% + /pgf/decoration automaton/persistent postcomputation/.store in=\pgf@decorate@persistent@post,% + /pgf/decoration automaton/repeat state/.code={% + \ifnum\pgf@decorate@repeatstate=-1\relax% + \pgfmathsetcount\pgf@decorate@repeatstate{#1}% + \fi% + },% + /pgf/decoration automaton/if input segment is closepath/.code={% + \ifpgf@decorate@is@closepath@% + \pgfkeysalso{#1}% + \fi% + }, + /pgf/decoration automaton/auto end on length/.code=\pgf@decorate@auto@end{#1}, + /pgf/decoration automaton/auto corner on length/.code=\pgf@decorate@auto@corner{#1}, +} + +\def\pgf@decorate@auto@end#1{% + \ifx\pgf@decorate@next\relax% + \pgfmathsetlength\pgf@x{#1}% + \ifpgf@decorate@is@closepath@% + \ifdim\pgfdecoratedremainingdistance>\pgf@x% + \ifdim\pgfdecoratedinputsegmentremainingdistance>\pgf@x% + \else% + \pgfpathclose% + \pgf@decorate@movealongpath{\pgfdecoratedinputsegmentremainingdistance}% + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@next\pgf@decorate@run% + \fi% + \else% + \pgfpathclose% + \def\pgf@decorate@current@state{final}% + \def\pgf@decorate@width{\pgfdecoratedremainingdistance} + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@next\pgf@decorate@run% + \fi% + \else% + \ifdim\pgfdecoratedremainingdistance>\pgf@x% + \else% + {% + \pgftransformreset% + \pgf@decorate@transformtoinputsegment% + \pgf@decorate@additionaltransform% + \pgfpathlineto{\pgfpoint{\pgfdecoratedremainingdistance}{0pt}} + }% + \def\pgf@decorate@current@state{final}% + \def\pgf@decorate@width{\pgfdecoratedremainingdistance} + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@next\pgf@decorate@run% + \fi% + \fi% + \fi% +} + +\def\pgf@decorate@auto@corner#1{% + \ifpgfdecoratepathhascorners% + \ifx\pgf@decorate@next\relax% + \pgfmathsetlength\pgf@x{#1}% + \ifdim\pgfdecoratedinputsegmentremainingdistance>\pgf@x% + \else% + {% + \pgftransformreset% + \pgf@decorate@transformtoinputsegment% + \pgf@decorate@additionaltransform% + \pgfpathlineto{\pgfqpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}} + }% + \pgf@decorate@movealongpath{\pgfdecoratedinputsegmentremainingdistance}% + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@next\pgf@decorate@run% + \fi% + \fi% + \fi% +} + +\def\pgf@decorate@switch@if#1to #2\pgf@stop{% + \ifx\pgf@decorate@next\relax% + \ifdim\pgfdecoratedremainingdistance=0pt\relax% + \def\pgf@decorate@current@state{#2}% + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@next\pgf@decorate@run% + \else% + \pgfmathsetlength\pgf@x{#1}% + \ifdim\pgfdecoratedremainingdistance<\pgf@x% + \def\pgf@decorate@current@state{#2}% + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@next\pgf@decorate@run% + \fi% + \fi% + \fi% +} + +\def\pgf@decorate@switch@ifinputsegment#1to #2\pgf@stop{% + \ifx\pgf@decorate@next\relax% + \pgfmathsetlength\pgf@x{#1}% + \ifdim\pgfdecoratedinputsegmentremainingdistance<\pgf@x% + \def\pgf@decorate@current@state{#2}% + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@next\pgf@decorate@run% + \fi% + \fi% +} + + + + +% \pgfsetdecorationsegmenttransformation +% +% Set the additional transform for each decoration state. +% +% Example: +% +% \pgfsetdecorationsegmenttransformation{\pgftransformyshift{5pt}} +% +\def\pgfsetdecorationsegmenttransformation#1{\def\pgf@decorate@additionaltransform{#1}} +\let\pgf@decorate@additionaltransform\pgfutil@empty% + + + + +\def\pgf@metadecoration@decoration#1{% + \edef\pgf@decorate@tempname{#1}% +} +\def\pgf@metadecoration@beforedecoration#1{% + \def\pgf@decorate@tempbefore{#1}% +} +\def\pgf@metadecoration@afterdecoration#1{% + \def\pgf@decorate@tempafter{#1}% +} + + +\def\pgf@final@text{final} + +% Run a meta decoration. +% +\def\pgf@metadecoration@run{% + \let\pgf@metadecoration@next\pgf@metadecoration@do@state% + \ifx\pgf@metadecoration@current@state\pgf@final@text% + \let\pgf@metadecoration@next\relax% + \fi% + \pgf@metadecoration@next% +} + +\def\pgf@metadecoration@do@state{% + \let\pgf@metadecoration@next\relax% + \let\pgf@metadecoration@next@state\pgf@metadecoration@current@state% + % + % Set up some macros. + % + \let\pgfmetadecoratedremainingdistance\pgf@decorated@remainingdistance% + \pgf@x-\pgfmetadecoratedremainingdistance\relax% + \advance\pgf@x\pgf@decorate@totalpathlength\relax% + \edef\pgfmetadecoratedcompleteddistance{\the\pgf@x}% + % + % Get the options. + % + \expandafter\expandafter\expandafter\pgf@metadecoration@setter + \expandafter\expandafter\expandafter{\csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @options\endcsname}% + \ifx\pgf@metadecoration@next\relax% + \let\pgf@metadecoration@next\pgf@metadecoration@do@code% + \fi% + \pgf@metadecoration@next% +} + +\def\pgf@metadecoration@do@code{% + % + % Execute code. + % + \let\pgf@decorate@tempname\pgfutil@empty% + \let\pgf@decorate@tempbefore\pgfutil@empty% + \let\pgf@decorate@tempafter\pgfutil@empty% + \let\pgfpointmetadecoratedpathfirst\pgfpointdecoratedpathfirst% + \let\pgfpointmetadecoratedpathlast\pgfpointdecoratedpathlast% + \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% + \ifx\pgf@decorate@tempname\pgfutil@empty% + \def\pgf@decorate@tempname{moveto} + \fi% + \pgf@decorate@invoke{% + {\pgf@decorate@tempname}{\pgf@metadecoration@width}% + {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% + }% + % + % Next iteration. + % + \let\pgf@metadecoration@current@state\pgf@metadecoration@next@state% + \pgf@metadecoration@run% +} + +\def\pgf@metadecoration@setter{\pgfqkeys{/pgf/meta-decoration automaton}} + +\pgfkeys{ + /pgf/meta-decoration automaton/width/.code=\def\pgf@metadecoration@width{#1}\pgf@metadecoration@switch@if#1 to final\pgf@stop,% + /pgf/meta-decoration automaton/switch if less than/.code=\pgf@metadecoration@switch@if#1\pgf@stop,% + /pgf/meta-decoration automaton/switch if input segment less than/.code=\pgf@metadecoration@switch@ifinputsegment#1\pgf@stop,% + /pgf/meta-decoration automaton/next state/.store in=\pgf@metadecoration@next@state,% +} + +\def\pgf@metadecoration@switch@if#1to #2\pgf@stop{% + \ifx\pgf@metadecoration@next\relax% + \pgfmathsetlength\pgf@x{#1}% + \ifdim\pgf@decorated@remainingdistance<\pgf@x% + \def\pgf@metadecoration@current@state{#2}% + \let\pgf@metadecoration@next\pgf@metadecoration@run% + \fi% + \fi% +} + +\def\pgf@metadecoration@switch@ifinputsegment#1to #2\pgf@stop{% + \ifx\pgf@metadecoration@next\relax% + \pgfmathsetlength\pgf@x{#1}% + \ifdim\pgfdecoratedinputsegmentremainingdistance<\pgf@x% + \def\pgf@metadecoration@current@state{#2}% + \let\pgf@metadecoration@next\pgf@metadecoration@run% + \fi% + \fi% +} + + + +% Move along the path by a specified distance. +% +\def\pgf@decorate@movealongpath#1{% + \pgfmathsetlength\pgf@decorate@distancetomove{#1}% + \advance\pgfdecoratedcompleteddistance\pgf@decorate@distancetomove% + \advance\pgfdecoratedremainingdistance-\pgf@decorate@distancetomove% + \pgf@decorate@@movealongpath% +} +\def\pgf@decorate@@movealongpath{% + \advance\pgfdecoratedinputsegmentcompleteddistance\pgf@decorate@distancetomove% + \advance\pgfdecoratedinputsegmentremainingdistance-\pgf@decorate@distancetomove% + \ifdim\pgfdecoratedinputsegmentremainingdistance>0pt\relax% + \let\pgf@next\pgf@decorate@@@movealongpath% + \else% + \pgf@decorate@distancetomove-\pgfdecoratedinputsegmentremainingdistance% + \pgf@decorate@processnextinputsegmentobject% + \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% + \pgfdecoratedremainingdistance0pt\relax% + \let\pgf@next\relax% + \else% + \let\pgf@next\pgf@decorate@@movealongpath% + \fi% + \fi% + \pgf@next% +} + +\def\pgf@decorate@@@movealongpath{% + % + % Move along input segment for real. + % + \pgf@decorate@movealonginputsegment{\the\pgf@decorate@distancetomove}% + \pgf@decorate@distancetomove0pt\relax% + % + % Grrr. Hacking to control some inaccuracies. + % + \ifdim\pgf@decorate@inputsegmenttime pt>1pt\relax% + \let\pgf@decorate@inputsegmenttimetemp\pgf@decorate@inputsegmenttime% + \pgf@decorate@processnextinputsegmentobject% + \pgf@x\pgf@decorate@inputsegmenttimetemp pt\relax% + \advance\pgf@x-1pt\relax% + \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@x}}% + \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% + \pgfdecoratedremainingdistance0pt\relax% + \fi% + \fi% +} + +% Return the next input segment object in a macro +% +\def\pgf@decorate@getnextinputsegmentobject#1{% + \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% + \let\pgf@next\relax% + \else% + \def\pgf@decorate@temp{#1}% + \let\pgf@next\pgf@decorate@@getnextinputsegmentobject% + \fi% + \pgf@next% +} +\def\pgf@decorate@@getnextinputsegmentobject{% + \expandafter\pgf@decorate@@@getnextinputsegmentobject\pgf@decorate@currentinputsegmentobjects\pgf@stop} +\def\pgf@decorate@@@getnextinputsegmentobject#1#2\pgf@stop{% + \expandafter\def\pgf@decorate@temp{#1}% + \def\pgf@decorate@currentinputsegmentobjects{#2}} + +% Process the next input segment object. +% +\def\pgf@decorate@processnextinputsegmentobject{% + % + \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% + % + % If the current input segment object is a moveto, execute the + % object macro and get the next input segment object. + % + \expandafter\pgfutil@in@\expandafter\pgf@decorate@inputsegmentobject@moveto% + \expandafter{\pgf@decorate@currentinputsegmentobject}% + \ifpgfutil@in@% + \pgf@decorate@currentinputsegmentobject% + \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \relax% + \fi% + % + \pgf@decorate@is@closepath@false% + \pgf@decorate@currentinputsegmentobject% + % + % Teensy hack in case a path goes nowhere. + % + \ifdim\pgfdecoratedinputsegmentlength=0pt\relax% + \def\pgfdecoratedinputsegmentlength{0.05pt}% Arbitrary choice >0pt. + \fi% + \pgfdecoratedinputsegmentremainingdistance\pgfdecoratedinputsegmentlength\relax% + \pgfdecoratedinputsegmentcompleteddistance0pt\relax% + \def\pgf@decorate@inputsegmenttime{0}% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + \let\pgfdecoratedangle\pgfmathresult% +} + + +% +% Input segment objects +% + +\newif\ifpgf@decorate@is@closepath@% + + +% Input segment object moveto. +% +\def\pgf@decorate@inputsegmentobject@moveto#1{% + \pgfpathmoveto{#1}% + \def\pgf@decorate@inputsegment@first{#1}% + \def\pgf@decorate@inputsegment@supporta{#1}% + \def\pgf@decorate@inputsegment@supportb{#1}% + \def\pgf@decorate@inputsegment@last{#1}% + \edef\pgf@decorate@lastmoveto{#1}% + \def\pgfdecoratedinputsegmentlength{0pt}% + \let\pgf@decorate@splitinputsegmentobject\pgf@decorate@splitinputsegmentobject@move% +} + +% Input segment object lineto. +% +\def\pgf@decorate@inputsegmentobject@lineto#1#2#3{% + \def\pgfdecoratedinputsegmentlength{#1}% + \def\pgf@decorate@inputsegment@first{#2}% + % + % OK, lines don't need supports, but this means angle calculations + % do not have to be done individually for each object. + % + \def\pgf@decorate@inputsegment@supporta{#3}% + \def\pgf@decorate@inputsegment@supportb{#2}% + \def\pgf@decorate@inputsegment@last{#3}% + % + \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% + \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% + \let\pgf@decorate@splitinputsegmentobject\pgf@decorate@splitinputsegmentobject@line% +} + +% Input segment object curveto. +% +\def\pgf@decorate@inputsegmentobject@curveto#1#2#3#4#5{% + \def\pgfdecoratedinputsegmentlength{#1}% + \def\pgf@decorate@inputsegment@first{#2}% + \def\pgf@decorate@inputsegment@supporta{#3}% + \def\pgf@decorate@inputsegment@supportb{#4}% + \def\pgf@decorate@inputsegment@last{#5}% + % + \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@curve% + \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@curve% + \let\pgf@decorate@splitinputsegmentobject\pgf@decorate@splitinputsegmentobject@curve% +} + +% Input segment object closepath. +% +% Treated like a lineto, but flag that it is a closepath. +% +\def\pgf@decorate@inputsegmentobject@closepath#1#2#3{% + \pgf@decorate@is@closepath@true% + % + \def\pgfdecoratedinputsegmentlength{#1}% + \def\pgf@decorate@inputsegment@first{#2}% + \def\pgf@decorate@inputsegment@supporta{#3}% + \def\pgf@decorate@inputsegment@supportb{#2}% + \def\pgf@decorate@inputsegment@last{#3}% + % + \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% + \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% + \let\pgf@decorate@splitinputsegmentobject\pgf@decorate@splitinputsegmentobject@line% +} + +% Input segment object endofinputsegments. +% +\def\pgf@decorate@inputsegmentobject@endofinputsegments{} + + + + +% This macro controls how the automaton moves along a line sub-path +% +\def\pgf@decorate@movealonginputsegment@line#1{}% Nothing special needed. + +% This macro controls how the automaton moves along a curve sub-path. +% +\def\pgf@decorate@movealonginputsegment@curve#1{% + \ifdim#1=0pt\relax% + \else% + \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@xb\pgf@decorate@inputsegmenttime pt\relax% + % + % Reduce the initial time step, depending on the length + % of the path. To do: Optimise this step (should also depend on #1). + % + \ifdim\pgf@decorate@currentpathlength<128pt\relax% + \pgf@yb.03125pt\relax% + \else% + \ifdim\pgf@decorate@currentpathlength<512pt\relax% + \pgf@yb.015625pt\relax% + \else% + \ifdim\pgf@decorate@currentpathlength<2048pt\relax% + \pgf@yb.00390625pt\relax% + \else% + \pgf@yb.0009765625pt\relax% + \fi% + \fi% + \fi% + \c@pgf@counta1\relax% + \pgfutil@tempdima0pt\relax% + \pgfmathloop% + \advance\pgf@xb\c@pgf@counta\pgf@yb% + % + % We would like to use \pgfpointcurveattime. However, we must not + % overuse \pgf@process or \pgfmath stuff within this loop, + % otherwise we increase the chances of save stack overflow. + % + \edef\pgf@decorate@temp{% + \pgf@xa\the\pgf@xa% + \pgf@xb\the\pgf@xb% + \pgf@ya\the\pgf@ya% + \pgf@yb\the\pgf@yb% + }% + % + \pgfpoint@decorate@curveattime{\pgfmath@tonumber{\pgf@xb}}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + % + \pgf@decorate@temp% + % + \pgf@xc\pgf@xa% + \pgf@yc\pgf@ya% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \advance\pgf@x-\pgf@xc% + \advance\pgf@y-\pgf@yc% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \advance\pgfutil@tempdima\c@pgf@counta\pgfutil@tempdimb% + \ifnum\c@pgf@counta>0\relax% + \ifdim\pgfutil@tempdima>#1\relax% + \c@pgf@counta-\c@pgf@counta% + \pgf@yb.5\pgf@yb% + \fi% + \else% + \ifdim\pgfutil@tempdima<#1\relax% + \c@pgf@counta-\c@pgf@counta% + \pgf@yb.5\pgf@yb% + \fi% + \fi% + \ifdim\pgf@yb=0pt\relax% *Should* be OK. + \else% + \repeatpgfmathloop% + \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@xb}}% + % + % Now calculate the angle at the new time on the curve. + % + % We can use \pgfpointcurveattime safely here. + % + \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \edef\pgf@marshal{% + \noexpand\pgfmathanglebetweenpoints% + {\pgf@x\the\pgf@xb\pgf@y\pgf@yb}% + {\pgf@x\the\pgf@xa\pgf@y\pgf@ya}% + }% + \pgf@marshal% + \let\pgfdecoratedangle\pgfmathresult% + \fi% +} + +% \pgfpoint@decorate@curveattime +% +% A `quick' version of \pgfpointcurveattime +% +% No parsing and no use of \pgf@process. +% This prevents save stack build up when used inside a loop. +% +\def\pgfpoint@decorate@curveattime#1#2#3#4#5{% + \edef\pgf@time@s{#1}% + \pgf@x-\pgf@time@s pt\relax% + \advance\pgf@x1pt\relax% + \edef\pgf@time@t{\pgf@sys@tonumber{\pgf@x}}% + #5\relax% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + #4\relax% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + #3\relax% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + #2\relax% + % First iteration: + \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa% + \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya% + \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb% + \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb% + \pgf@xb=\pgf@time@t\pgf@xb\advance\pgf@xb by\pgf@time@s\pgf@xc% + \pgf@yb=\pgf@time@t\pgf@yb\advance\pgf@yb by\pgf@time@s\pgf@yc% + % Second iteration: + \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa% + \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya% + \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb% + \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb% + % Save x/y + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + % Third iteration: + \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa% + \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya% +} + + +% Applies the necessary transform for a line sub-path. +% +\def\pgf@decorate@transformtoinputsegment@line{% + \pgftransformshift{% + \pgfpointadd{\pgf@decorate@inputsegment@first}% + {\pgfpointpolar{\pgfdecoratedangle}{\pgfdecoratedinputsegmentcompleteddistance}}% + }% + \pgftransformrotate{\pgfdecoratedangle}% +} + +% Applies the necessary transform for a curve sub-path. +% +\def\pgf@decorate@transformtoinputsegment@curve{% + \pgfslopedattimetrue% + \pgfallowupsidedownattimetrue% + \pgftransformcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% +} + + + + + +% \pgf@decorate@parsesoftpath +% +% Parses an instance of a soft path into intermediate line and curve +% sub-path objects which the decoration automaton can use to traverse +% the decorated path. +% +% The soft path should be well formed and only contain `primative' +% soft path tokens, that is: moveto, lineto, curvetosupporta, +% curvetosupportb, curveto, rectcorner, rectsize, and closepath. +% (i.e., all specialround tokens should have removed using +% \pgfprocessround) +% +% The overall length of the path is also calculated and returned +% in the macro \pgfdecoratedpathlength. +% +% Parameters: +% +% #1 - a macro containing a well formed soft path. +% #2 - a macro to store the intermediate sub-path representations. +% +% Example: +% +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathlineto{\pgfpoint{0pt}{12pt}} +% \pgfpathlineto{\pgfpoint{12pt}{0pt}} +% \pgfgetpath\softpath +% +% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath}{} +% +% results in: +% +% \parsedsoftpath -> +% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 0pt}{\pgf@x 0pt\pgf@y 12pt}} +% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 12pt}{\pgf@x 12pt\pgf@y 12pt}} +% +% \pgfdecoratedpathlength -> +% 24pt +% + +\def\pgf@decorate@parsesoftpath#1#2{% + \def\pgf@decorate@inputsegmentobjectsmacro{#2}% + \let\pgf@decorate@inputsegmentobjects\pgfutil@empty% + \pgfutil@tempdima0pt\relax% + \let\pgfpoint@decorate@lastparsed\pgfpoint@decorate@existingpathlast% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@origin% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \let\pgfpoint@decorated@firstparsed\pgfutil@empty% + \expandafter\pgf@decorate@@parsesoftpath#1\pgf@stop% +} + +\def\pgf@decorate@@parsesoftpath#1{% + \ifx#1\pgf@stop% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% <- removes final moveto (may not be desirable). + \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% + \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% + \expandafter\let\pgf@decorate@inputsegmentobjectsmacro\pgf@decorate@inputsegmentobjects% + \edef\pgf@decorate@totalpathlength{\the\pgfutil@tempdima}% + \let\pgf@next\relax% + \else% + \ifx#1\pgfsyssoftpath@movetotoken% + \let\pgf@next\pgf@decorate@parsemoveto% + \else% + \ifx#1\pgfsyssoftpath@linetotoken% + \let\pgf@next\pgf@decorate@parselineto% + \else% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \let\pgf@next\pgf@decorate@parsecurveto% + \else% + \ifx#1\pgfsyssoftpath@closepathtoken% + \let\pgf@next\pgf@decorate@parseclosepath% + \else% + \ifx#1\pgfsyssoftpath@rectcornertoken% + \let\pgf@next\pgf@decorate@parserect% + \else% + \PackageError{PGF}{Unrecognised soft path token `#1'}{}% + \fi% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgf@next} + + +\def\pgf@decorate@addtoinputsegmentobjects#1{% + % + % If there is an input segment object waiting (i.e. a moveto), insert it here. + % + \ifx\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \else% + \let\pgf@decorate@temp\pgf@decorate@queueinputsegmentobject% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \fi% + \ifx\pgfpoint@decorated@firstparsed\pgfutil@empty% + #1% + \let\pgfpoint@decorated@firstparsed\pgf@decorate@inputsegment@first% + \fi% + \expandafter\def\expandafter\pgf@decorate@inputsegmentobjects\expandafter% + {\pgf@decorate@inputsegmentobjects{#1}}% +} + +% Convert \pgfsyssoftpath@movetotoken{<X>}{<Y>} into the following +% representation: +% +% \pgf@decorate@inputsegmentobject@moveto{\pgf@x X\pgf@y Y} +% +% The moveto input segment object is not added immediately, so that +% only the last of multiple movetos is inserted. +% +\def\pgf@decorate@parsemoveto#1#2{% + \def\pgf@decorate@queueinputsegmentobject{\pgf@decorate@inputsegmentobject@moveto{\pgf@x#1\pgf@y#2}}% + \def\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \pgf@decorate@@parsesoftpath% +} + +% Convert \pgfsyssoftpath@linetotoken{<X>}{<Y>} into the following +% representation: +% +% \pgf@decorate@inputsegmentobject@lineto{<length>}{\pgf@x <Last X> \pgf@y <Last Y}{\pgf@x <X> \pgf@y <Y>} +% +\def\pgf@decorate@parselineto#1#2{% + \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@lineto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + }% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \pgf@decorate@@parsesoftpath% +} + +% Convert \pgfsyssoftpath@curvetosupportatoken{<Xa>}{<Ya>}...etc +% into the following representation: +% +% \pgf@decorate@inputsegmentobject@curveto{<length>}{\pgf@x <Last X> \pgf@y <Last Y} +% {\pgf@x <Xa> \pgf@y <Ya>}{\pgf@x <Xb> \pgf@y <Yb>}{\pgf@x <X> \pgf@y <Y>} +% +\def\pgf@decorate@parsecurveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{% + \pgf@decorate@curvelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@curveto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}% + {\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% + }% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#5\pgf@y#6}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \pgf@decorate@@parsesoftpath% +} + + +\def\pgf@decorate@parseclosepath#1#2{% + \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@closepath{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + }% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \pgf@decorate@@parsesoftpath% +} + +% Convert \pgfsyssoftpath@rectcornertoken{<X>}{<Y>}\pgfsyssoftpath@rectsizetoken{<Xa>}{<Ya>} +% into either (clockwise) +% +% \pgf@decorate@inputsegmentobject@moveto{<X>}{<Y>} +% \pgf@decorate@inputsegmentobject@lineto{<length 1>}{\pgf@x <X> \pgf@y <Y>}{\pgf@x <X> \pgf@y <Ya+Y>} +% \pgf@decorate@inputsegmentobject@lineto{<length 2>}{\pgf@x <X> \pgf@y <Ya+Y>}{\pgf@x <Xa+X> \pgf@y <Ya+Y>} +% \pgf@decorate@inputsegmentobject@lineto{<length 1>}{\pgf@x <Xa+X> \pgf@y <Ya+X>}{\pgf@x <Xa+X> \pgf@y <Y>} +% \pgf@decorate@inputsegmentobject@lineto{<length 2>}{\pgf@x <Xa+X> \pgf@y <Y>}{\pgf@x <X> \pgf@y <Y>} +% \pgf@decorate@inputsegmentobject@moveto{<Xa>}{<Ya>} +% +% ...or (anti-clockwise) +% +% \pgf@decorate@inputsegmentobject@moveto{<X>}{<Y>} +% \pgf@decorate@inputsegmentobject@lineto{<length 2>}{\pgf@x <X> \pgf@y <Y>}{\pgf@x <Xa+X> \pgf@y <Y>} +% \pgf@decorate@inputsegmentobject@lineto{<length 1>}{\pgf@x <Xa+X> \pgf@y <Y>}{\pgf@x <Xa+X> \pgf@y <Ya+Y>} +% \pgf@decorate@inputsegmentobject@lineto{<length 2>}{\pgf@x <Xa+X> \pgf@y <Ya+Y>}{\pgf@x <X> \pgf@y <Ya+Y>} +% \pgf@decorate@inputsegmentobject@lineto{<length 1>}{\pgf@x <X> \pgf@y <Ya+Y>}{\pgf@x <X> \pgf@y <Y>} +% \pgf@decorate@inputsegmentobject@moveto{<Xa>}{<Ya>} +% +\newif\ifpgfdecoraterectangleclockwise +\def\pgf@decorate@parserect#1#2\pgfsyssoftpath@rectsizetoken#3#4{% + % + % Subvert \pgf@decorate@parsesoftpath so parsing macros will + % return here instead of continuing to parse the soft path. + % + \let\pgf@decorate@orig@@parsesoftpath\pgf@decorate@@parsesoftpath% + \let\pgf@decorate@@parsesoftpath\relax% + \pgf@decorate@parsemoveto{#1}{#2}% + \pgf@xa#1\relax% + \pgf@ya#2\relax% + \ifpgfdecoraterectangleclockwise% + \advance\pgf@ya#4% + \pgf@yb\pgf@ya% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa#3% + \pgf@xb\pgf@xa% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya-#4% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa-#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parseclosepath\pgf@temp% + \else% + \advance\pgf@xa#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \pgf@xb\pgf@xa% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya#4% + \pgf@yb\pgf@ya% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa-#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya-#4% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parseclosepath\pgf@temp% + \fi% + % + % Restore the parsing. + % + \let\pgf@decorate@@parsesoftpath\pgf@decorate@orig@@parsesoftpath% + \edef\pgf@marshal{\noexpand\pgf@decorate@parsemoveto{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@marshal% +} + + + + +% \pgf@decorate@linelength +% +% Define \pgfmathresult as the distance between #1 and #2 (without units). +% +\def\pgf@decorate@linelength#1#2{% + \pgf@process{\pgfpointdiff{#1}{#2}}% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% +} + +% \pgf@decorate@curvelength +% +% Define \pgfmathresult as the length (without units) of the cubic +% bezier described by #1,#2,#3 and #4. +% +% To approximate the length of the curve P (sort of) use: +% +% curveLength(P,q) +% Q = subdivideLeft(P); +% R = subdivideRight(P); +% return curveLength'(Q,q) + curveLength'(R,q); +% +% curveLength'(P,q) +% <P1,P2,P3,P4> <- P; +% P' = P4 - P1; +% x = P'.x(); +% y = P'.y(); +% if (x < q) && (y < q) +% return |P'|; +% else% +% Q = subdivideLeft(P); +% R = subdivideRight(P); +% return curveLength'(Q,q) + curveLength'(R,q); +% +% Where q is some small value (`tolerance'). +% +\newif\ifpgf@decorate@subdivide +\def\pgf@decorate@curvelength#1#2#3#4{% + % + % Always begin with a subdivision in case #1 = #4. + % + \begingroup% + \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% + \advance\pgfutil@tempdimb\pgfmathresult pt\relax% + \pgfmath@returnone\pgfutil@tempdimb% + \endgroup% +} + +\def\pgf@decorate@@curvelength#1#2#3#4{% + \begingroup% + \pgf@decorate@curvecordlength{#1}{#2}{#3}{#4}% + \ifpgf@decorate@subdivide% + \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% + \advance\pgfutil@tempdimb\pgfmathresult pt\relax% + \expandafter\pgfmath@returnone\expandafter\pgfutil@tempdimb% + \else% + \expandafter\pgfmath@returnone\expandafter\pgfmathresult\expandafter p\expandafter t\expandafter% + \fi% + \endgroup% +} + +\def\pgf@decorate@curvelength@tolerance{1pt} + +\def\pgf@decorate@curvecordlength#1#2#3#4{% + % + % Calculate the curve cord vector. + % + #4\relax% + \pgf@xa\pgf@x\pgf@ya\pgf@y% + #1\relax% + \advance\pgf@xa-\pgf@x% + \advance\pgf@ya-\pgf@y% + \ifdim\pgf@xa<0pt\relax\pgf@xa-\pgf@xa\fi% + \ifdim\pgf@ya<0pt\relax\pgf@ya-\pgf@ya\fi% + % + % Always subdivide, unless... + % + \pgf@decorate@subdividetrue% + % + % The cord vector is small. + % + \ifdim\pgf@xa<\pgf@decorate@curvelength@tolerance\relax% + \ifdim\pgf@ya<\pgf@decorate@curvelength@tolerance\relax% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% + \pgf@decorate@subdividefalse% + \fi% + \fi% +} + +\def\pgf@decorate@recursive@subdividecurve@left#1#2#3#4{% + {% + % + % The left curve (from t=0 to t=.5) + % + #1\relax% + \pgfutil@tempdima\pgf@x% + \pgfutil@tempdimb\pgf@y% + \pgf@xa.5\pgf@x\pgf@ya.5\pgf@y% + \pgf@xb.25\pgf@x\pgf@yb.25\pgf@y% + \pgf@xc.125\pgf@x\pgf@yc.125\pgf@y% + #2\relax% + \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% + \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% + \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% + #3\relax% + \advance\pgf@xb.25\pgf@x\advance\pgf@yb.25\pgf@y% + \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% + #4\relax% + \advance\pgf@xc.125\pgf@x\advance\pgf@yc.125\pgf@y% + \xdef\pgf@marshal{% + \noexpand\pgf@decorate@@curvelength% + {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} + {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + }% + }% + \pgf@marshal% +} + +\def\pgf@decorate@recursive@subdividecurve@right#1#2#3#4{% + {% + % + % The right curve (from t=0.5 to t=1) + % + #1\relax% + \pgfutil@tempdima.125\pgf@x\pgfutil@tempdimb.125\pgf@y% + #2\relax% + \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% + \pgf@xa.25\pgf@x\pgf@ya.25\pgf@y% + #3\relax% + \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% + \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% + \pgf@xb.5\pgf@x\pgf@yb.5\pgf@y% + #4\relax% + \advance\pgfutil@tempdima.125\pgf@x\advance\pgfutil@tempdimb.125\pgf@y% + \advance\pgf@xa.25\pgf@x\advance\pgf@ya.25\pgf@y% + \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \xdef\pgf@marshal{% + \noexpand\pgf@decorate@@curvelength% + {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} + {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + }% + }% + \pgf@marshal% +} + + +\let\startpgfdecoration=\pgfdecoration +\let\stoppgfdecoration=\endpgfdecoration + +\let\startpgfmetadecoration=\pgfmetadecoration +\let\stoppgfmetadecoration=\endpgfmetadecoration + + + +% +% Predefined decorations +% + + +% Simple decorations. + +\pgfdeclaredecoration{lineto}{initial}{ + \state{initial}[switch if input segment less than=\pgfdecoratedremainingdistance to input segment, + width=\pgfdecoratedremainingdistance] + { + } + \state{input segment}[width=\pgfdecoratedinputsegmentlength,next state=initial] + { + \pgfpathlineto{\pgfpointdecoratedinputsegmentlast} + } + + \state{final}{\pgfpathlineto{\pgfpointdecoratedpathlast}} +} + +\pgfdeclaredecoration{moveto}{initial}{ + \state{initial}[width=\pgfdecoratedremainingdistance]{} + \state{final}{\pgfpathmoveto{\pgfpointdecoratedpathlast}} +} + +% This decorations curves to the end along the line. + +\pgfdeclaredecoration{curveto}{initial}{ + \state{initial}[width=\pgfdecoratedinputsegmentlength/100] + { + \pgfpathlineto{\pgfpointorigin} + } + \state{final}{\pgfpathlineto{\pgfpointdecoratedpathlast}} +} + + + + +% Compatibility with old "snakes": + +\let\pgfsnakeremainingdistance=\pgfdecoratedremainingdistance +\let\pgfsnakecompleteddistance=\pgfdecoratedcompleteddistance +\def\pgfsnakeangle{\pgfdecoratedangle} +\let\pgfdeclaresnake=\pgfdeclaredecoration +\let\pgfsetsnakesegmenttransformation=\pgfsetdecorationsegmenttransformation +\def\pgfpathsnakesto#1#2{% + \edef\pgf@temp{#1}% + \expandafter\pgfdecoration\expandafter{\pgf@temp}% + \pgfpathlineto{#2}% + \endpgfdecoration% +} +\def\pgfpathsnaketo#1#2{\pgfpathsnakesto{{#1}{\pgfsnakeremainingdistance}}{#2}} +\def\pgfpathsnakealongvector#1#2#3{% + \pgf@process{#3}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgfmathparse{#2}% + \pgf@xa=\pgfmathresult\pgf@xa% + \pgf@ya=\pgfmathresult\pgf@ya% + \advance\pgf@xa by\pgf@path@lastx% + \advance\pgf@ya by\pgf@path@lasty% + \edef\pgf@snake@lib@temp{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \pgfpathsnaketo{#1}{\pgf@snake@lib@temp}% +} + +\let\pgfsnakesegmentamplitude=\pgfdecorationsegmentamplitude +\let\pgfsnakesegmentlength=\pgfdecorationsegmentlength +\def\pgfsnakesegmentangle{\pgfdecorationsegmentangle} +\def\pgfsnakesegmentobjectlength{\pgfkeysvalueof{/pgf/decoration/shape start width}} +\def\pgfsnakesegmentaspect{\pgfdecorationsegmentaspect} + +\pgfset{% + /pgf/segment amplitude/.style={/pgf/decoration={amplitude=#1,shape height=2*#1}}, + /pgf/segment length/.style={/pgf/decoration={segment length=#1}}, + /pgf/segment angle/.style={/pgf/decoration={angle=#1}}, + /pgf/segment aspect/.style={/pgf/decoration={aspect=#1}}, + /pgf/segment object length/.style={/pgf/decoration={shape width=#1,radius=#1}}} + + + +\endinput
\ No newline at end of file |