% Copyright 2006 by Till Tantau
%
% 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.

\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleshapes.code.tex,v 1.4 2008/02/13 15:10:06 tantau Exp $



\newbox\pgfnodeparttextbox


% Creates a node
%
% #1 = shape type
% #2 = anchor
% #3 = name for later reference
% #4 = path usage command
%
% Description:
%
% This command draws a shape that has previously been defined using
% \pgfdeclareshape. The shape is shifted such that the anchor is at
% the origin. In order to transform the whole shape, you should setup
% pgf's transformation matrix prior to calling this command.
%
% When this command is called, the shape-specific TeX boxes of the
% node must have been setup correctly.
%
% Example:
%
% \pgftransformshift{\pgfpoint{1cm}{1cm}}
% \pgfmultipartnode{rectangle}{center}{hellonode}{\pgfusepath{stroke}}

\def\pgfmultipartnode#1#2#3#4{%
  \pgfutil@ifundefined{pgf@sh@s@#1}%
  {\PackageError{pgf}{Unknown shape ``#1''}{}}%
  {%
    {%
      \let\pgf@sh@savedmacros=\pgfutil@empty% MW
      \let\pgf@sh@savedpoints=\pgfutil@empty%
      \csname pgf@sh@s@#1\endcsname%
      \pgf@sh@savedpoints%
      \pgf@sh@savedmacros% MW
      \pgftransformshift{%
        \pgf@sh@reanchor{#1}{#2}%
        \pgf@x=-\pgf@x%
        \pgf@y=-\pgf@y%
      }%
      \expandafter\pgfsavepgf@process\csname pgf@sh@sa@#3\endcsname{%
      	\pgf@sh@reanchor{#1}{#2}%
      }%
      % Save the saved points and the transformation matrix
      \edef\pgf@test{#3}%
      \ifx\pgf@test\pgfutil@empty%
      \else%
        \expandafter\xdef\csname pgf@sh@ns@#3\endcsname{#1}%
        \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@np@#3\endcsname}%
        \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedpoints}%
        \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@ma@#3\endcsname}% MW
        \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedmacros}% MW
        \pgfgettransform\pgf@temp
        \expandafter\xdef\csname pgf@sh@nt@#3\endcsname{\pgf@temp}%
        \expandafter\xdef\csname pgf@sh@pi@#3\endcsname{\pgfpictureid}%
      \fi%
      \pgfutil@ifundefined{pgf@sh@bbg@#1}{}
      {{\pgfscope\csname pgf@sh@bbg@#1\endcsname\endpgfscope}}%
      \pgfutil@ifundefined{pgf@sh@bg@#1}{}%
      {\csname pgf@sh@bg@#1\endcsname#4}%
      \pgfutil@ifundefined{pgf@sh@fbg@#1}{}
      {{\pgfscope\csname pgf@sh@fbg@#1\endcsname\endpgfscope}}%
      {%
        \expandafter\pgfutil@for\expandafter\pgf@shape@com\expandafter:\expandafter=\csname pgf@sh@boxes@#1\endcsname\do{%
          {%
            \pgftransformshift{\pgf@sh@reanchor{#1}{\pgf@shape@com}}%
            \expandafter\pgfqboxsynced\expandafter{\csname pgfnodepart\pgf@shape@com box\endcsname}%
          }%
        }%
      }%
      \pgfutil@ifundefined{pgf@sh@bfg@#1}{}%
      {{\pgfscope\csname pgf@sh@bfg@#1\endcsname\endpgfscope}}%
      \pgfutil@ifundefined{pgf@sh@fg@#1}{}%
      {\csname pgf@sh@fg@#1\endcsname#4}%
      \pgfutil@ifundefined{pgf@sh@ffg@#1}{}%
      {{\pgfscope\csname pgf@sh@ffg@#1\endcsname\endpgfscope}}%
      \pgf@nodecallback{#3}%
    }%
  }%
}


\def\pgf@shift@node#1#2{%
  % This internal command shifts the recorded coordinates for node #1
  % by the vector #2. It is used to
  % correct the position of the node if the recorded coordinate
  % happens to be wrong
  {%
    \pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
    \pgf@process{#2}%
    \advance\pgf@pt@x by\pgf@x%
    \advance\pgf@pt@y by\pgf@y%
    \pgfgettransform{\pgf@temp}%
    \expandafter\xdef\csname pgf@sh@nt@#1\endcsname{\pgf@temp}%
  }%
}

\let\pgf@nodecallback=\pgfutil@gobble



% Creates a node
%
% #1 = shape type
% #2 = anchor
% #3 = normal TeX text
% #4 = name for later reference
% #5 = path usage command
%
% Description:
%
% This command draws a shape that has previously been defined using
% \pgfdeclareshape. The shape is shifted such that the anchor is at
% the origin. In order to transform the whole shape, you should setup
% pgf's transformation matrix prior to calling this command.
%
% Example:
%
% \pgftransformshift{\pgfpoint{1cm}{1cm}}
% \pgfnode{rectangle}{center}{Hello}{hellonode}{\pgfusepath{stroke}}

\def\pgfnode#1#2#3#4#5{%
  {%
    \setbox\pgfnodeparttextbox=\hbox%
    {%
      \pgfinterruptpicture%
        {#3}%
      \endpgfinterruptpicture%
    }%
    \pgfmultipartnode{#1}{#2}{#4}{#5}%
  }
}  

% Alias a node
%
% #1 = new node name
% #2 = existing node name
%
% Description:
%
% This command allows you to subsequently access the node #2 using the
% name #1.
%
% Example:
%
% \pgfnode{rectangle}{center}{Hallo}{hellonode}{}
% \pgfnodealias{mynode}{hellonode}

\def\pgfnodealias#1#2{%
  \pgf@node@gnamelet{pgf@sh@ns@#1}{pgf@sh@ns@#2}%
  \pgf@node@gnamelet{pgf@sh@np@#1}{pgf@sh@np@#2}%
  \pgf@node@gnamelet{pgf@sh@nt@#1}{pgf@sh@nt@#2}%
  \pgf@node@gnamelet{pgf@sh@pi@#1}{pgf@sh@pi@#2}%
  \pgf@node@gnamelet{pgf@sh@ma@#1}{pgf@sh@ma@#2}%
}
\def\pgf@node@gnamelet#1#2{%
  \expandafter\let\expandafter\pgf@temp\csname #2\endcsname%
  \expandafter\global\expandafter\let\csname #1\endcsname=\pgf@temp%
}


\def\pgf@sh@resavedanchor#1#2{%
  \pgf@process{#2}%
  \edef\pgf@sh@marshal{%
    \noexpand\pgfutil@g@addto@macro\noexpand\pgf@sh@savedpoints{%
      \noexpand\def\noexpand#1{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
    }}%
  \pgf@sh@marshal%
}


\def\pgf@sh@resaveddimen#1#2{%
  {#2\global\pgf@x=\pgf@x}%
  \edef\pgf@sh@marshal{%
    \noexpand\pgfutil@g@addto@macro\noexpand\pgf@sh@savedpoints{%
      \noexpand\def\noexpand#1{\the\pgf@x}%
    }}%
  \pgf@sh@marshal%
}

% MW
\newtoks\toks@savedmacro
\def\pgf@sh@resavedmacro#1#2{%
	\let#1\pgfutil@empty%
	\def\addtosavedmacro##1{%
		\expandafter\def\expandafter\pgf@sh@addtomacro@temp\expandafter{#1\noexpand\def\noexpand##1{##1}}%
		\expandafter\toks@savedmacro\expandafter{\pgf@sh@addtomacro@temp}%
		\expandafter\def\expandafter#1\expandafter{\the\toks@savedmacro}%
	}%
  #2\relax%
  \edef\pgf@sh@marshal{%
    \noexpand\pgfutil@g@addto@macro\noexpand\pgf@sh@savedmacros{%
      \noexpand\def\noexpand#1{#1}%
    }}%
  \pgf@sh@marshal%
}

% Invoke an anchor
\def\pgf@sh@reanchor#1#2{%
  \pgfutil@ifundefined{pgf@anchor@#1@#2}%
  {%
    \pgfmathsetcounter{pgf@counta}{#2}%
    \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\c@pgf@counta}{1pt}}%
  }%
  {\csname pgf@anchor@#1@#2\endcsname}%
}



% Retrieves an anchor of a shape
%
% #1 = name
% #2 = anchor or a number (corresponding to a degree)
%
% Description:
%
% This command yields a point at the anchor of the given named shape.
%
% Example:
%
% \pgfshape{rectangle}{center}{Hello}{hellonode}{\pgfusepath[stroke]}
% \pgfpathmoveto{\pgfpointanchor{hellonode}{center}}

\def\pgfpointanchor#1#2{%
  % Ok, check whether #1 is known!
  \pgfutil@ifundefined{pgf@sh@ns@#1}
  {\PackageError{pgf}{No shape named #1 is known}{}%
    \pgfpointorigin}%
  {%
    \pgf@process{%
      % MW install special macros
      \csname pgf@sh@ma@#1\endcsname% MW
      % install special coordinates
      \csname pgf@sh@np@#1\endcsname
      \pgf@sh@reanchor{\csname pgf@sh@ns@#1\endcsname}{#2}%
      {%
        \pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
        \pgf@pos@transform{\pgf@x}{\pgf@y}%
        \global\pgf@x=\pgf@x%
        \global\pgf@y=\pgf@y%
      }%
      % Add inter picture transformation
      \pgf@shape@interpictureshift{#1}%
      % Undo current transformation
      \pgftransforminvert%
      \pgf@pos@transform{\pgf@x}{\pgf@y}%
    }%
  }%
}

\def\pgf@shape@interpictureshift#1{%
  \expandafter\ifx\csname pgf@sh@pi@#1\endcsname\pgfpictureid%
  \else%
    \pgfsys@getposition{\csname pgf@sh@pi@#1\endcsname}\pgf@shape@original@pos%
    \pgfsys@getposition{\pgfpictureid}\pgf@shape@current@pos%
    \pgf@xa=\pgf@x%
    \pgf@ya=\pgf@y%
    \pgf@process{\pgfpointorigin\pgf@shape@current@pos}%
    \advance\pgf@xa by-\pgf@x%
    \advance\pgf@ya by-\pgf@y%
    \pgf@process{\pgfpointorigin\pgf@shape@original@pos}%
    \advance\pgf@xa by\pgf@x%
    \advance\pgf@ya by\pgf@y%
    \pgf@x=\pgf@xa%
    \pgf@y=\pgf@ya%
  \fi%
}



% Retrieves a border point of a shape
%
% #1 = name
% #2 = another point
%
% Description:
%
% This command yields a point on the border of the shape that is on a
% straight line from the center to the point #2.
%
% Example:
%
% \pgfshape{rectangle}{center}{Hello}{hellonode}{\pgfusepath[stroke]}
% \pgfpathmoveto{\pgfpointshapeborder{hellonode}{\pgfpoint{2cm}{1cm}}
% \pgfpathlineto{\pgfpoint{2cm}{1cm}}
% \pgfusepath{stroke}

\def\pgfpointshapeborder#1#2{%
  % Ok, check whether #1 is known!
  \pgfutil@ifundefined{pgf@sh@ns@#1}
  {\PackageError{pgf}{No shape named #1 is known}{}%
    \pgfpointorigin}%
  {%
    \pgf@process{%
      % MW install special macros
      \csname pgf@sh@ma@#1\endcsname% MW
      % install special coordinates
      \csname pgf@sh@np@#1\endcsname%
      {%
        \pgf@process{\pgfpointtransformed{#2}}%
        \pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
        \pgftransforminvert%
        \pgf@pos@transform{\pgf@x}{\pgf@y}%
        \pgf@xa=\pgf@x%
        \pgf@ya=\pgf@y%
        \pgf@process{\csname pgf@anchor@\csname pgf@sh@ns@#1\endcsname @center\endcsname}%
        \pgf@process{\pgf@shape@interpictureshift{#1}}%%
        \advance\pgf@xa by-\pgf@x%
        \advance\pgf@ya by-\pgf@y%
        \csname pgf@anchor@\csname pgf@sh@ns@#1\endcsname @border\endcsname{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
        \pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
        \pgf@pos@transform{\pgf@x}{\pgf@y}%
        \global\pgf@x=\pgf@x%
        \global\pgf@y=\pgf@y%
      }%
      % Add inter picture transformation
      \pgf@shape@interpictureshift{#1}%
      % Undo current transformation
      \pgftransforminvert%
      \pgf@pos@transform{\pgf@x}{\pgf@y}%
    }%
  }%
}



% Declares a shape type
%
% #1 = shape type
% #2 = shape specification
%
% Description:
%
% This command declares a new shape type. The shape specification
% should contain the following commands:
%
% - \savedanchor
%   This command takes two arguments: a name and some code. The point
%   specified by the code (the \pgf@x and \pgf@y values resulting from
%   executing the code, to be precise), will be stored under the given
%   name. Whenever, later on, an anchor is invoked these stored points
%   will be available. The \saveddimen works like \savedanchor, only a
%   single dimension is stored (taken from \pgf@x).
%   When a savedanchor is calculated, the height/width/depth of the
%   boxes mentioned in \nodeparts can be used.
%
% - \anchor
%   Specifies an anchor. This command takes two arguments: an anchor
%   name and some code for computing the anchor. When the anchor
%   computation starts, all shape points and shape dimension will be
%   setup.
%
% - \anchorborder
%   This command should compute a point on the border of the
%   shape. When the code is called, \pgf@x and \pgf@y will have been
%   preinitialised with a direction.
%
% - \behindbackgroundpath
%   Some things to be draw behind everything.
%
% - \backgroundpath
%   A path that is drawn behind the main box. How this path is used
%   depends on how \pgfshape is called.
%
% - \beforebackgroundpath
%   Some things to be draw before the background path, but behind the
%   main box.
%
% - \behindforegroundpath
%   Some things to be draw on top of the main box.
%
% - \foregroundpath
%   A path that is drawn on top of all of the above. How this path is
%   used depends on how \pgfshape is called.
%
% - \beforeforegroundpath
%   Some things to be draw before everything.
%
% - \nodeparts
%   List of node parts that make up the shape. For each entry XYZ in
%   the list there must be a box named \pgfnodepartXYZbox (possibly
%   ``redirected'' to some different box using \let). Each such box
%   will be placed at the anchor XYZ.
%   By default, \nodeparts is just {text}. Thus, there will be one
%   node part box named \pgfnodeparttextbox and this node will be
%   placed at the anchor text. 
%   
%
% Example:
%
% See the definition of rectangle, below.

\long\def\pgfdeclareshape#1#2{%
  {
    \def\shape@name{#1}
    \let\savedanchor=\pgf@sh@savedanchor
    \let\saveddimen=\pgf@sh@saveddimen
    \let\savedmacro=\pgf@sh@savedmacro% MW
    \let\anchor=\pgf@sh@anchor
    \let\anchorborder=\pgf@sh@anchorborder
    \let\behindbackgroundpath=\pgf@sh@behindbgpath
    \let\backgroundpath=\pgf@sh@bgpath
    \let\beforebackgroundpath=\pgf@sh@beforebgpath
    \let\behindforegroundpath=\pgf@sh@behindfgpath
    \let\foregroundpath=\pgf@sh@fgpath
    \let\beforeforegroundpath=\pgf@sh@beforefgpath
    \let\nodeparts=\pgf@sh@boxes
    \let\inheritsavedanchors=\pgf@sh@inheritsavedanchors
    \let\inheritanchor=\pgf@sh@inheritanchor
    \let\inheritanchorborder=\pgf@sh@inheritanchorborder
    \let\inheritbehindbackgroundpath=\pgf@sh@inheritbehindbgpath
    \let\inheritbackgroundpath=\pgf@sh@inheritbgpath
    \let\inheritbeforebackgroundpath=\pgf@sh@inheritbeforebgpath
    \let\inheritbehindforegroundpath=\pgf@sh@inheritbehindfgpath
    \let\inheritforegroundpath=\pgf@sh@inheritfgpath
    \let\inheritbeforeforegroundpath=\pgf@sh@inheritbeforefgpath
    \let\inheritnodeparts=\pgf@sh@inheritboxes
    \anchorborder{\csname pgf@anchor@#1@center\endcsname}%
    \anchor{text}{\pgfpointorigin}%
    \nodeparts{text}%
    \expandafter\global\expandafter\let\csname pgf@sh@s@\shape@name\endcsname=\pgfutil@empty%
    #2
  }
}

\def\pgf@sh@savedanchor#1#2{%
  \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resavedanchor{#1}{#2}}}
\def\pgf@sh@saveddimen#1#2{%
  \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resaveddimen{#1}{#2}}}
 \def\pgf@sh@savedmacro#1#2{% MW
  \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resavedmacro{#1}{#2}}}% MW
\def\pgf@sh@anchor#1#2{\expandafter\gdef\csname pgf@anchor@\shape@name @#1\endcsname{#2}}
\def\pgf@sh@anchorborder#1{\expandafter\gdef\csname pgf@anchor@\shape@name @border\endcsname##1{\pgf@process{##1}#1}}
\long\def\pgf@sh@behindbgpath#1{\expandafter\gdef\csname pgf@sh@bbg@\shape@name\endcsname{#1}}
\long\def\pgf@sh@bgpath#1{\expandafter\gdef\csname pgf@sh@bg@\shape@name\endcsname{#1}}
\long\def\pgf@sh@beforebgpath#1{\expandafter\gdef\csname pgf@sh@fbg@\shape@name\endcsname{#1}}
\long\def\pgf@sh@behindfgpath#1{\expandafter\gdef\csname pgf@sh@bfg@\shape@name\endcsname{#1}}
\long\def\pgf@sh@fgpath#1{\expandafter\gdef\csname pgf@sh@fg@\shape@name\endcsname{#1}}
\long\def\pgf@sh@beforefgpath#1{\expandafter\gdef\csname pgf@sg@ffg@\shape@name\endcsname{#1}}
\def\pgf@sh@boxes#1{\expandafter\gdef\csname pgf@sh@boxes@\shape@name\endcsname{#1}}

\def\pgf@sh@inheritsavedanchors[from=#1]{%
  \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\csname pgf@sh@s@#1\endcsname}}
  
 \def\pgf@sh@inheritanchor[from=#1]#2{%
  \edef\pgf@marshal{\global\let\expandafter\noexpand\csname
    pgf@anchor@\shape@name @#2\endcsname=\expandafter\noexpand\csname
    pgf@anchor@#1@#2\endcsname}%
  \pgf@marshal%
}
\def\pgf@sh@inheritanchorborder[from=#1]{%
  \edef\pgf@marshal{\global\let\expandafter\noexpand\csname
    pgf@anchor@\shape@name @border\endcsname=\expandafter\noexpand\csname
    pgf@anchor@#1@border\endcsname}%
  \pgf@marshal%
}
\def\pgf@sh@inheritor#1#2{%
  \edef\pgf@marshal{\global\let\expandafter\noexpand\csname
    pgf@sh@#1@\shape@name\endcsname=\expandafter\noexpand\csname
    pgf@sh@#1@#2\endcsname}%
  \pgf@marshal%
}
\def\pgf@sh@inheritbehindbgpath[from=#1]{\pgf@sh@inheritor{bbg}{#1}}
\def\pgf@sh@inheritbgpath[from=#1]{\pgf@sh@inheritor{bg}{#1}}
\def\pgf@sh@inheritbeforebgpath[from=#1]{\pgf@sh@inheritor{fbg}{#1}}
\def\pgf@sh@inheritbehindfgpath[from=#1]{\pgf@sh@inheritor{bfg}{#1}}
\def\pgf@sh@inheritfgpath[from=#1]{\pgf@sh@inheritor{fg}{#1}}
\def\pgf@sh@inheritbeforefgpath[from=#1]{\pgf@sh@inheritor{ffg}{#1}}
\def\pgf@sh@inheritboxes[from=#1]{\pgf@sh@inheritor{boxes}{#1}}



% 
% Coordinate. This shape is special: It is only used to reference a
% point for later usage. Nothing is drawn, all anchors are identical
% to the center. 
%

\pgfdeclareshape{coordinate}
{
  \savedanchor\centerpoint{%
    % x
    \pgf@x=.5\wd\pgfnodeparttextbox%
    % y
    \pgf@y=.5\ht\pgfnodeparttextbox%
    \advance\pgf@y by -.5\dp\pgfnodeparttextbox%
  }
  
  \anchor{center}{\centerpoint}
  \anchor{north}{\centerpoint}
  \anchor{north west}{\centerpoint}
  \anchor{north east}{\centerpoint}
  \anchor{center}{\centerpoint}
  \anchor{west}{\centerpoint}
  \anchor{east}{\centerpoint}
  \anchor{mid}{\centerpoint}
  \anchor{mid west}{\centerpoint}
  \anchor{mid east}{\centerpoint}
  \anchor{base}{\centerpoint}
  \anchor{base west}{\centerpoint}
  \anchor{base east}{\centerpoint}
  \anchor{south}{\centerpoint}
  \anchor{south west}{\centerpoint}
  \anchor{south east}{\centerpoint}
  \anchorborder{\centerpoint}

  \nodeparts{}% no text
}


% Value keys for shapes:
%
% /pgf/inner xsep     : recommended inner x separation
% /pgf/inner ysep     : recommended inner y separation
% /pgf/outer xsep     : recommended outer x separation
% /pgf/outer ysep     : recommended outer y separation
% /pgf/minimum width  : recommended minimum width
% /pgf/minimum height : recommended minimum height

\pgfset{
  inner xsep/.initial     =.3333em,
  inner ysep/.initial     =.3333em,
  inner sep/.style        ={/pgf/inner xsep=#1,/pgf/inner ysep=#1},
  outer xsep/.initial     =.5\pgflinewidth,
  outer ysep/.initial     =.5\pgflinewidth,
  outer sep/.style        ={/pgf/outer xsep=#1,/pgf/outer ysep=#1},
  minimum width/.initial  =1pt,
  minimum height/.initial =1pt,
  minimum size/.style     ={/pgf/minimum width=#1,/pgf/minimum height=#1},
}

% Keys for rotating the shape border.
% (may not be supported by all shapes)
%
% /pgf/shape border uses incircle : Calculate the shape border using the incircle 
%                                   around the node contents (+inner sep).
%						
% /pgf/shape border rotate        : Angle of independent border rotation.

\newif\ifpgfshapeborderusesincircle
\pgfkeys{/pgf/shape border uses incircle/.is if=pgfshapeborderusesincircle}
\pgfkeys{/pgf/shape border rotate/.initial=0}

% 
% Rectangle
%

\pgfdeclareshape{rectangle}
{
  \savedanchor\northeast{%
    % Calculate x
    %
    % First, is width < minimum width?
    \pgf@x=\the\wd\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
    \advance\pgf@x by 2\pgf@xc%
    \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
    \ifdim\pgf@x<\pgf@xb%
      % yes, too small. Enlarge...
      \pgf@x=\pgf@xb%
    \fi%
    % Now, calculate right border: .5\wd\pgfnodeparttextbox + .5 \pgf@x + outer sep
    \pgf@x=.5\pgf@x%
    \advance\pgf@x by.5\wd\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
    \advance\pgf@x by\pgf@xa%
    % Calculate y
    %
    % First, is height+depth < minimum height?
    \pgf@y=\ht\pgfnodeparttextbox%
    \advance\pgf@y by\dp\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
    \advance\pgf@y by 2\pgf@yc%
    \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
    \ifdim\pgf@y<\pgf@yb%
      % yes, too small. Enlarge...
      \pgf@y=\pgf@yb%
    \fi%
    % Now, calculate upper border: .5\ht-.5\dp + .5 \pgf@y + outer sep
    \pgf@y=.5\pgf@y%
    \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
    \advance\pgf@y by.5\ht\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
    \advance\pgf@y by\pgf@ya%
  }
    
  \savedanchor\southwest{%
      % Calculate x
      %
      % First, is width < minimum width?
      \pgf@x=\wd\pgfnodeparttextbox%
      \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
      \advance\pgf@x by 2\pgf@xc%
      \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
      \ifdim\pgf@x<\pgf@xb%
        % yes, too small. Enlarge...
        \pgf@x=\pgf@xb%
      \fi%
      % Now, calculate left border: .5\wd\pgfnodeparttextbox - .5 \pgf@x - outer sep
      \pgf@x=-.5\pgf@x%
      \advance\pgf@x by.5\wd\pgfnodeparttextbox%
      \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
      \advance\pgf@x by-\pgf@xa%
      % Calculate y
      %
      % First, is height+depth < minimum height?
      \pgf@y=\ht\pgfnodeparttextbox%
      \advance\pgf@y by\dp\pgfnodeparttextbox%
      \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
      \advance\pgf@y by 2\pgf@yc%
      \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
      \ifdim\pgf@y<\pgf@yb%
        % yes, too small. Enlarge...
        \pgf@y=\pgf@yb%
      \fi%
       % Now, calculate upper border: .5\ht-.5\dp - .5 \pgf@y - outer sep
      \pgf@y=-.5\pgf@y%
      \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
      \advance\pgf@y by.5\ht\pgfnodeparttextbox%
      \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
      \advance\pgf@y by-\pgf@ya%
  }

  %
  % Anchors
  % 
  \anchor{center}{
    \pgf@process{\northeast}%
    \pgf@xa=.5\pgf@x%
    \pgf@ya=.5\pgf@y%
    \pgf@process{\southwest}%
    \pgf@x=.5\pgf@x%
    \pgf@y=.5\pgf@y%
    \advance\pgf@x by \pgf@xa%
    \advance\pgf@y by \pgf@ya%
  }
  \anchor{mid}{\pgf@anchor@rectangle@center\pgfmathsetlength\pgf@y{.5ex}}
  \anchor{base}{\pgf@anchor@rectangle@center\pgf@y=0pt}
  \anchor{north}{
    \pgf@process{\southwest}%
    \pgf@xa=.5\pgf@x%
    \pgf@process{\northeast}%
    \pgf@x=.5\pgf@x%
    \advance\pgf@x by \pgf@xa%
  }
  \anchor{south}{
    \pgf@process{\northeast}%
    \pgf@xa=.5\pgf@x%
    \pgf@process{\southwest}%
    \pgf@x=.5\pgf@x%
    \advance\pgf@x by \pgf@xa%
  }
  \anchor{west}{
    \pgf@process{\northeast}%
    \pgf@ya=.5\pgf@y%
    \pgf@process{\southwest}%
    \pgf@y=.5\pgf@y%
    \advance\pgf@y by \pgf@ya%
  }
  \anchor{mid west}{\southwest\pgfmathsetlength\pgf@y{.5ex}}
  \anchor{base west}{\southwest\pgf@y=0pt}
  \anchor{north west}{
    \southwest
    \pgf@xa=\pgf@x
    \northeast
    \pgf@x=\pgf@xa}
  \anchor{south west}{\southwest}
  \anchor{east}{%
    \pgf@process{\southwest}%
    \pgf@ya=.5\pgf@y%
    \pgf@process{\northeast}%
    \pgf@y=.5\pgf@y%
    \advance\pgf@y by \pgf@ya%
  }
  \anchor{mid east}{\northeast\pgfmathsetlength\pgf@y{.5ex}}
  \anchor{base east}{\northeast\pgf@y=0pt}
  \anchor{north east}{\northeast}
  \anchor{south east}{
    \northeast
    \pgf@xa=\pgf@x
    \southwest
    \pgf@x=\pgf@xa
  }
  \anchorborder{%
    \pgf@xb=\pgf@x% xb/yb is target
    \pgf@yb=\pgf@y%
    \southwest%
    \pgf@xa=\pgf@x% xa/ya is se
    \pgf@ya=\pgf@y%
    \northeast%
    \advance\pgf@x by-\pgf@xa%
    \advance\pgf@y by-\pgf@ya%
    \pgf@xc=.5\pgf@x% x/y is half width/height
    \pgf@yc=.5\pgf@y%
    \advance\pgf@xa by\pgf@xc% xa/ya becomes center
    \advance\pgf@ya by\pgf@yc%
    \edef\pgf@marshal{%
      \noexpand\pgfpointborderrectangle
      {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}
      {\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
    }%
    \pgf@process{\pgf@marshal}%
    \advance\pgf@x by\pgf@xa%
    \advance\pgf@y by\pgf@ya%
  }

  %
  % Background path
  %
  \backgroundpath{
    \pgfpathrectanglecorners
    {\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
    {\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
  }
}



% Special  current bounding box  rectangle:
\expandafter\def\csname pgf@sh@ns@current bounding box\endcsname{rectangle}
\expandafter\def\csname pgf@sh@np@current bounding box\endcsname{%
  \def\southwest{\pgfqpoint{\pgf@picminx}{\pgf@picminy}}%
  \def\northeast{\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}%
}
\expandafter\def\csname pgf@sh@nt@current bounding box\endcsname{{1}{0}{0}{1}{0pt}{0pt}}
\expandafter\def\csname pgf@sh@pi@current bounding box\endcsname{\pgfpictureid}


% Special  current path bounding box  rectangle:
\expandafter\def\csname pgf@sh@ns@current path bounding box\endcsname{rectangle}
\expandafter\def\csname pgf@sh@np@current path bounding box\endcsname{%
  \def\southwest{\pgfqpoint{\pgf@pathminx}{\pgf@pathminy}}%
  \def\northeast{\pgfqpoint{\pgf@pathmaxx}{\pgf@pathmaxy}}%
}
\expandafter\def\csname pgf@sh@nt@current path bounding box\endcsname{{1}{0}{0}{1}{0pt}{0pt}}
\expandafter\def\csname pgf@sh@pi@current path bounding box\endcsname{\pgfpictureid}


% Special  current page bounding box rectangle:
\expandafter\def\csname pgf@sh@ns@current page\endcsname{rectangle}
\expandafter\def\csname pgf@sh@np@current page\endcsname{%
  \def\southwest{\pgfqpoint{0pt}{0pt}}%
  \def\northeast{\pgfqpoint{\paperwidth}{\paperheight}}%
}
\expandafter\def\csname pgf@sh@nt@current page\endcsname{{1}{0}{0}{1}{0pt}{0pt}}
\expandafter\def\csname pgf@sh@pi@current page\endcsname{pgfpageorigin}


% Special scope bounding box rectangle:
\pgfkeys{/pgf/local bounding box/.code={%
    \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{rectangle}
    \expandafter\gdef\csname pgf@sh@np@#1\endcsname{%
      \def\southwest{\pgfqpoint{\csname pgf@lbb@minx@#1\endcsname}{\csname pgf@lbb@miny@#1\endcsname}}%
      \def\northeast{\pgfqpoint{\csname pgf@lbb@maxx@#1\endcsname}{\csname pgf@lbb@maxy@#1\endcsname}}%
    }
    \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}
    \expandafter\gdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}
    \expandafter\gdef\csname pgf@lbb@maxx@#1\endcsname{-16000pt}%
    \expandafter\gdef\csname pgf@lbb@minx@#1\endcsname{16000pt}%
    \expandafter\gdef\csname pgf@lbb@maxy@#1\endcsname{-16000pt}%
    \expandafter\gdef\csname pgf@lbb@miny@#1\endcsname{16000pt}%
    \pgf@size@hookedtrue%
    \expandafter\def\expandafter\pgf@path@size@hook\expandafter{\pgf@path@size@hook\pgf@lbb@do{#1}}
  }%
}
\def\pgf@lbb@do#1{%
  \ifdim\pgf@size@hook@x<\csname pgf@lbb@minx@#1\endcsname\expandafter\xdef\csname pgf@lbb@minx@#1\endcsname{\the\pgf@size@hook@x}\fi%
  \ifdim\pgf@size@hook@x>\csname pgf@lbb@maxx@#1\endcsname\expandafter\xdef\csname pgf@lbb@maxx@#1\endcsname{\the\pgf@size@hook@x}\fi%
  \ifdim\pgf@size@hook@y<\csname pgf@lbb@miny@#1\endcsname\expandafter\xdef\csname pgf@lbb@miny@#1\endcsname{\the\pgf@size@hook@y}\fi%
  \ifdim\pgf@size@hook@y>\csname pgf@lbb@maxy@#1\endcsname\expandafter\xdef\csname pgf@lbb@maxy@#1\endcsname{\the\pgf@size@hook@y}\fi%
}

%
% Circle
%

\pgfdeclareshape{circle}
%
% Draws a circle around the text
%
{
  \savedanchor\centerpoint{%
    \pgf@x=.5\wd\pgfnodeparttextbox%
    \pgf@y=.5\ht\pgfnodeparttextbox%
    \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
  }
    
  \saveddimen\radius{%
    % 
    % Caculate ``height radius''
    % 
    \pgf@ya=.5\ht\pgfnodeparttextbox%
    \advance\pgf@ya by.5\dp\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/inner ysep}}%
    \advance\pgf@ya by\pgf@yb%
    % 
    % Caculate ``width radius''
    % 
    \pgf@xa=.5\wd\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/inner xsep}}%
    \advance\pgf@xa by\pgf@xb%
    % 
    % Calculate length of radius vector:
    % 
    \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgf@xa}{\pgf@ya}}}%
    \ifdim\pgf@x>\pgf@y%
        \c@pgf@counta=\pgf@x%
        \ifnum\c@pgf@counta=0\relax%
        \else%
          \divide\c@pgf@counta by 255\relax%
          \pgf@xa=16\pgf@xa\relax%
          \divide\pgf@xa by\c@pgf@counta%
          \pgf@xa=16\pgf@xa\relax%
        \fi%
      \else%
        \c@pgf@counta=\pgf@y%
        \ifnum\c@pgf@counta=0\relax%
        \else%
          \divide\c@pgf@counta by 255\relax%
          \pgf@ya=16\pgf@ya\relax%
          \divide\pgf@ya by\c@pgf@counta%
          \pgf@xa=16\pgf@ya\relax%
        \fi%
    \fi%
    \pgf@x=\pgf@xa%
    % 
    % If necessary, adjust radius so that the size requirements are
    % met: 
    % 
    \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/minimum width}}%  
    \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/minimum height}}%  
    \ifdim\pgf@x<.5\pgf@xb%
        \pgf@x=.5\pgf@xb%
    \fi%
    \ifdim\pgf@x<.5\pgf@yb%
        \pgf@x=.5\pgf@yb%
    \fi%
    % 
    % Now, add larger of outer sepearations.
    % 
    \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%  
    \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%  
    \ifdim\pgf@xb<\pgf@yb%
      \advance\pgf@x by\pgf@yb%
    \else%
      \advance\pgf@x by\pgf@xb%
    \fi%
  }

  %
  % Anchors
  % 
  \anchor{center}{\centerpoint}
  \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}}
  \anchor{base}{\centerpoint\pgf@y=0pt}
  \anchor{north}{\centerpoint\advance\pgf@y by\radius}
  \anchor{south}{\centerpoint\advance\pgf@y by-\radius}
  \anchor{west}{\centerpoint\advance\pgf@x by-\radius}
  \anchor{east}{\centerpoint\advance\pgf@x by\radius}
  \anchor{mid west}{\centerpoint\advance\pgf@x by-\radius\pgfmathsetlength\pgf@y{.5ex}}
  \anchor{mid east}{\centerpoint\advance\pgf@x by\radius\pgfmathsetlength\pgf@y{.5ex}}
  \anchor{base west}{\centerpoint\advance\pgf@x by-\radius\pgf@y=0pt}
  \anchor{base east}{\centerpoint\advance\pgf@x by\radius\pgf@y=0pt}
  \anchor{north west}{
    \centerpoint
    \pgf@xa=\radius
    \advance\pgf@x by-0.707107\pgf@xa
    \advance\pgf@y by0.707107\pgf@xa
  }
  \anchor{south west}{
    \centerpoint
    \pgf@xa=\radius
    \advance\pgf@x by-0.707107\pgf@xa
    \advance\pgf@y by-0.707107\pgf@xa
  }
  \anchor{north east}{
    \centerpoint
    \pgf@xa=\radius
    \advance\pgf@x by0.707107\pgf@xa
    \advance\pgf@y by0.707107\pgf@xa
  }
  \anchor{south east}{
    \centerpoint
    \pgf@xa=\radius
    \advance\pgf@x by0.707107\pgf@xa
    \advance\pgf@y by-0.707107\pgf@xa
  }
  \anchorborder{
    \pgf@xa=\pgf@x%
    \pgf@ya=\pgf@y%
    \edef\pgf@marshal{%
      \noexpand\pgfpointborderellipse
      {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}
      {\noexpand\pgfqpoint{\radius}{\radius}}%
    }%
    \pgf@marshal%
    \pgf@xa=\pgf@x%
    \pgf@ya=\pgf@y%
    \centerpoint%
    \advance\pgf@x by\pgf@xa%
    \advance\pgf@y by\pgf@ya%
  }

  %
  % Background path
  %
  \backgroundpath{
    \pgfutil@tempdima=\radius%
    \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%  
    \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%  
    \ifdim\pgf@xb<\pgf@yb%
      \advance\pgfutil@tempdima by-\pgf@yb%
    \else%
      \advance\pgfutil@tempdima by-\pgf@xb%
    \fi%
    \pgfpathcircle{\centerpoint}{\pgfutil@tempdima}%
  }
}





\endinput
