% 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