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

\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex,v 1.6 2013/09/11 06:15:59 vibrovski Exp $

\pgfdeclareshape{forbidden sign}
{
  \inheritsavedanchors[from=circle] % this is nearly a circle
  \inheritanchorborder[from=circle]
  \inheritanchor[from=circle]{north}
  \inheritanchor[from=circle]{north west}
  \inheritanchor[from=circle]{north east}
  \inheritanchor[from=circle]{center}
  \inheritanchor[from=circle]{west}
  \inheritanchor[from=circle]{east}
  \inheritanchor[from=circle]{mid}
  \inheritanchor[from=circle]{mid west}
  \inheritanchor[from=circle]{mid east}
  \inheritanchor[from=circle]{base}
  \inheritanchor[from=circle]{base west}
  \inheritanchor[from=circle]{base east}
  \inheritanchor[from=circle]{south}
  \inheritanchor[from=circle]{south west}
  \inheritanchor[from=circle]{south east}
  \inheritbackgroundpath[from=circle]
  \foregroundpath{
    \centerpoint%
    \pgf@xc=\pgf@x%
    \pgf@yc=\pgf@y%
    \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%
    \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-0.707107\pgfutil@tempdima}{-0.707107\pgfutil@tempdima}}}
    \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.707107\pgfutil@tempdima}{0.707107\pgfutil@tempdima}}}
    \pgfsetarrowsstart{}
    \pgfsetarrowsend{}
  }
}


\pgfdeclareshape{correct forbidden sign}
{
  \inheritsavedanchors[from=circle] % this is nearly a circle
  \inheritanchorborder[from=circle]
  \inheritanchor[from=circle]{north}
  \inheritanchor[from=circle]{north west}
  \inheritanchor[from=circle]{north east}
  \inheritanchor[from=circle]{center}
  \inheritanchor[from=circle]{west}
  \inheritanchor[from=circle]{east}
  \inheritanchor[from=circle]{mid}
  \inheritanchor[from=circle]{mid west}
  \inheritanchor[from=circle]{mid east}
  \inheritanchor[from=circle]{base}
  \inheritanchor[from=circle]{base west}
  \inheritanchor[from=circle]{base east}
  \inheritanchor[from=circle]{south}
  \inheritanchor[from=circle]{south west}
  \inheritanchor[from=circle]{south east}
  \inheritbackgroundpath[from=circle]
  \foregroundpath{
    \centerpoint%
    \pgf@xc=\pgf@x%
    \pgf@yc=\pgf@y%
    \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%
    \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.707107\pgfutil@tempdima}{-0.707107\pgfutil@tempdima}}}
    \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-0.707107\pgfutil@tempdima}{0.707107\pgfutil@tempdima}}}
    \pgfsetarrowsstart{}
    \pgfsetarrowsend{}
  }
}





% Keys for starburst shape
%
% /pgf/starburst point height : The maximum height of the outer points.
% /pgf/starburst points       : The number of points.
% /pgf/random starburst       : The seed for the random number generator.
%
\pgfkeys{/pgf/random starburst/%
  .code={%
    \ifx\pgfkeysnovalue#1%
      \pgfmathgeneratepseudorandomnumber%
    \else%
      \pgfmathtruncatemacro\pgfmathresult{#1}%
    \fi%
    \pgfkeyslet{/pgf/random starburst}{\pgfmathresult}%
  }%
}
\pgfkeys{/pgf/random starburst=100}

\pgfkeys{/pgf/starburst point height/.value required}
\pgfkeys{/pgf/starburst point height/.code={%
    \pgfmathparse{#1}%
    \edef\pgfmathresult{\pgfmathresult pt}%
    \pgfkeyslet{/pgf/starburst point height}{\pgfmathresult}%
  }%
}%
\pgfkeys{/pgf/starburst point height=.5cm}

\pgfkeys{/pgf/starburst points/.value required}
\pgfkeys{/pgf/starburst points/.code={%
    \pgfmathtruncatemacro\pgfmathresult{#1}%
    \pgfkeyslet{/pgf/starburst points}{\pgfmathresult}%
  }%  
}%
\pgfkeys{/pgf/starburst points=17}

\pgfdeclareshape{starburst}{%
  \savedmacro\anglestep{%
    \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}%
    \let\anglestep\pgfmathresult%
  }
  \savedmacro\calculatestarburstpoints{%
    %
    % Get the angle step.
    %
    \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}%
    \let\anglestep\pgfmathresult%
    %
    % Get the total number of points.
    %
    \pgfmathsetcounter{pgf@counta}{\pgfkeysvalueof{/pgf/starburst points}}%
    \multiply\c@pgf@counta2\relax%
    \edef\totalpoints{\the\c@pgf@counta}%
    \addtosavedmacro{\totalpoints}%
    %
    % Calculate the centerpoint.
    %
    \pgfextract@process\centerpoint{%
      \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
      \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}%
      \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}%
    }%
    %
    % Get the larger of the outer sep.
    %
    \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/outer ysep}}%
    \ifdim\pgf@x<\pgf@y%
      \pgf@x\pgf@y%
    \fi%
    \edef\outersep{\the\pgf@x}%
    % 
    % Get the node dimensions.
    % 
    \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/inner xsep}}%
    \pgfmathaddtolength\pgf@x{+.5\wd\pgfnodeparttextbox}%    
    \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/inner ysep}}%
    \pgfmathaddtolength\pgf@y{+.5\ht\pgfnodeparttextbox}%
    \pgfmathaddtolength\pgf@y{+.5\dp\pgfnodeparttextbox}%
    %
    %  Calculate the inner radii.
    %
    \ifpgfshapeborderusesincircle%
      \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}%
      %
      % Use the incircle...
      %
      \ifdim\pgf@y>\pgf@x%
        \pgf@x\pgf@y%
      \fi%
      \pgf@x1.41421\pgf@x%
      \pgf@y\pgf@x%
    \else%
      %
      % Get the rotation (with rounding).
      %
      \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}%
      \pgfmathmod@{\rotate}{360}%
      \afterassignment\pgfmath@gobbletilpgfmath@%
      \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@%
      \advance\c@pgf@counta45\relax%
      \divide\c@pgf@counta90\relax%
      \multiply\c@pgf@counta90\relax%
      \ifnum\c@pgf@counta<0\relax%
        \advance\c@pgf@counta360\relax%
      \fi%
      %
      % Calculate the width and height of the node
      % contents, according to any border rotation.
      %
      \ifnum\c@pgf@counta=90\relax%
        \pgf@xc\pgf@x%
        \pgf@x\pgf@y%
        \pgf@y\pgf@xc%
      \else%
        \ifnum\c@pgf@counta=270\relax%
          \pgf@xc\pgf@x%
          \pgf@x\pgf@y%
          \pgf@y\pgf@xc%
        \fi%
      \fi%
      \edef\rotate{\the\c@pgf@counta}%
      %
      % ...or not.
      %    
      \pgf@x=1.41421\pgf@x%
      \pgf@y=1.41421\pgf@y%
    \fi%
    \addtosavedmacro{\rotate}%
    % 
    % Adjust innerradius for minimum width and height.
    %
    \pgf@xa\pgf@x% 
    \pgfmathsetlength\pgf@xb{+\pgfkeysvalueof{/pgf/starburst point height}}%
    \advance\pgf@xa\pgf@xb%
    \pgfmathsetlength\pgf@xc{+\pgfkeysvalueof{/pgf/minimum width}}%
    \ifdim\pgf@xa<.5\pgf@xc%
      \pgf@x.5\pgf@xc%
      \advance\pgf@x-\pgf@xb%
    \fi%
    \pgf@ya\pgf@y% 
    \pgfmathsetlength\pgf@yb{+\pgfkeysvalueof{/pgf/starburst point height}}%
    \advance\pgf@ya\pgf@yb%
    \pgfmathsetlength\pgf@yc{+\pgfkeysvalueof{/pgf/minimum height}}%
    \ifdim\pgf@ya<.5\pgf@yc%
      \pgf@y.5\pgf@yc%
      \advance\pgf@y-\pgf@yb%
    \fi%  
    \edef\xinnerradius{\the\pgf@x}%
    \edef\yinnerradius{\the\pgf@y}%
    \addtosavedmacro{\xinnerradius}%
    \addtosavedmacro{\yinnerradius}%
    %
    % Calculate a radius outside the starburst.
    %
    \ifdim\pgf@y>\pgf@x%
      \pgf@x\pgf@y%
    \fi%
    \pgfmathaddtolength\pgf@x{+\pgfkeysvalueof{/pgf/starburst point height}}%
    \edef\externalradius{\the\pgf@x}%
    \addtosavedmacro{\externalradius}%
    %
    % Set the seed for the random number generator.
    %
    \pgfmathsetseed{\pgfkeysvalueof{/pgf/random starburst}}%  
    %
    % Now create the points on the shape and also 
    % the miter length and angle for each point.
    %
    \def\angle{90}% Start at the top.
    %
    % At point a, the miter length and angle are calculated for point b = a - 1.
    %
    \c@pgf@counta1\relax%
    \c@pgf@countb0\relax%
    %
    % As 3 consecutive points are required to be defined for miter
    % calculations, it is necessary to go over the first two points
    % again.
    % 
    \c@pgf@countc\totalpoints\relax%
    \advance\c@pgf@countc2\relax%
    \edef\looppoints{\the\c@pgf@countc}%
    \let\secondpoint\pgfutil@empty%
    \let\thirdpoint\pgfutil@empty%
    \pgfmathloop%
      %
      % Cycle the point definitions.
      %
      \let\firstpoint\secondpoint%  
      \let\secondpoint\thirdpoint%  
      \ifnum\pgfmathcounter>\looppoints%
      \else%
        \ifnum\pgfmathcounter>\totalpoints%
          \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname%
        \else%
          \ifodd\pgfmathcounter%
            %
            % An outer point.
            %
            \ifnum\pgfkeysvalueof{/pgf/random starburst}=0\relax%
              \pgf@xa\pgfkeysvalueof{/pgf/starburst point height}\relax%
            \else%
              \pgf@x\pgfkeysvalueof{/pgf/starburst point height}\relax%
              \pgf@xa.75\pgf@x%
              \pgf@xb.25\pgf@x%
              \pgfmathrnd%
              \pgf@xa\pgfmathresult\pgf@xa%
              \advance\pgf@xa\pgf@xb%
            \fi%
            \pgf@x\xinnerradius\relax%
            \advance\pgf@x\pgf@xa%
            \pgf@y\yinnerradius\relax%
            \advance\pgf@y\pgf@xa%
            \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{%
              \pgfpointpolar{\angle}{\the\pgf@x and \the\pgf@y}%
              \pgf@xa\pgf@x%
              \pgf@ya\pgf@y%
              \centerpoint%
              \advance\pgf@x\pgf@xa%
              \advance\pgf@y\pgf@ya%
            }%
          \else%
            %
            % An inner point.
            %
            \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{%
              \pgfpointpolar{\angle}{\xinnerradius and \yinnerradius}%
              \pgf@xa\pgf@x%
              \pgf@ya\pgf@y%
              \centerpoint%
              \advance\pgf@x\pgf@xa%
              \advance\pgf@y\pgf@ya%
            }%            
          \fi%
          %
          % Add the points to the saved macro.
          %
          \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname%
          \expandafter\addtosavedmacro\expandafter{\csname point@\the\c@pgf@counta @\endcsname}%
        \fi%        
        %
        % It is only possible to do the miter calculations if three points are defined.
        %
        \ifx\firstpoint\pgfutil@empty%
        \else%
          %
          % Calculate the miter length...
          %
          \pgfmathanglebetweenlines{\secondpoint}{\thirdpoint}{\secondpoint}{\firstpoint}%
          \pgfmathdivide@{\pgfmathresult}{2}%
          \let\defaultmiterangle\pgfmathresult%
          \pgfmathcosec@{\pgfmathresult}%
          \pgf@x\outersep\relax%
          \pgf@x\pgfmathresult\pgf@x%
          \edef\miterlength{\the\pgf@x}%
          %
          % ...the miter angle...
          %
          \pgfmathanglebetweenlines{\firstpoint}{\secondpoint}{\firstpoint}{\thirdpoint}%
          \pgfmathadd@{\pgfmathresult}{\defaultmiterangle}%
          \pgfmathsubtract@{180}{\pgfmathresult}%
          \let\angletemp\pgfmathresult%
          \pgfmathanglebetweenpoints{\firstpoint}{\thirdpoint}%
          \pgfmathsubtract@{180}{\pgfmathresult}%
          \pgfmathsubtract@{\angletemp}{\pgfmathresult}%
          \edef\miterangle{\pgfmathresult}%
          %
          % ...and thus the border point.
          %
          \pgfextract@process\borderpoint{%
            \secondpoint%
            \pgf@xa\pgf@x
            \pgf@ya\pgf@y%
            \pgfpointpolar{\miterangle}{\miterlength}%
            \advance\pgf@x\pgf@xa%
            \advance\pgf@y\pgf@ya%
          }%
          %
          % Get the angle from the centerpoint to the *unrotated* border points.
          %
          \pgfmathanglebetweenpoints{\centerpoint}{\borderpoint}%
          \expandafter\edef\csname angletoborderpoint@\the\c@pgf@countb @\endcsname{\pgfmathresult}%
          \expandafter\addtosavedmacro\expandafter{\csname angletoborderpoint@\the\c@pgf@countb @\endcsname}%
          %
          % Rotatee the border points and save.
          %
          \expandafter\pgfextract@process\csname borderpoint@\the\c@pgf@countb @\endcsname{%
            \pgfmathrotatepointaround{\borderpoint}{\centerpoint}{\rotate}%
          }%
          \expandafter\addtosavedmacro\expandafter{\csname borderpoint@\the\c@pgf@countb @\endcsname}%        
          %
          % Now create the anchors.
          %
          \c@pgf@countc\c@pgf@countb%
          \advance\c@pgf@countc1\relax%
          \divide\c@pgf@countc2\relax%
          \ifodd\c@pgf@countb\relax%
            \pgfutil@ifundefined{pgf@anchor@starburst@outer point\space\the\c@pgf@countc}{%
              \expandafter\xdef\csname pgf@anchor@starburst@outer point\space\the\c@pgf@countc\endcsname{%
                \noexpand\calculatestarburstpoints%
                \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname%
              }%
            }{}%
          \else%
            \pgfutil@ifundefined{pgf@anchor@starburst@inner point\space\the\c@pgf@countc}{%
              \expandafter\xdef\csname pgf@anchor@starburst@inner point\space\the\c@pgf@countc\endcsname{%
                \noexpand\calculatestarburstpoints%
                \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname%
              }%
            }{}%
          \fi%
        \fi%
        \pgfmathadd@{\angle}{\anglestep}%
        \pgfmathmod@{\pgfmathresult}{360}%  
        \let\angle\pgfmathresult%
        \advance\c@pgf@counta1\relax%
        \ifnum\c@pgf@counta>\totalpoints%
          \c@pgf@counta1\relax%
        \fi%
        \advance\c@pgf@countb1\relax%
        \ifnum\c@pgf@countb>\totalpoints%
          \c@pgf@countb1\relax%
        \fi%
    \repeatpgfmathloop%
  }
  \savedanchor\centerpoint{%
    \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
    \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}%
    \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}%
  }%
  \savedanchor\midpoint{%
    \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
    \pgfmathsetlength\pgf@y{+.5ex}%
  }%
  \savedanchor\basepoint{%
    \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
    \pgf@y0pt\relax%
  }%
  \anchor{center}{\centerpoint}
  \anchor{base}{\basepoint}
  \anchor{mid}{\midpoint}
  \anchor{north}{%
    \calculatestarburstpoints%
    \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{\externalradius}}%
  }
  \anchor{south}{%
    \calculatestarburstpoints%
    \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}%
  }
  \anchor{east}{%
    \calculatestarburstpoints%
    \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
  }
  \anchor{west}{%
    \calculatestarburstpoints%
    \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
  }
  \anchor{north west}{%
    \calculatestarburstpoints%
    \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}%
  }
  \anchor{south west}{%
    \calculatestarburstpoints%
    \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}%
  }
  \anchor{north east}{%
    \calculatestarburstpoints%
    \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}%
  }
  \anchor{south east}{%
    \calculatestarburstpoints%
    \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}%
  }
  \backgroundpath{%  
    \calculatestarburstpoints%
    \pgfmathloop%
      \ifnum\pgfmathcounter>\totalpoints%
      \else%
        \ifnum\pgfmathcounter=1\relax%
          \let\starburstaction\pgfpathmoveto%
        \else%
          \let\starburstaction\pgfpathlineto%
        \fi%
        \starburstaction{%
          %\pgfmathrotatepointaround{\csname point@\pgfmathcounter @\endcsname}{\centerpoint}{\rotate}}%
          \csname point@\pgfmathcounter @\endcsname}
      \repeatpgfmathloop%
    \pgfpathclose%    
  }
  \anchorborder{%
    %
    % Save x and y.
    %
    \edef\externalx{\the\pgf@x}%
    \edef\externaly{\the\pgf@y}%
    %
    % Adjust the location of the external 
    % point relative to \centerpoint.
    %
    \centerpoint%
    \pgf@xa\externalx\relax%
    \pgf@ya\externaly\relax%
    \advance\pgf@xa\pgf@x%
    \advance\pgf@ya\pgf@y%
    \edef\externalx{\the\pgf@xa}%
    \edef\externaly{\the\pgf@ya}%
    %
    % Get the starburst points.
    %
    \calculatestarburstpoints%
    %
    % Get the angle of the external point to the \centerpoint.
    %
    \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
    \pgfmathsubtract@{\pgfmathresult}{\rotate}%
    \ifdim\pgfmathresult pt<0pt\relax%
      \pgfmathadd@{\pgfmathresult}{360}%
    \fi%
    \let\externalangle\pgfmathresult%
    %
    % Locate the appropriate sides on the starburst border...
    %
    \ifdim\externalangle pt<90pt\relax%
      \c@pgf@counta0\relax%
      \c@pgf@countb\totalpoints\relax%
      \pgfmathloop%
      \ifnum\c@pgf@counta>0\relax%
      \else%
        \ifdim\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt>90pt\relax%
          \c@pgf@counta\c@pgf@countb%
        \else%
          \ifdim\externalangle pt>\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt\relax%
            \c@pgf@counta\c@pgf@countb%
          \fi%
        \fi%
        \advance\c@pgf@countb-1\relax%
      \repeatpgfmathloop%
      \edef\first{\the\c@pgf@counta}%
      \advance\c@pgf@counta1\relax%
      \ifnum\c@pgf@counta>\totalpoints\relax%
        \c@pgf@counta1\relax%
      \fi%
      \edef\second{\the\c@pgf@counta}%
    \else%
      \c@pgf@counta0\relax%
      \pgfmathloop%
      \ifnum\c@pgf@counta>0\relax%
      \else%
        \ifdim\csname angletoborderpoint@\pgfmathcounter @\endcsname pt<90pt\relax%
          \c@pgf@counta\pgfmathcounter%
        \else%
          \ifdim\externalangle pt<\csname angletoborderpoint@\pgfmathcounter @\endcsname pt\relax%
            \c@pgf@counta\pgfmathcounter%  
          \fi%
        \fi%          
      \repeatpgfmathloop%
      \edef\first{\the\c@pgf@counta}%
      \advance\c@pgf@counta-1\relax%
      \ifnum\c@pgf@counta=0\relax%
        \c@pgf@counta\totalpoints\relax%
      \fi%
      \edef\second{\the\c@pgf@counta}%
    \fi%
    %
    % ...and thus, the point on the star border.
    %
    \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
        {\csname borderpoint@\first @\endcsname}{\csname borderpoint@\second @\endcsname}%
  }%
}




% Keys for shape cloud.
%
% /pgf/cloud puffs    : the number of cloud puffs.
% /pgf/cloud puff arc : the length of the cloud puff arc.

\newif\ifpgfcloudanchorsuseellipse%
\newif\ifpgfcloudignoresaspect%
\pgfcloudignoresaspectfalse%
\pgfkeys{/pgf/.cd,
  cloud puffs/.initial=10,
  cloud puff arc/.initial=150,
  cloud ignores aspect/.is if=pgfcloudignoresaspect,
  cloud anchors use ellipse/.is if=pgfcloudanchorsuseellipse
}%


% If symbol library is loaded separately these need to be defined.
%
\pgfkeys{/pgf/.cd,
  aspect/.code={\pgfsetshapeaspect{#1}},% this for tikz...
  shape aspect/.initial=1,% but this is consistent with other pgfset stuff. 
  shape aspect/.code={%
    \pgfkeys{/pgf/aspect=#1}%
    \pgfkeyssetvalue{/pgf/shape aspect}{#1}
  }%
}

\def\pgfsetshapeaspect#1{%
  \def\pgfshapeaspect{#1}%
  % Invert
  \pgfutil@tempdima=#1pt%
  \pgfutil@tempdima=.125\pgfutil@tempdima%
  \c@pgf@counta=\pgfutil@tempdima\relax% 8192*determinant
  \pgfutil@tempdima=8192pt%
  \divide\pgfutil@tempdima by\c@pgf@counta%
  \edef\pgfshapeaspectinverse{\pgf@sys@tonumber{\pgfutil@tempdima}}
}

\pgfsetshapeaspect{1}
%

% Shape cloud.
%
\pgfdeclareshape{cloud}{%
  \savedmacro\getradii{%
    \pgfmathtruncatemacro\puffs{\pgfkeysvalueof{/pgf/cloud puffs}}%
    \addtosavedmacro\puffs%
    \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/cloud puffs}}%
    \let\anglestep\pgfmathresult%
    \addtosavedmacro\anglestep%
    \pgfmathsetmacro\arc{\pgfkeysvalueof{/pgf/cloud puff arc}}%
    \addtosavedmacro\arc%
    %
    % x radius.
    %
    \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
    \advance\pgf@x.5\wd\pgfnodeparttextbox%
    \pgf@x1.4142135\pgf@x%
    %
    % y radius.
    %
    \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
    \advance\pgf@y.5\ht\pgfnodeparttextbox%
    \advance\pgf@y.5\dp\pgfnodeparttextbox%
    \pgf@y1.4142135\pgf@y%
    %
    % Adjust for shape aspect.
    %
    \ifpgfcloudignoresaspect%
      \pgf@xc\pgf@x%
      \pgf@yc\pgf@y%
    \else%
      \pgf@xc\pgfshapeaspect\pgf@y%
      \ifdim\pgf@xc<\pgf@x%
        \pgf@xc\pgf@x%
      \fi%
      \pgf@yc\pgfshapeaspectinverse\pgf@xc%
      \ifdim\pgf@yc<\pgf@y%
        \pgf@yc\pgf@y%
        \pgf@xc\pgfshapeaspect\pgf@y%
      \fi%
    \fi%
    %
    \edef\xinnerradius{\the\pgf@xc}%
    \edef\yinnerradius{\the\pgf@yc}%
    %
    % Get the larger of the outer sep.
    %  
    \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
    \ifdim\pgf@x<\pgf@y%
      \pgf@x\pgf@y%
    \fi%
    \edef\outersep{\the\pgf@x}%
    \addtosavedmacro\outersep%
    %
    % For a given cloud, with puff arc length a, the quotient of the
    % distance between the start and end point of a puffs circular arc
    % and the radius of that arc, is constant:
    %
    % g = .5 * sec((180-a)/2)
    % 
    \pgfmathsubtract{180}{\arc}%
    \pgfmathdivide@{\pgfmathresult}{2}%
    \let\tempangle\pgfmathresult%
    \pgfmathsec@{\pgfmathresult}%
    \pgfmathdivide@{\pgfmathresult}{2}%
    \let\arcradiusquotient\pgfmathresult%
    \addtosavedmacro\arcradiusquotient%
    %
    % In addition, the quotient of the distance between the start and
    % end point of a puffs circular arc and the height of that arc 
    % (ignoring rotation), is also constant:
    %
    % h = .5 * (1-sin((180-a)/2))/cos((180-a)/2)
    %   = g  * (1 - sin((180-a)/2))
    \pgfmathsin@{\tempangle}%
    \pgfmathsubtract@{1}{\pgfmathresult}%
    \pgfmathmultiply@{\pgfmathresult}{\arcradiusquotient}%
    \let\archeightquotient\pgfmathresult%
    \addtosavedmacro\archeightquotient%
    %
    % Minimum size is applied to the circum-ellipse (i.e. the ellipse 
    % that passes through the extremeties of each puff). Thus, the
    % relationship between the radii of the elliptical incircle ("inellipse"?) 
    % of the cloud (x and y) and the radii of the circum-ellispe (X and Y), 
    % is given by 
    %
    % X = 2(x*cos(p/2) + ky)  
    % Y = 2(y*cos(p/2) + kx)
    % 
    % where:
    % k = sin(p/2)*((1-cos(a/2))/sin(a/2))
    % p = the angle between each puff (i.e. 360/<puffs>) 
    % a = the length of arc of the puff.
    % 
    \pgfmathdivide{\arc}{2}%
    \let\halfarcangle\pgfmathresult%
    \pgfmathcos@{\pgfmathresult}%
    \pgfmathsubtract@{1}{\pgfmathresult}%
    \let\pgf@temp\pgfmathresult%
    \pgfmathsin@{\halfarcangle}%
    \pgfmathdivide@{\pgf@temp}{\pgfmathresult}%
    \let\pgf@temp\pgfmathresult%
    \pgfmathdivide@{\anglestep}{2}%
    \pgfmathsin@{\pgfmathresult}%
    \pgfmathmultiply@{\pgfmathresult}{\pgf@temp}%
    \let\k\pgfmathresult%
    %
    \pgfmathdivide@{\anglestep}{2}%
    \pgfmathcos@{\pgfmathresult}%
    \let\coshalfanglestep\pgfmathresult%
    %
    % Calculate the actual radii of the circum-ellipse.
    %
    \pgf@x\xinnerradius\relax%
    \pgf@y\yinnerradius\relax%
    \pgf@xa\coshalfanglestep\pgf@x%
    \advance\pgf@xa\k\pgf@y%
    \pgf@ya\coshalfanglestep\pgf@y%
    \advance\pgf@ya\k\pgf@x%
    %
    % Adjust for minimum height (Y').
    %
    \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
    \ifdim\pgf@ya<.5\pgf@yb%
      \pgf@ya.5\pgf@yb%
    \fi%
    %
    % Adjust for minimum width (X').
    %
    \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
    \ifdim\pgf@xa<.5\pgf@xb%
      \pgf@xa.5\pgf@xb%
    \fi%
    %
    \edef\xouterradius{\the\pgf@xa}%
    \addtosavedmacro\xouterradius%
    \edef\youterradius{\the\pgf@ya}%
    \addtosavedmacro\youterradius%
    %
    % Now recalculate `in-ellispe' radii: 
    %
    % x = (X'cos(p/2)-kY')/cos^2(p/2)-k^2, 
    % y = (Y'cos(p/2)-kX')/cos^2(p/2)-k^2, 
    %
    \pgf@xc\k pt\relax%
    \pgf@xc-\k\pgf@xc%
    \pgf@yc\coshalfanglestep pt\relax%
    \pgf@yc\coshalfanglestep\pgf@yc%
    \advance\pgf@xc\pgf@yc\relax%
    \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xc}}% cos^2(p/2)-k^2
    %
    \pgf@x\coshalfanglestep\pgf@xa%
    \advance\pgf@x-\k\pgf@ya%
    \pgf@x\pgfmathresult\pgf@x%
    \pgf@y\coshalfanglestep\pgf@ya%
    \advance\pgf@y-\k\pgf@xa%
    \pgf@y\pgfmathresult\pgf@y%
    %
    \edef\xinnerradius{\the\pgf@x}%
    \edef\yinnerradius{\the\pgf@y}%
    \addtosavedmacro\xinnerradius%
    \addtosavedmacro\yinnerradius%
    %
    % Get some useful trig. constants.
    %
    \pgfmathdivide@{\arc}{4}%
    \let\quarterarc\pgfmathresult%
    \pgfmathsubtract@{180}{\arc}%
    \pgfmathdivide@{\pgfmathresult}{2}%
    \let\halfcomplementarc\pgfmathresult%
    %
    \addtosavedmacro\arc%
    \addtosavedmacro\quarterarc%
    \addtosavedmacro\halfcomplementarc%
    %
    \pgfmathsec@{\halfcomplementarc}% 1/cos((180-a)/2)
    \let\sechalfcomplementarc\pgfmathresult%
    \pgfmathsin@{\halfcomplementarc}% sin((180-a)/2)
    \let\sinhalfcomplementarc\pgfmathresult%
    %
    \addtosavedmacro\sechalfcomplementarc%
    \addtosavedmacro\sinhalfcomplementarc%
    %
    \pgfmathsin@{\quarterarc}% sin(a/4)
    \let\sinquarterarc\pgfmathresult%
    \pgfmathcos@{\quarterarc}% cos(a/4)
    \let\cosquarterarc\pgfmathresult%
    \pgfmathreciprocal@{\cosquarterarc}%
    \pgfmathmultiply@{\pgfmathresult}{\sinquarterarc}% tan(a/4)
    \let\tanquarterarc\pgfmathresult%
    %
    \addtosavedmacro\sinquarterarc%
    \addtosavedmacro\cosquarterarc%
    \addtosavedmacro\tanquarterarc%
    %
  }
  \savedanchor\centerpoint{%
    \pgf@x.5\wd\pgfnodeparttextbox%
    \pgf@y.5\ht\pgfnodeparttextbox%
    \advance\pgf@y-.5\dp\pgfnodeparttextbox%
  }
  \savedanchor\midpoint{%
    \pgf@x.5\wd\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@y{+.5ex}%
  }
  \savedanchor\basepoint{%
    \pgf@x.5\wd\pgfnodeparttextbox%
    \pgf@y0pt%
  }
  \anchor{center}{\centerpoint}
  \anchor{mid}{\midpoint}
  \anchor{base}{\basepoint}
  \anchor{north}{%
    \getradii%
    \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{\youterradius}}%
  }%
  \anchor{south}{%
    \getradii%
    \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{-\youterradius}}%
  }%
  \anchor{east}{%
    \getradii%
    \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{\xouterradius}{0pt}}%
  }%
  \anchor{west}{%
    \getradii%
    \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{-\xouterradius}{0pt}}%
  }%
  \anchor{north west}{%
    \getradii%
    \pgfextract@process\pgf@sh{%
      \pgf@x\xouterradius\relax%
      \pgf@x-0.707106\pgf@x%
      \pgf@y\youterradius\relax%
      \pgf@y0.707106\pgf@y%
    }%
    \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}%
  }%
  \anchor{north east}{%
    \getradii%
    \pgfextract@process\pgf@sh{%
      \pgf@x\xouterradius\relax%
      \pgf@x0.707106\pgf@x%
      \pgf@y\youterradius\relax%
      \pgf@y0.707106\pgf@y%
    }%
    \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}%
  }%
  \anchor{south west}{%
    \getradii%
    \pgfextract@process\pgf@sh{%
      \pgf@x\xouterradius\relax%
      \pgf@x-0.707106\pgf@x%
      \pgf@y\youterradius\relax%
      \pgf@y-0.707106\pgf@y%
    }%
    \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}%
  }%
  \anchor{south east}{%
    \getradii%
    \pgfextract@process\pgf@sh{%
      \pgf@x\xouterradius\relax%
      \pgf@x0.707106\pgf@x%
      \pgf@y\youterradius\relax%
      \pgf@y-0.707106\pgf@y%
    }%
    \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}%
  }%
  %
  % Each `puff' is a circular arc of length a, drawn using two a/2 
  % arcs (a < 180), approximated by Bezier curves. 
  % Due to TeX rounding errors, it is sometimes necessary to `force' 
  % the arc to end at a specific point. So...
  %
  % @article{riskus2006,
  %   author  = {Aleskus Ri\v{s}kus},
  %   title   = {Approximation of a cubic Bezier curve by circular arcs and vice versa},
  %   journal = {Information Technology and Control},
  %   year    = {2006},
  %   volume  = {35},
  %   number  = {4}
  % }
  %
  \backgroundpath{%
    {%
    \getradii%
    %
    % Get the start angle.
    %
    \pgfmathdivide@{\anglestep}{2}%
    \pgfmathsubtract@{90}{\pgfmathresult}%
    \let\angle\pgfmathresult%
    %
    % Calculate the first arc point.
    %
    \pgfextract@process\arcfirstpoint{%
      \pgfpointadd{\centerpoint}{%
        \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}%
      }%
    }%
    \pgfpathmoveto{\arcfirstpoint}%
    \let\arcendpoint\arcfirstpoint%
    %
    \pgfmathloop%
    \ifnum\pgfmathcounter>\puffs\relax%
    \else
      \let\arcstartpoint\arcendpoint%
      %
      % Make sure beginning and end of path are exactly the same.
      %
      \ifnum\pgfmathcounter=\puffs\relax%
        \let\arcendpoint\arcfirstpoint%
      \else%
        \pgfmathadd@{\angle}{\anglestep}%
        \let\angle\pgfmathresult%
        \pgfextract@process\arcendpoint{%
          \pgfpointadd{\centerpoint}{%
            \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}%
          }%
        }%  
      \fi%
      %
      % Get some useful cloud parameters from \arcstartpoint and \arcendpoint.
      %
      \pgf@sh@getcloudpuffparameters%
      %
      % Get the rotation for the Bezier curve.
      %
      \pgfmathsubtract@{90}{\quarterarc}%
      \pgfmathadd@{\pgfmathresult}{\arcslope}%
      \let\arcrotate\pgfmathresult%
      \pgfmathsin@{\arcrotate}%
      \let\sinarcrotate\pgfmathresult%
      \pgfmathcos@{\arcrotate}%
      \let\cosarcrotate\pgfmathresult%
      %
      % Calculate the amount by which to scale the control 
      % points, in order to approximate an a/2 arc with radius x.
      %
      \pgf@x\arcradius\relax%
      \pgf@x\tanquarterarc\pgf@x% tan(a/4)
      \edef\controlscale{\pgfmath@tonumber{\pgf@x}}%
      %
      % Get the first control point for the first arc (length a/2)...
      %
      \pgfextract@process\controlone{%
        %
        % k = 0.552284745 (a `magic' number)...
        %
        \pgf@x0.55228475pt\relax%
        \pgf@x\sinquarterarc\pgf@x% k * sin(a/2)
        \pgf@y0.55228475pt\relax%
        \pgf@y\cosquarterarc\pgf@y% k * cos(a/2)
        %
        % ...scale the control points up...
        %
        \pgf@x\controlscale\pgf@x%
        \pgf@y\controlscale\pgf@y%
        %
        % ...rotate...
        %
        \pgf@xa\cosarcrotate\pgf@x%
        \advance\pgf@xa-\sinarcrotate\pgf@y%
        \pgf@ya\cosarcrotate\pgf@y%
        \advance\pgf@ya\sinarcrotate\pgf@x%
        %
        % ...and shift.
        %
        \arcstartpoint%
        \advance\pgf@x\pgf@xa%
        \advance\pgf@y\pgf@ya%
      }%
      %
      % Get the midpoint of the 150� arc.
      %
      \pgfextract@process\arcmidpoint{%
        \pgfextract@process\arcmidpoint{%
          \pgf@x-\halfchordlength\relax%
          \pgf@y\segmentheight\relax%
        }%
        \pgfpointadd{\arcstartpoint}{%
          \pgfmathrotatepointaround{\arcmidpoint}{\pgfpointorigin}{\arcslope}%
        }%
      }%
      %
      % Get the second control point for the first arc (length a/2)...
      %
      \pgfextract@process\controltwo{%    
        \pgf@x0.55228475pt\relax%
        \pgf@x\sinquarterarc\pgf@x%  k * sin(a/2)
        \pgf@y-0.55228475pt\relax%
        \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2)    
        %
        % ...scale, rotate and shift.
        %
        \pgf@x\controlscale\pgf@x%
        \pgf@y\controlscale\pgf@y%
        %
        \pgf@xa\cosarcrotate\pgf@x%
        \advance\pgf@xa-\sinarcrotate\pgf@y%
        \pgf@ya\cosarcrotate\pgf@y%
        \advance\pgf@ya\sinarcrotate\pgf@x%
        %
        \arcmidpoint%
        \advance\pgf@x\pgf@xa%
        \advance\pgf@y\pgf@ya%
      }%
      {%
        \pgfsetcornersarced{\pgfpointorigin}%
        \pgfpathcurveto{\controlone}{\controltwo}{\arcmidpoint}%
      }%
      %
      % Do the same for the second arc...
      %
      \pgfmathadd@{\quarterarc}{90}%
      \pgfmathadd@{\pgfmathresult}{\arcslope}%
      \let\arcrotate\pgfmathresult%
      \pgfmathsin@{\arcrotate}%
      \let\sinarcrotate\pgfmathresult%
      \pgfmathcos@{\arcrotate}%
      \let\cosarcrotate\pgfmathresult%
      %
      % First control point for the second arc...
      %
      \pgfextract@process\controlone{%        
        \pgf@x0.55228475pt\relax%
        \pgf@x\sinquarterarc\pgf@x% k * sin(a/2)
        \pgf@y0.55228475pt\relax%
        \pgf@y\cosquarterarc\pgf@y% k * cos(a/2)
        %
        % ...scale, rotate and shift.
        %
        \pgf@x\controlscale\pgf@x%
        \pgf@y\controlscale\pgf@y%
        %
        \pgf@xa\cosarcrotate\pgf@x%
        \advance\pgf@xa-\sinarcrotate\pgf@y%
        \pgf@ya\cosarcrotate\pgf@y%
        \advance\pgf@ya\sinarcrotate\pgf@x%
        %
        \arcmidpoint%
        \advance\pgf@x\pgf@xa%
        \advance\pgf@y\pgf@ya%
      }%
      %
      % Second control point for the second arc.
      %
      \pgfextract@process\controltwo{%        
        \pgf@x0.55228475pt\relax%
        \pgf@x\sinquarterarc\pgf@x%  k * sin(a/2)
        \pgf@y-0.55228475pt\relax%
        \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2)    
        %
        % ...scale, rotate and shift.
        %
        \pgf@x\controlscale\pgf@x%
        \pgf@y\controlscale\pgf@y%
        %
        \pgf@xa\cosarcrotate\pgf@x%
        \advance\pgf@xa-\sinarcrotate\pgf@y%
        \pgf@ya\cosarcrotate\pgf@y%
        \advance\pgf@ya\sinarcrotate\pgf@x%
        %
        \arcendpoint%
        \advance\pgf@x\pgf@xa%
        \advance\pgf@y\pgf@ya%
      }%
      \pgfpathcurveto{\controlone}{\controltwo}{\arcendpoint}%
      \repeatpgfmathloop%
    \pgfpathclose% Phew!
    }%
  }%
  %
  % Calculate a point on the border of the cloud. This is a two-stage process:
  %
  % 1. Locate the correct puff.
  % 2. Locate the angle on the circular arc which forms the puff.
  %
  \anchorborder{%
    %
    % Save x and y.
    %
    \edef\externalx{\the\pgf@x}%
    \edef\externaly{\the\pgf@y}%
     %
    % Get the inner radii and trig. constants.
    %
    \getradii%    
    %
    %
    %
    \ifpgfcloudanchorsuseellipse%
      \pgfpointadd{\centerpoint}{%
        \pgfpointborderellipse{%
          \pgfpoint{\externalx}{\externaly}
          }{%
            \pgfpoint{\xouterradius}{\youterradius}
          }%
      }%
    \else%
      \pgfextract@process\externalpoint{%
        \centerpoint%
        \advance\pgf@x\externalx\relax%
        \advance\pgf@y\externaly\relax%
      }%
      \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
      \let\externalangle\pgfmathresult%
      %
      % 1. Locate the correct puff: 
      %
      % Get end angle of the relavent puff arc.
      %
      \pgfmathdivide@{\anglestep}{2}%
      \let\halfanglestep\pgfmathresult%
      \pgfmathsubtract@{90}{\halfanglestep}%
      \let\endangle\pgfmathresult%
      \pgfmathloop%
        \pgfmathsubtract@{\endangle}{\anglestep}%
        \ifdim\pgfmathresult pt<-\anglestep pt\relax%
        \else%
          \let\endangle\pgfmathresult%
      \repeatpgfmathloop%
      \def\angle{0}%
      \let\lastangle\angle%
      \pgfmathloop%
        \pgfmathadd@{\endangle}{\anglestep}%
        \let\endangle\pgfmathresult%
        %
        % Calculate the `miter point'. This is the point between 
        % each puff, and takes into account the outer sep.
        %
        \pgfextract@process\miterpoint{%
          %
          \pgfextract@process\secondpoint{%
            \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}%
          }%
          %
          \pgfmathadd@{\endangle}{\anglestep}%
          \let\angletemp\pgfmathresult%
          \pgfextract@process\thirdpoint{%
            \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}%
          }%
          %
          \pgfmathsubtract@{\endangle}{\anglestep}%
          \let\angletemp\pgfmathresult%
          \pgfextract@process\firstpoint{%
            \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}%
          }%
          %
          \pgfmathanglebetweenpoints{\firstpoint}{\secondpoint}%
          \let\anglealpha\pgfmathresult%
          \pgfmathanglebetweenpoints{\secondpoint}{\thirdpoint}%
          \let\anglebeta\pgfmathresult%
          %
          \pgfmathsubtract@{\anglebeta}{\anglealpha}%
          \pgfmathdivide@{\pgfmathresult}{2}%
          \pgfmathadd@{\pgfmathresult}{\halfcomplementarc}%
          \pgfmathcosec@{\pgfmathresult}%
          \pgf@x\outersep\relax%
          \pgf@x\pgfmathresult\pgf@x%
          \edef\miterradius{\the\pgf@x}%
          %
          \pgfmathadd@{\anglealpha}{\anglebeta}%
          \pgfmathsubtract@{\pgfmathresult}{180}%
          \pgfmathdivide@{\pgfmathresult}{2}%
          \let\miterangle\pgfmathresult%
          \pgfpointadd{\secondpoint}{%
            \pgfqpointpolar{\miterangle}{\miterradius}%
          }%
        }%
        %
        % Get the angle of the miter point...
        %
        \pgfmathanglebetweenpoints{\pgfpointorigin}{\miterpoint}%
        \let\angle\pgfmathresult%
        \ifdim\angle pt<\lastangle pt\relax% Guard against 360� = 0�
          \pgfmathadd@{\angle}{360}%
          \let\angle\pgfmathresult%
        \fi%
        \let\lastangle\angle%
        %
        % ...and see if it is greater than the external point.
        %
      \ifdim\externalangle pt>\angle pt\relax%
      \repeatpgfmathloop%
      %
      % Get the start angle of the relevant arc and ensure angles are in the range.
      %
      \pgfmathmod@{\endangle}{360}%
      \let\endangle\pgfmathresult%
      \pgfmathsubtract@{\endangle}{\anglestep}%
      \ifdim\pgfmathresult pt<0pt\relax%
        \pgfmathadd@{\pgfmathresult}{360}%
      \fi%
      \let\startangle\pgfmathresult%
      %
      % Now, get the start and end points of the arc.
      %
      \pgfextract@process\arcstartpoint{%
        \pgfpointadd{\centerpoint}{%
          \pgfpointpolar{+\startangle}{+\xinnerradius and +\yinnerradius}%
        }%
      }%  
      \pgfextract@process\arcendpoint{%
        \pgfpointadd{\centerpoint}{%
          \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}%
        }%
      }%  
      %
      % Get some useful cloud parameters from \arcstartpoint and \arcendpoint.
      %
      \pgf@sh@getcloudpuffparameters%
      %
      % Hackery, for when an arc straddles 0�.
      %
      \ifdim\endangle pt<\startangle pt\relax%
        \pgfmathadd@{\externalangle}{180}%
        \pgfmathmod@{\pgfmathresult}{360}%
        \let\x\pgfmathresult%
      \else%
        \let\x\externalangle%
      \fi%
      %
      % 2. Locate the angle on the circular arc which forms the puff.
      % 
      % Essentially a binary search to find the angle on the circular  
      % arc, which provides the nearset estimate to the border point.
      %
      \let\s\halfcomplementarc% The start of the arc.
      \pgfmathadd@{\s}{\arc}%
      \let\e\pgfmathresult% The end of the arc.
      \pgfmathadd@{\e}{\s}%
      \pgfmathdivide@{\pgfmathresult}{2}%
      \let\n\pgfmathresult% The nearest estimate (default to middle of arc).
      \def\m{360}% Measure of `nearness'.
      \pgfmathloop%
        \pgfmathadd@{\e}{\s}%
        \pgfmathdivide@{\pgfmathresult}{2}%
        \let\p\pgfmathresult% The point halfway between \s and \e.
        \ifdim\p pt=\s pt\relax% 
        \else%
          %
          % Get the point on the circular arc.
          %
          \pgfmathadd@{\p}{\arcslope}%
          \let\a\pgfmathresult%
          \pgfextract@process\arcpoint{%
            \pgfpointadd{\circlecenterpoint}{%
              \pgfqpointpolar{\a}{\outerarcradius}%
            }%
          }%
          %
          % Find the angle between the node centre and the point on the arc.
          %
          \pgfmathanglebetweenpoints{\centerpoint}{\arcpoint}%
          %
          % Hackery, for when an arc straddles 0�.
          %
          \ifdim\endangle pt<\startangle pt\relax%
            \pgfmathadd@{\pgfmathresult}{180}%
            \pgfmathmod@{\pgfmathresult}{360}%
          \fi%
          \let\q\pgfmathresult%
          \ifdim\x pt=\q pt% Found it!
            \pgfmathbreakloop% Breaks after current iteration is complete.
          \else
            \ifdim\x pt<\q pt\relax%
              \let\e\p%
            \else%
              \let\s\p%
            \fi%
          \fi%
          \pgfmathsubtract@{\x}{\q}%
          \pgfmathabs@{\pgfmathresult}%
          %
          % Save the estimate if it is better than any previous estimate.
          %
          \ifdim\pgfmathresult pt<\m pt\relax%
            \let\m\pgfmathresult%
            \let\n\p%
          \fi%        
      \repeatpgfmathloop%
      %
      % Use the nearest estimate as the anchor angle.
      %
      \pgfmathadd@{\n}{\arcslope}%
      \let\anchorangle\pgfmathresult%
      %
      % Finally, the required point.
      %
      \pgfpointadd{\circlecenterpoint}{%
        \pgfqpointpolar{\anchorangle}{\outerarcradius}%
      }%
    \fi%
  }% Again, Phew!
  %
  % Now, a sneaky hack. This means an arbitrary `puff' anchors 
  % can be used for positiong the cloud shape. This is needed
  % if a cloud is positioned using the `puff <n+1>' anchor, where
  % n is the number of puffs of any previously drawn cloud.
  %
  \pgfutil@g@addto@macro\pgf@sh@s@cloud{%
    \c@pgf@counta\puffs\relax%
    \pgfmathloop%
      \ifnum\c@pgf@counta>0\relax%
        \pgfutil@ifundefined{pgf@anchor@cloud@puff\space\the\c@pgf@counta}{%
        \expandafter\xdef\csname pgf@anchor@cloud@puff\space\the\c@pgf@counta\endcsname{%
          \noexpand\pgf@sh@@cloudpuffanchor{\the\c@pgf@counta}%
        }%
      }{\c@pgf@counta0\relax}%
      \advance\c@pgf@counta-1\relax%
    \repeatpgfmathloop%  
  }%
}

% \pgf@sh@@cloudpuffanchor
% 
% Internal macro for calculating the anchors puff 1, puff 2, ... etc.
%
\def\pgf@sh@@cloudpuffanchor#1{%
    \getradii%
    \pgfmathdivide@{\anglestep}{2}%
    \let\halfanglestep\pgfmathresult%
    \c@pgf@counta#1\relax%
    \advance\c@pgf@counta-1\relax%
    \pgfmathmultiply@{\anglestep}{\the\c@pgf@counta}%
    \pgfmathadd@{\pgfmathresult}{90}%
    \pgfmathsubtract@{\pgfmathresult}{\halfanglestep}%
    \let\angle\pgfmathresult%
    %
    % Calculate the first arc point.
    %
    \pgfextract@process\arcstartpoint{%
      \pgfpointadd{\centerpoint}{%
        \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}%
      }%
    }%
    %
    \pgfmathadd@{\angle}{\anglestep}%
    \let\angle\pgfmathresult%
    \pgfextract@process\arcendpoint{%
      \pgfpointadd{\centerpoint}{%
        \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}%
      }%
    }%  
    %
    % Get some useful cloud parameters from \arcstartpoint and \arcendpoint.
    %
    \pgf@sh@getcloudpuffparameters%
    %
    % Calculate the point.
    %
    \pgfmathadd@{\arcslope}{90}%
    \let\anchorangle\pgfmathresult%
    \pgfpointadd{\circlecenterpoint}{%
      \pgfqpointpolar{\anchorangle}{\outerarcradius}%
    }%
}  

% \pgf@sh@cloudpuffparameters
%
% Internal macro to calculate some common arc parameters which 
% are required when calculating radii, drawing the background
% path and calculating border anchors.
%
\def\pgf@sh@getcloudpuffparameters{%
  %
  % Calculate the angle to which the entire arc is sloped.
  %
  \pgfmathanglebetweenpoints{\arcendpoint}{\arcstartpoint}%
  \let\arcslope\pgfmathresult%
  %
  % Calculate the chord length and arc radius.
  %
  \pgfpointdiff{\arcendpoint}{\arcstartpoint}%
  \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}
  \pgf@x\pgfmathresult pt\relax%
  \pgf@xa.5\pgf@x%
  \edef\halfchordlength{\the\pgf@xa}%
  \pgf@x\arcradiusquotient\pgf@x%
  \edef\arcradius{\the\pgf@x}%
  \pgf@xa\outersep\relax%
  \advance\pgf@xa\pgf@x%
  \edef\outerarcradius{\the\pgf@xa}%
  %
  % Calculate the height of the resulting segment.
  %
  \pgf@y-\sinhalfcomplementarc\pgf@x% sin((180-a)/2)
  \advance\pgf@y\pgf@x%
  \edef\segmentheight{\the\pgf@y}%
  %
  % Calculate the center of the circle of which the arc is a part.
  %
  \pgfextract@process\circlecenterpoint{%
    \pgfextract@process\circlecenterpoint{%
      \pgf@x-\halfchordlength\relax%
      \pgf@y\segmentheight\relax%
      \advance\pgf@y-\arcradius
    }%
    \pgfpointadd{\arcstartpoint}{%
      \pgfmathrotatepointaround{\circlecenterpoint}{\pgfpointorigin}{\arcslope}%
    }%
  }%
}





% Internal macros for signal shape.
%
\def\pgf@lib@sh@signal@nowhere{nowhere}%
\def\pgf@lib@sh@signal@from{from}%
\def\pgf@lib@sh@signal@to{to}%

\def\pgf@lib@sh@signal@parsedirection#1#2{%
  %
  \let\pgf@lib@sh@signal@direction=#2%
  \edef\pgf@lib@sh@temp{#1}%
  \expandafter\pgf@lib@sh@signal@@parsedirection\pgf@lib@sh@temp\pgf@stop}

\def\pgf@lib@sh@signal@@parsedirection#1\pgf@stop{%
  \pgfutil@in@{and}{#1}%
  \ifpgfutil@in@%
    \pgf@lib@sh@signal@@@parsedirection#1\pgf@lib%
  \else%
    \pgf@lib@sh@signal@@@parsedirection#1 and #1\pgf@lib%
  \fi
}
\def\pgf@lib@sh@signal@@@parsedirection#1 and #2\pgf@lib{%
  \pgfutil@in@{nowhere}{#1}%
  \ifpgfutil@in@
  \else%
    \pgf@lib@sh@signal@@@@parsedirection{#1}%
    \pgf@lib@sh@signal@@@@parsedirection{#2}%
  \fi%
}
\def\pgf@lib@sh@signal@@@@parsedirection#1{%
  \pgfutil@in@{ #1 }{ east right }%
  \ifpgfutil@in@%
    \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@direction%
    \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere%
    \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere%
  \fi%
  \pgfutil@in@{ #1 }{ left west }%
  \ifpgfutil@in@%
    \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@direction%
    \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere%
    \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere%
  \fi%
  \pgfutil@in@{ #1 }{ above up north }%
  \ifpgfutil@in@%
    \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@direction%
    \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere%
    \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere%
  \fi%
  \pgfutil@in@{ #1 }{ below down south }%
  \ifpgfutil@in@%
    \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@direction%
    \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere%
    \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere%
  \fi%
}


% Keys for signal shape:
%
\pgfkeys{/pgf/.cd,
  signal pointer angle/.initial=90,
  signal to/.initial=east,
  signal from/.initial=nowhere
}

\pgfdeclareshape{signal}{%
  \savedmacro\installsignalparameters{%
    %
    \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere%
    \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere%
    \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere%
    \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere%
    %
    \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal from}}{\pgf@lib@sh@signal@from}%
    \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal to}}{\pgf@lib@sh@signal@to}%    
    %
    % Define a centerpoint.
    %
    \pgfextract@process\centerpoint{%
      \pgf@x.5\wd\pgfnodeparttextbox%
      \pgf@y.5\ht\pgfnodeparttextbox%
      \advance\pgf@y-.5\dp\pgfnodeparttextbox%
    }%
    %
    % Get some useful trig. stuff
    %
    \pgfmathsetmacro\pointerangle{\pgfkeysvalueof{/pgf/signal pointer angle}}%
    %
    \pgfmathdivide@{\pointerangle}{2}%
    \let\halfpointerangle=\pgfmathresult%
    %
    \pgfmathcosec@{\halfpointerangle}%
    \let\cosechalfpointerangle=\pgfmathresult%
    %
    \pgfmathdivide@{\halfpointerangle}{2}%
    \let\quarterpointerangle=\pgfmathresult%
    %
    \pgfmathcosec@{\quarterpointerangle}%
    \let\cosecquarterpointerangle=\pgfmathresult%
    %
    \pgfmathsec@{\quarterpointerangle}%
    \let\secquarterpointerangle=\pgfmathresult%
    %
    \pgfmathsubtract@{90}{\quarterpointerangle}%
    \let\complementquarterpointerangle\pgfmathresult%
    %
    % Get the larger of the outer sep.
    %
    \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
    \ifdim\pgf@x>\pgf@y%
      \pgf@y\pgf@x%
    \fi%
    \pgf@yc=\pgf@y%
    %
    % Calculate the miter due to the line width, at the pointer apex... 
    %
    \pgf@x=\cosechalfpointerangle\pgf@y%
    \edef\pointerapexmiter{\the\pgf@x}%
    %
    % ...at a corner by a `to' pointer (i.e. sticks out)...
    %
    \pgf@x=\secquarterpointerangle\pgf@y%
    \edef\tocornermiter{\the\pgf@x}%
    %
    % ...at a corner by a `from' pointer (i.e. sticks in).
    %
    \pgf@x=\cosecquarterpointerangle\pgf@y
    \edef\fromcornermiter{\the\pgf@x}%
    %
    % Get the (half) dimensions of the node.
    %
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
    \advance\pgf@xa.5\wd\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
    \advance\pgf@ya.5\ht\pgfnodeparttextbox%
    \advance\pgf@ya.5\dp\pgfnodeparttextbox%
    %
    % Get the distance a pointer sticks out to the side...
    %
    \pgfmathsubtract@{90}{\halfpointerangle}%
    \pgfmathtan@{\pgfmathresult}%
    \pgf@xb=\pgfmathresult\pgf@ya%
    % 
    % ...and up.
    %
    \pgf@yb=\pgfmathresult\pgf@xa%
    %
    % Adjust for minimum height.
    %
    \pgfutil@tempdima=2.0\pgf@ya%
    \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere%
    \else%
      \advance\pgfutil@tempdima by\pgf@yb%
    \fi%
    \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere%
    \else%
      \advance\pgfutil@tempdima by\pgf@yb%
    \fi%
    \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}%
    \ifdim\pgfutil@tempdima<\pgf@y%
      \pgfutil@tempdima=\pgf@y%
      %
      \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere%
      \else%
        \advance\pgfutil@tempdima by-\pgf@yb%
      \fi%
      \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere%
      \else%
        \advance\pgfutil@tempdima by-\pgf@yb%
      \fi%
      \pgf@ya=0.5\pgfutil@tempdima%
      \pgfmathsubtract@{90}{\halfpointerangle}%
      \pgfmathtan@{\pgfmathresult}%
      \pgf@xb=\pgfmathresult\pgf@ya%
    \fi%
    %
    % Adjust for minimum width.
    %
    \pgfutil@tempdima=2.0\pgf@xa%
    \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
    \else%
      \advance\pgfutil@tempdima by\pgf@xb%
    \fi%
    \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
    \else%
      \advance\pgfutil@tempdima by\pgf@xb%
    \fi%
    \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/minimum width}}%
    \ifdim\pgfutil@tempdima<\pgf@x%
      \pgfutil@tempdima=\pgf@x%
      \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
      \else%
        \advance\pgfutil@tempdima by-\pgf@xb%
      \fi%
      \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
      \else%
        \advance\pgfutil@tempdima by-\pgf@xb%
      \fi%
      \pgf@xa=0.5\pgfutil@tempdima%
      \pgfmathsubtract@{90}{\halfpointerangle}%
      \pgfmathtan@{\pgfmathresult}%
      \pgf@yb=\pgfmathresult\pgf@xa%
    \fi%
    %
    % So, define the points for the background path.
    %
    \pgfextract@process\north{%
      \centerpoint%
      \advance\pgf@y\pgf@ya%
      \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to%
        \advance\pgf@y\pgf@yb%
      \fi%
    }%
    \pgfextract@process\south{%
      \centerpoint%
      \advance\pgf@y-\pgf@ya%
      \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to%
        \advance\pgf@y-\pgf@yb%
      \fi%
    }%
    \pgfextract@process\east{%
      \centerpoint%
      \advance\pgf@x\pgf@xa%
      \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to%
        \advance\pgf@x\pgf@xb%
      \fi%
    }%
    \pgfextract@process\west{%
      \centerpoint%
      \advance\pgf@x-\pgf@xa%
      \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to%
        \advance\pgf@x-\pgf@xb%
      \fi%
    }%
    \pgfextract@process\northeast{%
      \centerpoint%
      \advance\pgf@y\pgf@ya%
      \advance\pgf@x\pgf@xa%
      \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from%
        \advance\pgf@y\pgf@yb%
      \fi%
      \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from%
        \advance\pgf@x\pgf@xb%
      \fi%
    }%
    \pgfextract@process\southeast{%
      \centerpoint%
      \advance\pgf@y-\pgf@ya%
      \advance\pgf@x\pgf@xa%
      \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from%
        \advance\pgf@y-\pgf@yb%
      \fi%
      \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from%
        \advance\pgf@x\pgf@xb%
      \fi%
    }%
    \pgfextract@process\southwest{%
      \centerpoint%
      \advance\pgf@y-\pgf@ya%
      \advance\pgf@x-\pgf@xa%
      \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from%
        \advance\pgf@y-\pgf@yb%
      \fi%
      \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from%
        \advance\pgf@x-\pgf@xb%
      \fi%
    }%
    \pgfextract@process\northwest{%
      \centerpoint%
      \advance\pgf@y\pgf@ya%
      \advance\pgf@x-\pgf@xa%
      \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from%
        \advance\pgf@y\pgf@yb%
      \fi%
      \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from%
        \advance\pgf@x-\pgf@xb%
      \fi%
    }%
    \addtosavedmacro{\north}%
    \addtosavedmacro{\south}%
    \addtosavedmacro{\east}%
    \addtosavedmacro{\west}%
    \addtosavedmacro{\northeast}%
    \addtosavedmacro{\southwest}%
    \addtosavedmacro{\southeast}%
    \addtosavedmacro{\northwest}%
    %
    % Calculate the `miter vectors' (i.e. +outer sep). 
    %
    \pgfextract@process\northmiter{%
      \pgf@x0pt%
      \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere%
        \pgf@y\pgf@yc%
      \else%
        \pgf@y\pointerapexmiter\relax%
      \fi%
    }%
    \pgfextract@process\southmiter{%
      \pgf@x0pt%
      \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere%
        \pgf@y-\pgf@yc%
      \else%
        \pgf@y-\pointerapexmiter\relax%
      \fi%
    }%
    \pgfextract@process\eastmiter{%
      \pgf@y0pt%
      \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
        \pgf@x\pgf@yc%
      \else%
        \pgf@x\pointerapexmiter\relax%
      \fi%
    }%
    \pgfextract@process\westmiter{%
      \pgf@y0pt%
      \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
        \pgf@x-\pgf@yc%
      \else%
        \pgf@x-\pointerapexmiter\relax%
      \fi%
    }%
    \pgfextract@process\northeastmiter{%
      \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
        \pgf@x\pgf@yc
        \pgf@y\pgf@yc%
      \else
        \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from%
          \pgfqpointpolar{\quarterpointerangle}{\fromcornermiter}
        \else%
          \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to%
            \pgfqpointpolar{\complementquarterpointerangle}{\tocornermiter}%
          \fi%
        \fi%  
      \fi%
      \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from%
        \pgfqpointpolar{\complementquarterpointerangle}{\fromcornermiter}%
      \else%
        \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to%
          \pgfqpointpolar{\quarterpointerangle}{\tocornermiter}%
        \fi%
      \fi%  
    }%
    \pgfextract@process\southeastmiter{%
      \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
        \pgf@x\pgf@yc%
        \pgf@y\pgf@yc%
      \else
        \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from%
          \pgfqpointpolar{-\quarterpointerangle}{\fromcornermiter}
        \else%
          \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to%
            \pgfqpointpolar{-\complementquarterpointerangle}{\tocornermiter}%
          \fi%
        \fi%  
      \fi%
      \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from%
        \pgfqpointpolar{-\complementquarterpointerangle}{\fromcornermiter}
      \else%
        \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to%
          \pgfqpointpolar{-\quarterpointerangle}{\tocornermiter}%
        \fi%
      \fi%  
    }%
    \pgfextract@process\southwestmiter{%
      \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
        \pgf@x-\pgf@yc
        \pgf@y-\pgf@yc%
      \else
        \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from%
          \pgfmathadd@{\quarterpointerangle}{180}%
          \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}
        \else%
          \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to%
            \pgfmathadd@{\complementquarterpointerangle}{180}%
            \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}%
          \fi%
        \fi%  
      \fi%
      \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from%
        \pgfmathadd@{\complementquarterpointerangle}{180}%
        \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}%
      \else%
        \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to%
          \pgfmathadd@{\quarterpointerangle}{180}%
          \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}%
        \fi%
      \fi%  
    }%
    \pgfextract@process\northwestmiter{%
      \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
        \pgf@x-\pgf@yc%
        \pgf@y\pgf@yc%
      \else
        \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from%
          \pgfmathsubtract@{180}{\quarterpointerangle}%
          \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}
        \else%
          \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to%
            \pgfmathsubtract@{180}{\complementquarterpointerangle}%
            \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}%
          \fi%
        \fi%  
      \fi%
      \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from%
        \pgfmathsubtract@{180}{\complementquarterpointerangle}%
        \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}%
      \else%
        \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to%
          \pgfmathsubtract@{180}{\quarterpointerangle}%
          \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}%
        \fi%
      \fi%  
    }%
    \addtosavedmacro{\northmiter}%
    \addtosavedmacro{\southmiter}%
    \addtosavedmacro{\eastmiter}%
    \addtosavedmacro{\westmiter}%
    \addtosavedmacro{\northeastmiter}%
    \addtosavedmacro{\southeastmiter}%
    \addtosavedmacro{\southwestmiter}%
    \addtosavedmacro{\northwestmiter}%
    %
    % Now calculate the anchor points
    %
    \pgfextract@process\anchornorth{%
      \pgfpointadd{\north}{\northmiter}%
    }%
    \pgfextract@process\anchorsouth{%
      \pgfpointadd{\south}{\southmiter}%
    }%
    \pgfextract@process\anchoreast{%
      \pgfpointadd{\east}{\eastmiter}%
    }%
    \pgfextract@process\anchorwest{%
      \pgfpointadd{\west}{\westmiter}%
    }%
    \pgfextract@process\anchornortheast{%
      \pgfpointadd{\northeast}{\northeastmiter}%
    }%
    \pgfextract@process\anchorsoutheast{%
      \pgfpointadd{\southeast}{\southeastmiter}%
    }%
    \pgfextract@process\anchorsouthwest{%
      \pgfpointadd{\southwest}{\southwestmiter}%
    }%
    \pgfextract@process\anchornorthwest{%
      \pgfpointadd{\northwest}{\northwestmiter}%
    }%
    \addtosavedmacro{\anchornorth}%
    \addtosavedmacro{\anchorsouth}%
    \addtosavedmacro{\anchoreast}%
    \addtosavedmacro{\anchorwest}%
    \addtosavedmacro{\anchornortheast}%
    \addtosavedmacro{\anchorsouthwest}%
    \addtosavedmacro{\anchorsoutheast}%
    \addtosavedmacro{\anchornorthwest}%    
  }%
  \savedanchor\centerpoint{%
    \pgf@x.5\wd\pgfnodeparttextbox%
    \pgf@y.5\ht\pgfnodeparttextbox%
    \advance\pgf@y-.5\dp\pgfnodeparttextbox%
  }%
  \savedanchor\basepoint{%
    \pgf@x.5\wd\pgfnodeparttextbox%
    \pgf@y0pt%
  }%
  \savedanchor\midpoint{%
    \pgf@x.5\wd\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@y{+.5ex}%
  }%
  \anchor{center}{\centerpoint}%
  \anchor{base}{\basepoint}%
  \anchor{base east}{%
    \installsignalparameters%
    \anchoreast%
    \pgf@xa\pgf@x%
    \pgf@ya\pgf@y%
    \anchorsoutheast%
    \ifdim\pgf@xa>\pgf@x%
      \pgfutil@tempdima\pgf@xa%
    \else%
      \pgfutil@tempdima\pgf@x%
    \fi%
    \pgfextract@process\externalpoint{%
      \basepoint%
      \pgf@x\pgfutil@tempdima%
    }
    \basepoint%
    \let\firstpoint\anchoreast%
    \ifdim\pgf@y<\pgf@ya%
      \let\secondpoint\anchorsoutheast%
    \else%
      \let\secondpoint\anchornortheast%
    \fi%
    \pgfpointintersectionoflines{\basepoint}{\externalpoint}%
      {\firstpoint}{\secondpoint}%    
  }%
  \anchor{base west}{%
    \installsignalparameters%
    \anchorwest%
    \pgf@xa\pgf@x%
    \pgf@ya\pgf@y%
    \anchorsouthwest%
    \ifdim\pgf@xa<\pgf@x%
      \pgfutil@tempdima\pgf@xa%
    \else%
      \pgfutil@tempdima\pgf@x%
    \fi%
    \pgfextract@process\externalpoint{%
      \basepoint%
      \pgf@x\pgfutil@tempdima%
    }
    \basepoint%
    \let\firstpoint\anchorwest%
    \ifdim\pgf@y<\pgf@ya%
      \let\secondpoint\anchorsouthwest%
    \else%
      \let\secondpoint\anchornorthwest%
    \fi%
    \pgfpointintersectionoflines{\basepoint}{\externalpoint}%
      {\firstpoint}{\secondpoint}%    
  }%
  \anchor{mid}{\midpoint}%
  \anchor{mid east}{%
    \installsignalparameters%
    \anchoreast%
    \pgf@xa\pgf@x%
    \pgf@ya\pgf@y%
    \anchorsoutheast%
    \ifdim\pgf@xa>\pgf@x%
      \pgfutil@tempdima\pgf@xa%
    \else%
      \pgfutil@tempdima\pgf@x%
    \fi%
    \pgfextract@process\externalpoint{%
      \midpoint%
      \pgf@x\pgfutil@tempdima%
    }
    \midpoint%
    \let\firstpoint\anchoreast%
    \ifdim\pgf@y<\pgf@ya%
      \let\secondpoint\anchorsoutheast%
    \else%
      \let\secondpoint\anchornortheast%
    \fi%
    \pgfpointintersectionoflines{\midpoint}{\externalpoint}%
      {\firstpoint}{\secondpoint}%    
  }%
  \anchor{mid west}{%
    \installsignalparameters%
    \anchorwest%
    \pgf@xa\pgf@x%
    \pgf@ya\pgf@y%
    \anchorsouthwest%
    \ifdim\pgf@xa<\pgf@x%
      \pgfutil@tempdima\pgf@xa%
    \else%
      \pgfutil@tempdima\pgf@x%
    \fi%
    \pgfextract@process\externalpoint{%
      \midpoint%
      \pgf@x\pgfutil@tempdima%
    }
    \midpoint%
    \let\firstpoint\anchorwest%
    \ifdim\pgf@y<\pgf@ya%
      \let\secondpoint\anchorsouthwest%
    \else%
      \let\secondpoint\anchornorthwest%
    \fi%
    \pgfpointintersectionoflines{\midpoint}{\externalpoint}%
      {\firstpoint}{\secondpoint}%    
  }%
  \anchor{north}{\installsignalparameters\anchornorth}%
  \anchor{south}{\installsignalparameters\anchorsouth}%
  \anchor{east}{\installsignalparameters\anchoreast}%
  \anchor{west}{\installsignalparameters\anchorwest}%
  \anchor{north east}{\installsignalparameters\anchornortheast}%
  \anchor{south east}{\installsignalparameters\anchorsoutheast}%
  \anchor{south west}{\installsignalparameters\anchorsouthwest}%
  \anchor{north west}{\installsignalparameters\anchornorthwest}%
  \backgroundpath{%
    \installsignalparameters%
    \pgfpathmoveto{\north}%
    \pgfpathlineto{\northeast}%
    \pgfpathlineto{\east}%
    \pgfpathlineto{\southeast}%
    \pgfpathlineto{\south}%
    \pgfpathlineto{\southwest}%
    \pgfpathlineto{\west}%
    \pgfpathlineto{\northwest}%
    \pgfpathclose%
  }
  \anchorborder{%
    %
    % Save x and y.
    %
    \edef\externalx{\the\pgf@x}%
    \edef\externaly{\the\pgf@y}%
    %
    % Adjust the location of the external 
    % point relative to \centerpoint.
    %
    \centerpoint%
    \pgf@xa\externalx\relax%
    \pgf@ya\externaly\relax%
    \advance\pgf@xa\pgf@x%
    \advance\pgf@ya\pgf@y%
    \edef\externalx{\the\pgf@xa}%
    \edef\externaly{\the\pgf@ya}%
    %
    % Get the shape parameters.
    %
    \installsignalparameters%
    %
    % Get the angle of the external point to the \centerpoint.
    %
    \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
    \let\externalangle\pgfmathresult%
    %
    %
    %
    \pgfmathanglebetweenpoints{\centerpoint}{\anchorwest}%
    \ifdim\externalangle pt<\pgfmathresult pt\relax%
      \pgfmathanglebetweenpoints{\centerpoint}{\anchornorth}%
      \ifdim\externalangle pt<\pgfmathresult pt\relax%
        \pgfmathanglebetweenpoints{\centerpoint}{\anchornortheast}%
        \ifdim\externalangle pt<\pgfmathresult pt\relax%
          \let\firstpoint\anchoreast%
          \let\secondpoint\anchornortheast%
        \else%
          \let\secondpoint\anchornortheast%
          \let\firstpoint\anchornorth%
        \fi%
      \else%
        \pgfmathanglebetweenpoints{\centerpoint}{\anchornorthwest}%
        \ifdim\externalangle pt<\pgfmathresult pt\relax%
          \let\firstpoint\anchornorth%
          \let\secondpoint\anchornorthwest%
        \else%
          \let\secondpoint\anchornorthwest%
          \let\firstpoint\anchorwest%
        \fi%
      \fi%
    \else%
      \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouth}%
      \ifdim\externalangle pt<\pgfmathresult pt\relax%
        \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouthwest}%
        \ifdim\externalangle pt<\pgfmathresult pt\relax%
          \let\firstpoint\anchorwest%
          \let\secondpoint\anchorsouthwest%
        \else%
          \let\secondpoint\anchorsouthwest%
          \let\firstpoint\anchorsouth%
        \fi%
      \else%
        \pgfmathanglebetweenpoints{\centerpoint}{\anchorsoutheast}%
        \ifdim\externalangle pt<\pgfmathresult pt\relax%
          \let\firstpoint\anchorsouth%
          \let\secondpoint\anchorsoutheast%
        \else%
          \let\secondpoint\anchorsoutheast%
          \let\firstpoint\anchoreast%
        \fi%
      \fi%
    \fi%
    %
    % Now locate the point.
    %
    \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
      {\firstpoint}{\secondpoint}%
  }%
}%






% Keys for shape tape
%
% /pgf/tape bend top : Type of bend for north side.
% /pgf/tape bend bottom : Type of bend for south side.
% /pgf/tape bend height : The height of the bends.
\pgfkeys{/pgf/.cd,
  tape bend top/.initial=in and out,
  tape bend bottom/.initial=in and out,
  tape bend/.style={/pgf/tape bend top=#1, /pgf/tape bend bottom=#1},
  tape bend height/.initial=5pt
}

\def\pgf@lib@sh@inandouttext{in and out}
\def\pgf@lib@sh@outandintext{out and in}
\def\pgf@lib@sh@nonetext{none}

\pgfdeclareshape{tape}{
  \savedmacro\tapedimensions{%
    \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
    \advance\pgf@x.5\wd\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
    \advance\pgf@y.5\ht\pgfnodeparttextbox%
    \advance\pgf@y.5\dp\pgfnodeparttextbox%
    %
    \pgfmathsetlengthmacro\outerxsep{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlengthmacro\outerysep{\pgfkeysvalueof{/pgf/outer ysep}}%
    \addtosavedmacro\outerxsep%
    \addtosavedmacro\outerysep%
    %
    \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/tape bend height}}%
    \pgfutil@tempdima.5\pgfutil@tempdima%
    \edef\halfbendheight{\the\pgfutil@tempdima}%
    \addtosavedmacro\halfbendheight%
    %
    \pgfkeysgetvalue{/pgf/tape bend top}{\topbendstyle}%
    \pgfkeysgetvalue{/pgf/tape bend bottom}{\bottombendstyle}%
    \addtosavedmacro\topbendstyle%
    \addtosavedmacro\bottombendstyle%
    %
    \ifx\topbendstyle\pgf@lib@sh@nonetext%
    \else%
      \advance\pgf@y\pgfutil@tempdima%
    \fi%
    \ifx\bottombendstyle\pgf@lib@sh@none%
    \else%
      \advance\pgf@y\pgfutil@tempdima%
    \fi%
    %
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
    \ifdim\pgf@x<.5\pgf@xa%
      \pgf@x.5\pgf@xa%
    \fi%
    \ifdim\pgf@y<.5\pgf@ya%
      \pgf@y.5\pgf@ya%
    \fi%
    \ifx\topbendstyle\pgf@lib@sh@nonetext%
    \else%
      \advance\pgf@y-\pgfutil@tempdima%
    \fi%
    \ifx\bottombendstyle\pgf@lib@sh@nonetext%
    \else%
      \advance\pgf@y-\pgfutil@tempdima%
    \fi%  
    %
    \pgfutil@tempdima3.414213\pgfutil@tempdima% 1 / (1-sin(45))
    \edef\bendyradius{\the\pgfutil@tempdima}%
    \addtosavedmacro\bendyradius%
    \advance\pgfutil@tempdima\outerysep%
    \edef\outerbendyradius{\the\pgfutil@tempdima}%
    \addtosavedmacro\outerbendyradius%
    \advance\pgfutil@tempdima-\outerysep%
    \advance\pgfutil@tempdima-\outerysep%
    \edef\innerbendyradius{\the\pgfutil@tempdima}%
    \addtosavedmacro\innerbendyradius%
    %
    \pgfutil@tempdima0.707106\pgf@x% cos(45) 
    \edef\bendxradius{\the\pgfutil@tempdima}%
    \addtosavedmacro\bendxradius%
    \advance\pgfutil@tempdima\outerxsep%
    \edef\outerbendxradius{\the\pgfutil@tempdima}%
    \addtosavedmacro\outerbendxradius%
    \advance\pgfutil@tempdima-\outerxsep%
    \advance\pgfutil@tempdima-\outerxsep%
    \edef\innerbendxradius{\the\pgfutil@tempdima}%
    \addtosavedmacro\innerbendxradius%
    %
    \edef\halfwidth{\the\pgf@x}%
    \edef\halfheight{\the\pgf@y}%
    \addtosavedmacro\halfwidth%
    \addtosavedmacro\halfheight%
    %
    \advance\pgf@x\outerxsep%
    \edef\outerhalfwidth{\the\pgf@x}%
    \addtosavedmacro\outerhalfwidth%
    %
    \pgf@xc\bendxradius%
    \pgf@yc\bendyradius%
    \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@xc}}%
    \pgfmathatan{\pgfmathresult}%
    \pgf@xc\pgfmathresult pt\relax%
    \pgf@xc.5\pgf@xc%
    \edef\halfangle{\pgfmath@tonumber{\pgf@xc}}%
    \addtosavedmacro\halfangle%
    %
    \pgf@xc45pt\relax%
    \advance\pgf@xc-\halfangle pt%
    \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}%
    \let\cothalfanglein\pgfmathresult%
    \addtosavedmacro\cothalfanglein%
    %
    \pgf@xc90pt\relax%
    \advance\pgf@xc-\halfangle pt%
    \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}%
    \let\cothalfangleout\pgfmathresult%
    \addtosavedmacro\cothalfangleout%
    %
  }
  \savedanchor{\centerpoint}{%
    \pgf@x.5\wd\pgfnodeparttextbox%
    \pgf@y.5\ht\pgfnodeparttextbox%
    \advance\pgf@y-.5\dp\pgfnodeparttextbox%  
  }
    \savedanchor{\midpoint}{%
    \pgf@x.5\wd\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@y{+0.5ex}%
  }
  \savedanchor{\basepoint}{%
    \pgf@x.5\wd\pgfnodeparttextbox%
    \pgf@y0pt%
  }
  \anchor{center}{\centerpoint}%
  \anchor{mid}{\midpoint}%
  \anchor{mid east}{\tapedimensions\midpoint\advance\pgf@x\outerhalfwidth}%
  \anchor{mid west}{\tapedimensions\midpoint\advance\pgf@x-\outerhalfwidth}%
  \anchor{base}{\basepoint}%
  \anchor{base east}{\tapedimensions\basepoint\advance\pgf@x\outerhalfwidth}%
  \anchor{base west}{\tapedimensions\basepoint\advance\pgf@x-\outerhalfwidth}%
  \anchor{north}{%
    \csname pgf@anchor@tape@north east\endcsname%
    \pgf@ya\pgf@y%  
    \csname pgf@anchor@tape@north west\endcsname%
    \advance\pgf@ya\pgf@y%  
    \centerpoint%
    \pgf@y.5\pgf@ya%
  }
  \anchor{south}{%
    \csname pgf@anchor@tape@south east\endcsname%
    \pgf@ya\pgf@y%  
    \csname pgf@anchor@tape@south west\endcsname%
    \advance\pgf@ya\pgf@y%  
    \centerpoint%
    \pgf@y.5\pgf@ya%
  }
  \anchor{east}{%
    \tapedimensions%
    \centerpoint%
    \advance\pgf@x\outerhalfwidth%
  }
  \anchor{west}{%
    \tapedimensions%
    \centerpoint%
    \advance\pgf@x-\outerhalfwidth%
  }
  \anchor{north east}{%
    \tapedimensions%
    \centerpoint%
    \advance\pgf@x\outerhalfwidth%
    \advance\pgf@y\halfheight%
    \pgf@yc\outerysep%
    \ifx\topbendstyle\pgf@lib@sh@inandouttext%
      \advance\pgf@y\halfbendheight%
      \advance\pgf@y\cothalfangleout\pgf@yc%  
    \else%
      \ifx\topbendstyle\pgf@lib@sh@outandintext%  
        \advance\pgf@y\halfbendheight%
        \advance\pgf@y\cothalfanglein\pgf@yc%  
      \else%
        \advance\pgf@y\pgf@yc%
      \fi%
    \fi%    
  }%
  \anchor{north west}{%
    \tapedimensions%
    \centerpoint%
    \advance\pgf@x-\outerhalfwidth%
    \advance\pgf@y\halfheight%
    \pgf@yc\outerysep%
    \ifx\topbendstyle\pgf@lib@sh@inandouttext%
      \advance\pgf@y\halfbendheight%
      \advance\pgf@y\cothalfanglein\pgf@yc%  
    \else%
      \ifx\topbendstyle\pgf@lib@sh@outandintext%
        \advance\pgf@y\halfbendheight%
        \advance\pgf@y\cothalfangleout\pgf@yc%  
      \else%
        \advance\pgf@y\pgf@yc%
      \fi%
    \fi%      
  }%
  \anchor{south east}{%
    \tapedimensions%
    \centerpoint%
    \advance\pgf@x\outerhalfwidth%
    \advance\pgf@y-\halfheight%
    \pgf@yc\outerysep%
    \ifx\topbendstyle\pgf@lib@sh@outandintext%
      \advance\pgf@y-\halfbendheight%
      \advance\pgf@y-\cothalfangleout\pgf@yc%  
    \else%
      \ifx\topbendstyle\pgf@lib@sh@inandouttext%  
        \advance\pgf@y-\halfbendheight%
        \advance\pgf@y-\cothalfanglein\pgf@yc%  
      \else%
        \advance\pgf@y-\pgf@yc%
      \fi%
    \fi%      
  }%
  \anchor{south west}{%
    \tapedimensions%
    \centerpoint%
    \advance\pgf@x-\outerhalfwidth%
    \advance\pgf@y-\halfheight%
    \pgf@yc\outerysep%
    \ifx\topbendstyle\pgf@lib@sh@outandintext%
      \advance\pgf@y-\halfbendheight%
      \advance\pgf@y-\cothalfanglein\pgf@yc%  
    \else%
      \ifx\topbendstyle\pgf@lib@sh@inandouttext%
        \advance\pgf@y-\halfbendheight%
        \advance\pgf@y-\cothalfangleout\pgf@yc%  
      \else%
        \advance\pgf@y-\pgf@yc%
      \fi%
    \fi%      
  }%
  \backgroundpath{%
    \tapedimensions%
    %
    \pgf@xc\halfwidth%
    \pgf@yc\halfheight%    
    %
    \pgf@xc\bendxradius%
    \pgf@yc\bendyradius%    
    {%
      \pgftransformshift{\centerpoint}%
      \pgfpathmoveto{\pgfqpoint{-\halfwidth}{0pt}}%
      \pgfpathlineto{\pgfqpoint{-\halfwidth}{\halfheight}}%
      \ifx\topbendstyle\pgf@lib@sh@inandouttext%
        \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}%
        \pgfpatharc{225}{315}{\bendxradius and \bendyradius}%
        \pgfpatharc{135}{45}{\bendxradius and \bendyradius}%
      \else%
        \ifx\topbendstyle\pgf@lib@sh@outandintext%
          \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}%
          \pgfpatharc{135}{45}{\bendxradius and \bendyradius}%
          \pgfpatharc{225}{315}{\bendxradius and \bendyradius}%
        \else%
          \pgfpathlineto{\pgfqpoint{\halfwidth}{\halfheight}}%
        \fi%
      \fi%
      \pgfpathlineto{\pgfqpoint{\halfwidth}{-\halfheight}}%
      \ifx\bottombendstyle\pgf@lib@sh@inandouttext%
        \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}%
        \pgfpatharc{45}{135}{\bendxradius and \bendyradius}%
        \pgfpatharc{315}{225}{\bendxradius and \bendyradius}%
      \else%
        \ifx\bottombendstyle\pgf@lib@sh@outandintext%
          \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}%
          \pgfpatharc{315}{225}{\bendxradius and \bendyradius}%
          \pgfpatharc{45}{135}{\bendxradius and \bendyradius}%
        \else%
          \pgfpathlineto{\pgfqpoint{-\halfwidth}{-\halfheight}}%
        \fi%
      \fi%
      \pgfpathclose%
    }%  
  }
  \anchorborder{%
    \pgf@xa\pgf@x%
    \pgf@ya\pgf@y%
    \pgfextract@process\externalpoint{%
      \centerpoint%
      \advance\pgf@x\pgf@xa%
      \advance\pgf@y\pgf@ya%
    }%
    \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
    \let\externalangle\pgfmathresult%
    \tapedimensions%
    %
    \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north west\endcsname}%
    \ifdim\externalangle pt<\pgfmathresult pt%
      \ifdim\externalangle pt<90pt%
        \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north east\endcsname}%
        \ifdim\externalangle pt<\pgfmathresult pt%
          \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
            {\csname pgf@anchor@tape@north east\endcsname}%
            {\csname pgf@anchor@tape@south east\endcsname}%
        \else%
          % Between north and north east.
          \ifx\topbendstyle\pgf@lib@sh@inandouttext%
            % in and out.
            \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
            {%
              \centerpoint%
              \pgf@xc\halfwidth%
              \advance\pgf@x.5\pgf@xc%
              \advance\pgf@y\halfheight%
              \advance\pgf@y\halfbendheight%
              \pgf@yc\bendyradius%
              \advance\pgf@y-.707106\pgf@yc%
            }%
            {5}{175}{\outerbendxradius and \outerbendyradius}%
          \else%
            \ifx\topbendstyle\pgf@lib@sh@outandintext%
              % out and in.
              \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
              {%
                \centerpoint%
                \pgf@xc\halfwidth%
                \advance\pgf@x.5\pgf@xc%
                \advance\pgf@y\halfheight%
                \advance\pgf@y\halfbendheight%
                \pgf@yc\bendyradius%
                \advance\pgf@y.707106\pgf@yc%
              }%
              {185}{355}{\innerbendxradius and \innerbendyradius}%
            \else%
              \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
                {\csname pgf@anchor@tape@north east\endcsname}%
                {\csname pgf@anchor@tape@north west\endcsname}%
            \fi%
          \fi%
        \fi%
      \else%
        % Between north and north west.
        \ifx\topbendstyle\pgf@lib@sh@inandouttext%
          % in and out.
          \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
            {%
              \centerpoint%
              \pgf@xc\halfwidth%
              \advance\pgf@x-.5\pgf@xc%
              \advance\pgf@y\halfheight%
              \advance\pgf@y\halfbendheight%
              \pgf@yc\bendyradius%
              \advance\pgf@y.707106\pgf@yc%
            }%
            {185}{355}{\innerbendxradius and \innerbendyradius}%
        \else%
          \ifx\topbendstyle\pgf@lib@sh@outandintext%
            % out and in.
            \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
            {%
              \centerpoint%
              \pgf@xc\halfwidth%
              \advance\pgf@x-.5\pgf@xc%
              \advance\pgf@y\halfheight%
              \advance\pgf@y\halfbendheight%
              \pgf@yc\bendyradius%
              \advance\pgf@y-.707106\pgf@yc%
            }%
            {5}{175}{\outerbendxradius and \outerbendyradius}%
          \else%
            \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
              {\csname pgf@anchor@tape@north east\endcsname}%
              {\csname pgf@anchor@tape@north west\endcsname}%
          \fi%
        \fi%
      \fi%
    \else%
      \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south west\endcsname}%
        \ifdim\externalangle pt>\pgfmathresult pt%
        \ifdim\externalangle pt>270pt%
          \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south east\endcsname}%
          \ifdim\externalangle pt>\pgfmathresult pt%
            \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
              {\csname pgf@anchor@tape@north east\endcsname}%
              {\csname pgf@anchor@tape@south east\endcsname}%
          \else%
            % Between south and south east.
            \ifx\bottombendstyle\pgf@lib@sh@inandouttext%
              % in and out.
              \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
              {%
                \centerpoint%
                \pgf@xc\halfwidth%
                \advance\pgf@x.5\pgf@xc%
                \advance\pgf@y-\halfheight%
                \advance\pgf@y-\halfbendheight%
                \pgf@yc\bendyradius%
                \advance\pgf@y-.707106\pgf@yc%
              }%
              {5}{175}{\innerbendxradius and \innerbendyradius}%
            \else%
              \ifx\bottombendstyle\pgf@lib@sh@outandintext%
                % out and in.
                \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
              {%
                \centerpoint%
                \pgf@xc\halfwidth%
                \advance\pgf@x.5\pgf@xc%
                \advance\pgf@y-\halfheight%
                \advance\pgf@y-\halfbendheight%
                \pgf@yc\bendyradius%
                \advance\pgf@y.707106\pgf@yc%
              }%
              {185}{355}{\outerbendxradius and \outerbendyradius}%
              \else%
                \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
                  {\csname pgf@anchor@tape@south east\endcsname}%
                  {\csname pgf@anchor@tape@south west\endcsname}%
              \fi%
            \fi%
          \fi%
        \else%
          % Between south and south west.
          \ifx\bottombendstyle\pgf@lib@sh@inandouttext%
            % in and out.
            \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
              {%
                \centerpoint%
                \pgf@xc\halfwidth%
                \advance\pgf@x-.5\pgf@xc%
                \advance\pgf@y-\halfheight%
                \advance\pgf@y-\halfbendheight%
                \pgf@yc\bendyradius%
                \advance\pgf@y.707106\pgf@yc%
              }%
              {185}{355}{\outerbendxradius and \outerbendyradius}%
          \else%
            \ifx\bottombendstyle\pgf@lib@sh@outandintext%
              % out and in.
              \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
              {%
                \centerpoint%
                \pgf@xc\halfwidth%
                \advance\pgf@x-.5\pgf@xc%
                \advance\pgf@y-\halfheight%
                \advance\pgf@y-\halfbendheight%
                \pgf@yc\bendyradius%
                \advance\pgf@y-.707106\pgf@yc%
              }%
              {5}{175}{\innerbendxradius and \innerbendyradius}%
            \else%
              \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
                {\csname pgf@anchor@tape@south east\endcsname}%
                {\csname pgf@anchor@tape@south west\endcsname}%
            \fi%
          \fi%
        \fi%
      \else%
        \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
          {\csname pgf@anchor@tape@north west\endcsname}%
          {\csname pgf@anchor@tape@south west\endcsname}%
      \fi%
    \fi%
  }%
}




% Keys for magnifying glass shape
%
% /pgf/magnifying glass handle angle  : The angle of handle
% /pgf/magnifying glass handle aspect : The length of the handle as a multiple
%                               of the radius of the circle
%

\pgfkeys{/pgf/.cd,
  magnifying glass handle angle/.initial=-45,
  magnifying glass handle aspect/.initial=1.5
}

\pgfdeclareshape{magnifying glass}
{
  \inheritsavedanchors[from=circle] % this is nearly a circle
  \inheritanchorborder[from=circle]
  \inheritanchor[from=circle]{north}
  \inheritanchor[from=circle]{north west}
  \inheritanchor[from=circle]{north east}
  \inheritanchor[from=circle]{center}
  \inheritanchor[from=circle]{west}
  \inheritanchor[from=circle]{east}
  \inheritanchor[from=circle]{mid}
  \inheritanchor[from=circle]{mid west}
  \inheritanchor[from=circle]{mid east}
  \inheritanchor[from=circle]{base}
  \inheritanchor[from=circle]{base west}
  \inheritanchor[from=circle]{base east}
  \inheritanchor[from=circle]{south}
  \inheritanchor[from=circle]{south west}
  \inheritanchor[from=circle]{south east}
  \inheritbackgroundpath[from=circle]
  \foregroundpath{
    \centerpoint%
    \pgf@xc=\pgf@x%
    \pgf@yc=\pgf@y%
    \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%
    \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}
      {\pgfpointpolar{\pgfkeysvalueof{/pgf/magnifying glass handle angle}}{\pgfutil@tempdima}}}
    \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}
      {\pgfpointpolar{\pgfkeysvalueof{/pgf/magnifying glass handle angle}}{\pgfutil@tempdima+\pgfutil@tempdima*(\pgfkeysvalueof{/pgf/magnifying glass handle aspect})}}}
    \pgfsetarrowsstart{}
    \pgfsetarrowsend{}
  }
}


\pgfkeys{%
  /pgf/magnetic tape tail/.initial=0.15,
  /pgf/magnetic tape tail extend/.initial=0cm,
}
\pgfdeclareshape{magnetic tape}{
  \nodeparts{text}
  \savedmacro\installparameters{%
    %
    \pgf@x=0.5\wd\pgfnodeparttextbox%
    \pgf@y=0.5\ht\pgfnodeparttextbox%
    \advance\pgf@y by-0.5\dp\pgfnodeparttextbox%
    \edef\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
    %
    \pgf@x=\wd\pgfnodeparttextbox%
    \pgf@y=\ht\pgfnodeparttextbox%
    \advance\pgf@y by\dp\pgfnodeparttextbox%
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
    \advance\pgf@x by2.0\pgf@xa%
    \advance\pgf@y by2.0\pgf@ya%
    \ifdim\pgf@y>\pgf@x%
      \pgf@x=\pgf@y%
    \fi%
    \pgf@x=1.414213\pgf@x%
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
    \ifdim\pgf@x<\pgf@xa%
      \pgf@x=\pgf@xa%
    \fi%
    \ifdim\pgf@x<\pgf@ya%
      \pgf@x=\pgf@ya%
    \fi%
    \pgf@x=0.5\pgf@x%
    \edef\radius{\the\pgf@x}%
    %
    \pgfmathparse{max(\pgfkeysvalueof{/pgf/magnetic tape tail extend},0)}%
    \edef\tailextend{\pgfmathresult pt}%
    %
    \pgfmathparse{min(max(\pgfkeysvalueof{/pgf/magnetic tape tail},0),1)}%    
    \pgf@xa=\pgfmathresult\pgf@x%    
    \edef\tailheight{\the\pgf@xa}%
    %
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
    \ifdim\pgf@xa<\pgf@ya%
      \pgf@xa=\pgf@ya%
    \fi%
    \edef\outersep{\the\pgf@xa}%
    %
    \pgfmathparse{\outersep+\radius}%
    \edef\outerradius{\pgfmathresult pt}%
    %
    \pgfmathparse{(\radius-\tailheight)/\radius}%
    \pgfmathasin@{\pgfmathresult}%
    \pgfmathadd@{-\pgfmathresult}{360}%
    \let\tailangle=\pgfmathresult%
    %
    \pgfmathparse{\outerradius/(\outerradius+\tailextend)}%
    \pgfmathatan@{\pgfmathresult}%
    \pgfmathadd@{-\pgfmathresult}{360}%
    \let\tailbottomangle=\pgfmathresult%
    %
    \pgfmathparse{(\outerradius-\outersep-\tailheight-\outersep)/(\outerradius+\tailextend)}%
    \pgfmathatan@{\pgfmathresult}%
    \pgfmathadd@{-\pgfmathresult}{360}%
    \let\tailtopangle=\pgfmathresult%
    %
    \addtosavedmacro\radius%
    \addtosavedmacro\outerradius%
    \addtosavedmacro\outersep%
    \addtosavedmacro\tailheight%
    \addtosavedmacro\tailextend
    \addtosavedmacro\tailangle%
    \addtosavedmacro\tailtopangle%
    \addtosavedmacro\tailbottomangle%
    \addtosavedmacro\centerpoint%
  }
  \savedanchor{\base}{\pgfqpoint{0.5\wd\pgfnodeparttextbox}{0pt}}
  \savedanchor{\mid}{\pgfqpoint{0.5\wd\pgfnodeparttextbox}{0pt}\pgfmathsetlength\pgf@y{.5ex}}
  \anchor{center}{\installparameters\centerpoint}%  \addtosavedmacro\outerradius%
  \anchor{base}{\base}
  \anchor{mid}{\mid}
  \anchor{base west}{\installparameters\pgfpointadd{\base}{\pgfqpoint{-\outerradius}{0pt}}}
  \anchor{base east}{\installparameters\pgfpointadd{\base}{\pgfqpoint{\outerradius}{0pt}}}
  \anchor{mid west}{\installparameters\pgfpointadd{\mid}{\pgfqpoint{-\outerradius}{0pt}}}
  \anchor{mid east}{\installparameters\pgfpointadd{\mid}{\pgfqpoint{\outerradius}{0pt}}}
  \anchor{north}{\installparameters%
    \pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{\outerradius}}}
  \anchor{north east}{\installparameters%
    \pgfpointadd{\centerpoint}{\pgfqpointpolar{45}{\outerradius}}}
  \anchor{south}{\installparameters%
    \pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{-\outerradius}}}
  \anchor{south east}{\installparameters%
    \pgfpointadd{\centerpoint}{\pgfqpoint{\outerradius}{-\outerradius}}}
  \anchor{east}{\installparameters%
      \pgfpointadd{\centerpoint}{\pgfqpoint{\outerradius}{0pt}}}
  \anchor{south west}{\installparameters%
    \pgfpointadd{\centerpoint}{\pgfqpointpolar{225}{\outerradius}}}
  \anchor{west}{\installparameters%
    \pgfpointadd{\centerpoint}{\pgfqpoint{-\outerradius}{0pt}}}
  \anchor{north west}{\installparameters%
      \pgfpointadd{\centerpoint}{\pgfqpointpolar{135}{\outerradius}}}    
  \anchor{tail east}{\installparameters%
        \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius+\outersep+\tailheight/2}}}  
  \anchor{tail south east}{\installparameters%
          \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius}}}    
  \anchor{tail north east}{\installparameters%
            \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius+\outersep+\tailheight+\outersep}}}        
  \backgroundpath{
  %
    \installparameters%
    {%
    \pgftransformshift{\centerpoint}%
    \pgfpathmoveto{\pgfpointpolar{\tailangle}{\radius}}%
    \pgfpatharc{\tailangle}{360}{\radius}%
    \pgfpatharc{0}{270}{\radius}%
    \pgfpathlineto{\pgfpoint{\radius+\tailextend}{-\radius}}%
    \pgfpathlineto{\pgfpoint{\radius+\tailextend}{-\radius+\tailheight}}%
    \pgfpathclose%
    }%
  }
  \anchorborder{%
    \pgfextract@process\externalpoint{}%
    \installparameters%
    \pgfmathanglebetweenpoints{\pgfpointorigin}{\externalpoint}
    \ifdim\pgfmathresult pt<270pt\relax%
      \pgfpointadd{\centerpoint}{%
        \pgfpointborderellipse%
          {\externalpoint}%
          {\pgfqpoint{\outerradius}{\outerradius}}%  
      }%
    \else%
      \ifdim\pgfmathresult pt<\tailbottomangle pt\relax%
        \pgfpointadd{\centerpoint}{%
          \pgfpointintersectionoflines%
            {\externalpoint}{\pgfpointorigin}%
            {\pgfqpoint{0pt}{-\outerradius}}{\pgfqpoint{\outerradius}{-\outerradius}}%  
        }%
      \else%
        \ifdim\pgfmathresult pt<\tailtopangle pt\relax%
          \pgfpointadd{\centerpoint}{%
            \pgfpointintersectionoflines%
              {\externalpoint}{\pgfpointorigin}%
              {\pgfqpoint{\outerradius}{\outerradius}}{\pgfqpoint{\outerradius}{-\outerradius}}%  
          }%
        \else%
          \pgfpointadd{\centerpoint}{%
            \pgfpointborderellipse%
              {\externalpoint}%
              {\pgfqpoint{\outerradius}{\outerradius}}%  
            }%
        \fi%
      \fi%
    \fi%
  }
}

% Local Variables:
% tab-width: 2
% End: