Current File : //usr/share/texlive/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex |
% Copyright 2018 by Mark Wibrow
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Public License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.
\usepgflibrary{shapes.symbols}%
% Keys for callouts
%
% Common to all callouts:
% /pgf/callout absolute pointer
% /pgf/callout relative pointer
%
% ellipse callout only:
% /pgf/callout pointer arc
%
% rectangle callout only:
% /pgf/callout pointer width
%
% cloud callout only:
% /pgf/callout pointer start size
% /pgf/callout pointer end size
% /pgf/callout pointer segments
%
\newif\ifpgf@lib@callout@absolutepointer
\pgfkeys{/pgf/.cd,
callout pointer arc/.initial=15,
callout pointer width/.initial=.25cm,
callout pointer start size/.initial=.2 of callout,
callout pointer end size/.initial=.1 of callout,
callout pointer segments/.initial=2,
callout absolute pointer/.code={\pgf@lib@callout@makeabsolutepointer{#1}},
callout relative pointer/.code={\pgf@lib@callout@makerelativepointer{#1}},
callout pointer shorten/.initial=0cm,
}%
\def\pgf@lib@callout@makeabsolutepointer#1{%
\pgf@lib@callout@absolutepointertrue%
{%
\pgftransformshift{#1}%
\pgfmultipartnode{coordinate}{center}{pgf@lib@callout@pointer}{}%
}%
}%
\def\pgf@lib@callout@makerelativepointer#1{%
\pgf@lib@callout@absolutepointerfalse%
\def\pgf@lib@callout@relativepointer{#1}%
}%
\pgfkeys{/pgf/callout relative pointer=\pgfpointpolar{300}{.5cm}}%
% Shape ellipse callout
%
%
\pgfdeclareshape{ellipse callout}{%
\savedmacro\ellipsecalloutpoints{%
%
% 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%
\edef\outersep{\the\pgf@x}%
\else%
\edef\outersep{\the\pgf@y}%
\fi%
\addtosavedmacro\outersep%
%
% Calculate the node dimensions...
%
\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
\advance\pgf@x.5\wd\pgfnodeparttextbox%
\pgf@x1.4142136\pgf@x%
\pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
\ifdim\pgf@x<.5\pgf@xa%
\pgf@x.5\pgf@xa%
\fi%
%
\pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
\advance\pgf@y.5\ht\pgfnodeparttextbox%
\advance\pgf@y.5\dp\pgfnodeparttextbox%
\pgf@y1.4142136\pgf@y%
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
\ifdim\pgf@y<.5\pgf@ya%
\pgf@y.5\pgf@ya%
\fi%
%
% ...without outer sep...
%
\edef\xpathradius{\the\pgf@x}%
\edef\ypathradius{\the\pgf@y}%
%
% ...and width outer sep.
%
\pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
\edef\xradius{\the\pgf@x}%
\pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
\edef\yradius{\the\pgf@y}%
%
\addtosavedmacro\xradius%
\addtosavedmacro\xpathradius%
\addtosavedmacro\yradius%
\addtosavedmacro\ypathradius%
%
\pgfmathsetmacro\pointerarc{\pgfkeysvalueof{/pgf/callout pointer arc}}%
\addtosavedmacro\pointerarc%
%
\pgfextract@process\centerpoint{%
\pgf@x.5\wd\pgfnodeparttextbox%
\pgf@y.5\ht\pgfnodeparttextbox%
\advance\pgf@y-.5\dp\pgfnodeparttextbox%
}%
%
% Get the relative pointer.
%
\ifpgf@lib@callout@absolutepointer%
\else%
\pgfextract@process\calloutpointer{%
\pgfextract@process\borderpoint{%
\expandafter\pgfpointborderellipse\expandafter{\pgf@lib@callout@relativepointer}{\pgfqpoint{\xpathradius}{\ypathradius}}%
}%
\pgfmathanglebetweenpoints{\pgfpointorigin}{\borderpoint}%
\let\pointerangle\pgfmathresult%
\expandafter\pgf@process\expandafter{\pgf@lib@callout@relativepointer}%
\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
\edef\pointerradius{\pgfmathresult pt}%
\pgfpointadd{\borderpoint}{\pgfqpointpolar{\pointerangle}{\pointerradius}}%
\pgf@xa\pgf@x%
\pgf@ya\pgf@y%
\centerpoint%
\advance\pgf@x\pgf@xa%
\advance\pgf@y\pgf@ya%
}%
%
\addtosavedmacro\calloutpointer%
\pgf@lib@callouts@shortenpointer%
\pgf@lib@ellipsecallout@getpoints%
\addtosavedmacro\calloutpointeranchor%
\addtosavedmacro\beforecalloutangle%
\addtosavedmacro\aftercalloutangle%
\fi%
}%
\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\relax%
}%
\anchor{center}{\centerpoint}%
\anchor{mid}{\midpoint}%
\anchor{mid east}{%
\ellipsecalloutpoints%
\pgfmathpointintersectionoflineandarc{\midpoint\advance\pgf@x\xradius}{\midpoint}%
{\centerpoint}{270}{450}{\xradius and \yradius}%
}%
\anchor{mid west}{%
\ellipsecalloutpoints%
\pgfmathpointintersectionoflineandarc{\midpoint\advance\pgf@x-\xradius}{\midpoint}%
{\centerpoint}{90}{270}{\xradius and \yradius}%
}%
\anchor{base}{\basepoint}%
\anchor{base east}{%
\ellipsecalloutpoints%
\pgfmathpointintersectionoflineandarc{\basepoint\advance\pgf@x\xradius}{\basepoint}%
{\centerpoint}{270}{450}{\xradius and \yradius}%
}%
\anchor{base west}{%
\ellipsecalloutpoints%
\pgfmathpointintersectionoflineandarc{\basepoint\advance\pgf@x-\xradius}{\basepoint}%
{\centerpoint}{90}{270}{\xradius and \yradius}%
}%
\anchor{north}{%
\ellipsecalloutpoints%
\centerpoint%
\advance\pgf@y\yradius\relax%
}%
\anchor{south}{%
\ellipsecalloutpoints%
\centerpoint%
\advance\pgf@y-\yradius\relax%
}%
\anchor{east}{%
\ellipsecalloutpoints%
\centerpoint%
\advance\pgf@x\xradius\relax%
}%
\anchor{west}{%
\ellipsecalloutpoints%
\centerpoint%
\advance\pgf@x-\xradius\relax%
}%
\anchor{north west}{%
\ellipsecalloutpoints%
\pgf@xa\xradius\relax%
\pgf@ya\yradius\relax%
\centerpoint%
\advance\pgf@y0.7071067\pgf@ya%
\advance\pgf@x-0.7071067\pgf@xa%
}%
\anchor{north east}{%
\ellipsecalloutpoints%
\pgf@xa\xradius\relax%
\pgf@ya\yradius\relax%
\centerpoint%
\advance\pgf@y0.7071067\pgf@ya%
\advance\pgf@x0.7071067\pgf@xa%
}%
\anchor{south west}{%
\ellipsecalloutpoints%
\pgf@xa\xradius\relax%
\pgf@ya\yradius\relax%
\centerpoint%
\advance\pgf@y-0.7071067\pgf@ya%
\advance\pgf@x-0.7071067\pgf@xa%
}%
\anchor{south east}{%
\ellipsecalloutpoints%
\pgf@xa\xradius\relax%
\pgf@ya\yradius\relax%
\centerpoint%
\advance\pgf@y-0.7071067\pgf@ya%
\advance\pgf@x0.7071067\pgf@xa%
}%
\anchor{pointer}{%
\ellipsecalloutpoints%
\calloutpointeranchor%
}%
\backgroundpath{%
\ellipsecalloutpoints%
\ifpgf@lib@callout@absolutepointer%
\pgfextract@process\calloutpointer{%
\pgfpointanchor{pgf@lib@callout@pointer}{center}%
}%
\pgf@lib@callouts@shortenpointer%
\pgf@lib@ellipsecallout@getpoints%
\calloutpointeranchor%
\ifx\pgf@node@name\pgfutil@empty%
\else%
\edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}%
\edef\pgf@sh@@@temp{%
\noexpand\def\noexpand\calloutpointeranchor{%
\noexpand\pgf@x\the\pgf@x%
\noexpand\pgf@y\the\pgf@y%
}%
}%
\expandafter\pgf@sh@@temp\expandafter{\pgf@sh@@@temp}
\fi%
\fi%
\pgfpathmoveto{\calloutpointer}%
\pgfpathlineto{\aftercalloutpointer}%
\ifdim\aftercalloutangle pt<\beforecalloutangle pt\relax%
\pgfpatharc{\aftercalloutangle}{\beforecalloutangle}{\xpathradius and \ypathradius}%
\else%
\pgfpatharc{\aftercalloutangle}{360}{\xpathradius and \ypathradius}%
\pgfpatharc{0}{\beforecalloutangle}{\xpathradius and \ypathradius}%
\fi%
\pgfpathclose%
}%
\anchorborder{%
\pgfextract@process\externalpoint{}%
\ellipsecalloutpoints%
\pgfpointadd{\pgfpointborderellipse{\externalpoint}{\pgfpoint{\xradius}{\yradius}}%
}{\centerpoint}%
}%
}%
% Internal macro for calculating the points for the
% ellipse callout pointer.
%
% The following must be set up:
%
% \centerpoint - the center of the ellipse.
% \calloutpointer - the location of the callout point.
% \pointerarc - the width of the pointer.
% \xpathradius - the x radius of the ellipse.
% \ypathradius - the y radius of the ellipse.
%
\def\pgf@lib@ellipsecallout@getpoints{%
\pgfextract@process\borderpoint{%
\pgfpointborderellipse{%
\centerpoint%
\pgf@xa\pgf@x%
\pgf@ya\pgf@y%
\calloutpointer%
\advance\pgf@x-\pgf@xa%
\advance\pgf@y-\pgf@ya%
}{\pgfqpoint{\xpathradius}{\ypathradius}}%
}%
\pgfmathangleonellipse{\borderpoint}{\xpathradius and \ypathradius}%
\pgfutil@tempdima\pointerarc pt\relax%
\pgfutil@tempdimb\pgfmathresult pt\relax%
\advance\pgfutil@tempdimb-.5\pgfutil@tempdima%
\ifdim\pgfutil@tempdimb<0pt\relax%
\advance\pgfutil@tempdimb360pt\relax%
\fi%
\edef\beforecalloutangle{\pgfmath@tonumber{\pgfutil@tempdimb}}%
\advance\pgfutil@tempdimb\pgfutil@tempdima%
\ifdim\pgfutil@tempdimb<360pt\relax%
\else%
\advance\pgfutil@tempdimb-360pt\relax%
\fi%
\edef\aftercalloutangle{\pgfmath@tonumber{\pgfutil@tempdimb}}%
%
\pgfextract@process\beforecalloutpointer{%
\pgfpointadd{\centerpoint}{%
\pgfpointpolar{\beforecalloutangle}{\xpathradius and \ypathradius}%
}%
}%
\pgfextract@process\aftercalloutpointer{%
\pgfpointadd{\centerpoint}{%
\pgfpointpolar{\aftercalloutangle}{\xpathradius and \ypathradius}%
}%
}%
%
% Calculate the pointer anchor.
%
\pgf@lib@callouts@pointeranchor%
}%
% If the callout pointer is very pointed and stroked, the anchor will be
% miles away from the end of the pointer which will (typically) be
% bevelled.
% Using outer sep=0pt is one solution, however, another is provided
% using this special key:
%
% /pgf/callout pointer anchor aspect
%
% which takes a value from 0 (ignore any outer sep) to 1 (use
% the full outer sep).
\pgfkeys{/pgf/callout pointer anchor aspect/.initial=1}%
% Internal macro for calculating the anchor for the callout pointer.
%
% Requires the following to be set up (points are anti-clockwise)
%
% \beforecalloutpointer - point on the border before the callout pointer
% \calloutpointer
% \aftercalloutpointer - point on the border after the callout pointer
% \outersep - the largest of the outer xsep or ysep.
%
\def\pgf@lib@callouts@pointeranchor{%
\pgfutil@tempdimb\outersep\relax%
%
\pgfmathanglebetweenlines{\calloutpointer}{\aftercalloutpointer}{\calloutpointer}{\beforecalloutpointer}%
\pgfmathdivide@{\pgfmathresult}{2}%
\pgfutil@tempdima\pgfmathresult pt\relax%
\pgfmathcosec@{\pgfmathresult}%
\pgfutil@tempdimb\pgfmathresult\pgfutil@tempdimb%
\pgfmathanglebetweenpoints{\calloutpointer}{\aftercalloutpointer}%
\advance\pgfutil@tempdima\pgfmathresult pt\relax%
\advance\pgfutil@tempdima180pt\relax%
%
\pgfextract@process\calloutpointeranchor{%
\pgfpointadd{%
\pgfmathparse{\pgfkeysvalueof{/pgf/callout pointer anchor aspect}}%
\pgfutil@tempdimb\pgfmathresult\pgfutil@tempdimb%
\pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
}{%
\calloutpointer%
}%
}%
}%
\def\pgf@lib@callouts@shortenpointer{%
\pgfextract@process\calloutpointer{%
\pgfmathanglebetweenpoints{\calloutpointer}{\centerpoint}%
\let\angle\pgfmathresult%
\pgfmathsin@{\angle}%
\let\sinpointerangle\pgfmathresult%
\pgfmathcos@{\angle}%
\let\cospointerangle\pgfmathresult%
\pgfpointadd{\calloutpointer}{%
\pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/callout pointer shorten}}%
\pgf@x\cospointerangle\pgfutil@tempdima%
\pgf@y\sinpointerangle\pgfutil@tempdima%
}%
}%
}%
\pgfdeclareshape{rectangle callout}{%
\savedmacro\rectanglecalloutpoints{%
%
\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
\advance\pgf@x.5\wd\pgfnodeparttextbox%
\pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
\ifdim\pgf@x<.5\pgf@xa%
\pgf@x.5\pgf@xa%
\fi%
\edef\xtemp{\the\pgf@x}%
\pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
%
\pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
\advance\pgf@y.5\ht\pgfnodeparttextbox%
\advance\pgf@y.5\dp\pgfnodeparttextbox%
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
\ifdim\pgf@y<.5\pgf@ya%
\pgf@y.5\pgf@ya%
\fi%
\edef\ytemp{\the\pgf@y}%
\pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
%
\edef\xlength{\the\pgf@x}%
\edef\ylength{\the\pgf@y}%
\addtosavedmacro\xlength%
\addtosavedmacro\ylength%
%
\pgfmathsetlengthmacro\pointerwidth{\pgfkeysvalueof{/pgf/callout pointer width}}%
\addtosavedmacro\pointerwidth%
%
\pgfextract@process\centerpoint{%
\pgf@x.5\wd\pgfnodeparttextbox%
\pgf@y.5\ht\pgfnodeparttextbox%
\advance\pgf@y-.5\dp\pgfnodeparttextbox%
}%
%
% Process the relative callout pointer.
%
\ifpgf@lib@callout@absolutepointer%
\else%
\pgfextract@process\calloutpointer{%
\pgfextract@process\borderpoint{%
\expandafter\pgfpointborderrectangle\expandafter{\pgf@lib@callout@relativepointer}%
{\pgfqpoint{\xtemp}{\ytemp}}%
}%
\pgfmathanglebetweenpoints{\pgfpointorigin}{\borderpoint}%
\let\pointerangle\pgfmathresult%
\expandafter\pgf@process\expandafter{\pgf@lib@callout@relativepointer}%
\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
\edef\pointerradius{\pgfmathresult pt}%
\pgfpointadd{\borderpoint}{\pgfqpointpolar{\pointerangle}{\pointerradius}}%
\pgf@xa\pgf@x%
\pgf@ya\pgf@y%
\centerpoint%
\advance\pgf@x\pgf@xa%
\advance\pgf@y\pgf@ya%
}%
\pgf@lib@callouts@shortenpointer%
\addtosavedmacro\calloutpointer%
\pgf@lib@rectanglecallout@pointer%
\addtosavedmacro\calloutpointeranchor%
\addtosavedmacro\beforecalloutpointer%
\addtosavedmacro\aftercalloutpointer%
\addtosavedmacro\firstpoint%
\addtosavedmacro\secondpoint%
\addtosavedmacro\thirdpoint%
\addtosavedmacro\fourthpoint%
\fi%
}%
\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\relax%
}%
\savedanchor\midpoint{%
\pgf@x.5\wd\pgfnodeparttextbox%
\pgfmathsetlength\pgf@y{+.5em}%
}%
\anchor{center}{\centerpoint}%
\anchor{mid}{\midpoint}%
\anchor{mid east}{%
\rectanglecalloutpoints%
\midpoint%
\advance\pgf@x\xlength\relax%
}%
\anchor{mid west}{%
\rectanglecalloutpoints%
\midpoint%
\advance\pgf@x-\xlength\relax%
}%
\anchor{base}{\basepoint}%
\anchor{base east}{%
\rectanglecalloutpoints%
\basepoint%
\advance\pgf@x\xlength\relax%
}%
\anchor{base west}{%
\rectanglecalloutpoints%
\basepoint%
\advance\pgf@x-\xlength\relax%
}%
\anchor{north}{%
\rectanglecalloutpoints%
\centerpoint%
\advance\pgf@y\ylength\relax%
}%
\anchor{south}{%
\rectanglecalloutpoints%
\centerpoint%
\advance\pgf@y-\ylength\relax%
}%
\anchor{east}{%
\rectanglecalloutpoints%
\centerpoint%
\advance\pgf@x\xlength\relax%
}%
\anchor{west}{%
\rectanglecalloutpoints%
\centerpoint%
\advance\pgf@x-\xlength\relax%
}%
\anchor{north east}{%
\rectanglecalloutpoints%
\centerpoint%
\advance\pgf@x\xlength\relax%
\advance\pgf@y\ylength\relax%
}%
\anchor{south west}{%
\rectanglecalloutpoints%
\centerpoint%
\advance\pgf@x-\xlength\relax%
\advance\pgf@y-\ylength\relax%
}%
\anchor{south east}{%
\rectanglecalloutpoints%
\centerpoint%
\advance\pgf@x\xlength\relax%
\advance\pgf@y-\ylength\relax%
}%
\anchor{north west}{%
\rectanglecalloutpoints%
\centerpoint%
\advance\pgf@x-\xlength\relax%
\advance\pgf@y\ylength\relax%
}%
\anchor{pointer}{%
\rectanglecalloutpoints%
\calloutpointeranchor%
}%
\backgroundpath{%
\rectanglecalloutpoints%
\pgf@x\xlength\relax%
\pgf@y\ylength\relax%
\pgfmathaddtolength\pgf@x{-\pgfkeysvalueof{/pgf/outer xsep}}%
\pgfmathaddtolength\pgf@y{-\pgfkeysvalueof{/pgf/outer ysep}}%
\edef\xtemp{\the\pgf@x}%
\edef\ytemp{\the\pgf@y}%
%
% The absolute pointer must be calculated here because the
% anchor of the shape (which is calculated after the saved
% macros and points) affects how the pointer joins the
% main rectangle.
%
\ifpgf@lib@callout@absolutepointer%
\pgfextract@process\calloutpointer{%
\pgfpointanchor{pgf@lib@callout@pointer}{center}%
}%
\pgf@lib@callouts@shortenpointer%
\pgfmathsetlengthmacro\pointerwidth{\pgfkeysvalueof{/pgf/callout pointer width}}%
\pgf@lib@rectanglecallout@pointer%
%
% \pgf@node@name = the shape name (from \pgfmultipartnode)
%
\ifx\pgf@node@name\pgfutil@empty%
\else%
%
% Now hack an extra saved anchor \calloutpointeranchor,
% with the new anchor for the callout pointer.
%
\edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}%
\edef\pgf@sh@@@temp{%
\noexpand\def\noexpand\calloutpointeranchor{%
\noexpand\pgf@x\the\pgf@x%
\noexpand\pgf@y\the\pgf@y%
}%
}%
\expandafter\pgf@sh@@temp\expandafter{\pgf@sh@@@temp}%
\fi%
\fi%
{%
\pgfsetcornersarced{\pgfqpoint{0pt}{0pt}}%
\pgfpathmoveto{\beforecalloutpointer}%
}%
\pgfpathlineto{\calloutpointer}%
{%
\pgfsetcornersarced{\pgfqpoint{0pt}{0pt}}%
\pgfpathlineto{\aftercalloutpointer}%
}%
{%
\pgftransformshift{\centerpoint}%
\pgfpathlineto{\firstpoint}%
\pgfpathlineto{\secondpoint}%
\pgfpathlineto{\thirdpoint}%
\pgfpathlineto{\fourthpoint}%
{%
\pgfsetcornersarced{\pgfqpoint{0pt}{0pt}}%
\pgfpathclose%
}%
}
}%
\anchorborder{%
\pgfextract@process\externalpoint{}%
\rectanglecalloutpoints%
\pgfpointadd{\centerpoint}%
{%
\pgfpointborderrectangle{\pgfpointadd{\centerpoint}{\externalpoint}}%
{\pgfqpoint{\xlength}{\ylength}}%
}%
}%
}%
% \pgf@lib@rectanglecallout@pointer
%
% Internal macro for calculations relating to the rectangle callout.
%
% Requires the following to be set up:
%
% \calloutpointer - the location of the callout point.
% \xtemp - the half width of the rectangle
% \ytemp - the half height of the rectangle
% \pointerwidth - the width of the pointer.
%
\def\pgf@lib@rectanglecallout@pointer{%
%
% Ensure that the pointer never connects to the main shape
% too near to a corner. This is done for two reasons:
% 1. It can look ugly.
% 2. If the corners are rounded, a mess can result.
%
\pgfextract@process\borderpoint{%
\pgfpointborderrectangle{%
\centerpoint%
\pgf@xa\pgf@x%
\pgf@ya\pgf@y%
\calloutpointer%
\advance\pgf@x-\pgf@xa%
\advance\pgf@y-\pgf@ya%
}{\pgfqpoint{\xtemp}{\ytemp}}%
}%
\pgfmathanglebetweenpoints{\pgfpointorigin}{\borderpoint}%
\let\borderangle\pgfmathresult%
%
\pgfutil@tempdima\pointerwidth\relax%
\pgf@xa\xtemp\relax%
\advance\pgf@xa-\pgfutil@tempdima%
\pgf@ya\ytemp\relax%
\advance\pgf@ya-\pgfutil@tempdima%
%
\pgf@process{%
\pgfutil@ifundefined{pgf@corner@arc}{\pgfpointorigin}{%
\expandafter\pgfqpoint\pgf@corner@arc}%
}%
\advance\pgf@xa-\pgf@x%
\advance\pgf@ya-\pgf@y%
%
\borderpoint%
\pgf@xb\pgf@x%
\pgf@yb\pgf@y%
%
\pgf@xc0pt\relax%
\pgf@yc0pt\relax%
%
\pgfmathanglebetweenpoints{\pgfpointorigin}{\pgfqpoint{\xtemp}{\ytemp}}%
\ifdim\borderangle pt<\pgfmathresult pt\relax%
\pgf@yc.5\pgfutil@tempdima%
\ifdim\pgf@yb>\pgf@ya%
\pgf@yb\pgf@ya%
\fi%
%
% Establish the order for drawing the rectangle corners.
%
\edef\firstpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
\edef\secondpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
\edef\thirdpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
\edef\fourthpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
\else%
\pgfmathanglebetweenpoints{\pgfpointorigin}{\pgfqpoint{-\xtemp}{\ytemp}}%
\ifdim\borderangle pt<\pgfmathresult pt\relax%
\pgf@xc-.5\pgfutil@tempdima%
\ifdim\pgf@xb>\pgf@xa%
\pgf@xb\pgf@xa%
\else%
\ifdim\pgf@xb<-\pgf@xa%
\pgf@xb-\pgf@xa%
\fi%
\fi%
\edef\firstpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
\edef\secondpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
\edef\thirdpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
\edef\fourthpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
\else%
\pgfmathanglebetweenpoints{\pgfpointorigin}{\pgfqpoint{-\xtemp}{-\ytemp}}%
\ifdim\borderangle pt<\pgfmathresult pt\relax%
\pgf@yc-.5\pgfutil@tempdima%
\ifdim\pgf@yb>\pgf@ya%
\pgf@yb\pgf@ya%
\else%
\ifdim\pgf@yb<-\pgf@ya%
\pgf@yb-\pgf@ya%
\fi%
\fi%
\edef\firstpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
\edef\secondpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
\edef\thirdpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
\edef\fourthpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
\else%
\pgfmathanglebetweenpoints{\pgfpointorigin}{\pgfqpoint{\xtemp}{-\ytemp}}%
\ifdim\borderangle pt<\pgfmathresult pt\relax%
\pgf@xc.5\pgfutil@tempdima%
\ifdim\pgf@xb>\pgf@xa%
\pgf@xb\pgf@xa%
\else%
\ifdim\pgf@xb<-\pgf@xa%
\pgf@xb-\pgf@xa%
\fi%
\fi%
\edef\firstpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
\edef\secondpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
\edef\thirdpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
\edef\fourthpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
\else%
\pgf@yc.5\pgfutil@tempdima%
\ifdim\pgf@yb<-\pgf@ya%
\pgf@yb-\pgf@ya%
\fi%
\edef\firstpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
\edef\secondpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
\edef\thirdpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
\edef\fourthpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
\fi%
\fi%
\fi%
\fi%
\pgfextract@process\beforecalloutpointer{%
\centerpoint%
\advance\pgf@x\pgf@xb%
\advance\pgf@y\pgf@yb%
\advance\pgf@x-\pgf@xc%
\advance\pgf@y-\pgf@yc%
}%
\pgfextract@process\aftercalloutpointer{%
\centerpoint%
\advance\pgf@x\pgf@xb%
\advance\pgf@y\pgf@yb%
\advance\pgf@x\pgf@xc%
\advance\pgf@y\pgf@yc%
}%
%
% Now calculate the pointer anchor.
%
\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
\pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
\ifdim\pgf@x>\pgf@y%
\edef\outersep{\the\pgf@x}%
\else%
\edef\outersep{\the\pgf@y}%
\fi%
\pgf@lib@callouts@pointeranchor%
}%
% Internal macro for parsing the size of
% the cloud callout pointer.
%
% \pgf@x and \pgf@y should be set up as the
% width and height of the main shape.
%
% \pgf@xa and \pgf@ya are returned appropriately.
%
\def\pgf@lib@callout@setpointersize#1{%
\edef\pgf@lib@callout@temp{#1}%
\edef\pgf@marshall{\noexpand\pgfutil@in@{of callout}{\pgf@lib@callout@temp}}%
\pgf@marshall%
\ifpgfutil@in@%
\expandafter\pgf@xa\expandafter\pgf@lib@callout@setpointerrelativesize%
\pgf@lib@callout@temp\pgf@lib@stop\pgf@x%
\expandafter\pgf@ya\expandafter\pgf@lib@callout@setpointerrelativesize%
\pgf@lib@callout@temp\pgf@lib@stop\pgf@y%
\else%
\edef\pgf@marshall{\noexpand\pgfutil@in@{and}{\pgf@lib@callout@temp}}%
\pgf@marshall%
\ifpgfutil@in@%
\expandafter\pgf@lib@callout@setpointerbothsizes\pgf@lib@callout@temp\pgf@lib@stop%
\else%
\pgfmathsetlength\pgf@xa{#1}%
\pgfmathsetlength\pgf@ya{#1}%
\fi%
\fi%
}%
\def\pgf@lib@callout@setpointerrelativesize#1of callout#2\pgf@lib@stop{#1}%
\def\pgf@lib@callout@setpointerbothsizes#1and#2\pgf@lib@stop{%
\pgfmathsetlength\pgf@xa{#2}%
\pgfmathsetlength\pgf@ya{#2}%
}%
% Shape: cloud callout.
%
\pgfdeclareshape{cloud callout}{%
\savedanchor\calloutpointer{%
\pgfutil@ifundefined{pgf@sh@s@cloud}{%
\pgferror{I cannot find the cloud shape. Please load the `symbol shapes' library}}{}%
\pgf@sh@s@cloud%
\pgf@sh@savedmacros%
%
\pgfextract@process\centerpoint{%
\pgf@x.5\wd\pgfnodeparttextbox%
\pgf@y.5\ht\pgfnodeparttextbox%
\advance\pgf@y-.5\dp\pgfnodeparttextbox%
}%
\ifpgf@lib@callout@absolutepointer%
\else%
\pgfextract@process\calloutpointer{%
\pgfextract@process\borderpoint{%
\expandafter\pgfpointborderellipse\expandafter{\pgf@lib@callout@relativepointer}%
{\pgfqpoint{\xouterradius}{\youterradius}}%
}%
\pgfmathanglebetweenpoints{\pgfpointorigin}{\borderpoint}%
\let\pointerangle\pgfmathresult%
\expandafter\pgf@process\expandafter{\pgf@lib@callout@relativepointer}%
\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
\edef\pointerradius{\pgfmathresult pt}%
\pgfpointadd{\borderpoint}{\pgfqpointpolar{\pointerangle}{\pointerradius}}%
\pgf@xa\pgf@x%
\pgf@ya\pgf@y%
\centerpoint%
\advance\pgf@x\pgf@xa%
\advance\pgf@y\pgf@ya%
}%
\pgf@lib@callouts@shortenpointer%
\fi%
}%
\anchor{pointer}{%
\calloutpointer%
}%
\inheritsavedanchors[from=cloud]%
\inheritanchor[from=cloud]{center}%
\inheritanchor[from=cloud]{base}%
\inheritanchor[from=cloud]{mid}%
\inheritanchor[from=cloud]{north}%
\inheritanchor[from=cloud]{south}%
\inheritanchor[from=cloud]{east}%
\inheritanchor[from=cloud]{west}%
\inheritanchor[from=cloud]{north east}%
\inheritanchor[from=cloud]{south west}%
\inheritanchor[from=cloud]{south east}%
\inheritanchor[from=cloud]{north west}%
\inheritanchorborder[from=cloud]%
\backgroundpath{%
\pgf@sh@bg@cloud%
\ifpgf@lib@callout@absolutepointer%
\pgfextract@process\calloutpointer{%
\pgfpointanchor{pgf@lib@callout@pointer}{center}%
}%
\ifx\pgf@node@name\pgfutil@empty%
\else%
\edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}%
\edef\pgf@sh@@@temp{%
\noexpand\def\noexpand\calloutpointeranchor{%
\noexpand\pgf@x\the\pgf@x%
\noexpand\pgf@y\the\pgf@y%
}%
}%
\expandafter\pgf@sh@@temp\expandafter{\pgf@sh@@@temp}
\fi%
\fi%
%
\pgfextract@process\borderpoint{%
\pgfpointadd{%
\pgfpointborderellipse{\pgfpointdiff{\centerpoint}{\calloutpointer}}%
{\pgfqpoint{\xouterradius}{\youterradius}}%
}{\centerpoint}%
}%
\pgf@lib@callouts@shortenpointer%
\pgfmathanglebetweenpoints{\calloutpointer}{\centerpoint}%
\let\angle\pgfmathresult%
\pgfmathsin@{\angle}%
\let\sinpointerangle\pgfmathresult%
\pgfmathcos@{\angle}%
\let\cospointerangle\pgfmathresult%
%
\pgf@x\xouterradius\relax%
\pgf@x2.0\pgf@x%
\pgf@y\yinnerradius\relax%
\pgf@y2.0\pgf@y%
\pgf@lib@callout@setpointersize{\pgfkeysvalueof{/pgf/callout pointer start size}}%
\pgf@xb\pgf@xa%
\pgf@yb\pgf@ya%
\pgf@lib@callout@setpointersize{\pgfkeysvalueof{/pgf/callout pointer end size}}%
\advance\pgf@xb-\pgf@xa%
\advance\pgf@yb-\pgf@ya%
%
\pgfmathsetcount\c@pgf@counta{\pgfkeysvalueof{/pgf/callout pointer segments}}%
\divide\pgf@xb\c@pgf@counta%
\divide\pgf@yb\c@pgf@counta%
%
\pgf@process{\pgfpointdiff{\borderpoint}{\calloutpointer}}%
\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
\pgfutil@tempdima\pgfmathresult pt\relax%
\divide\pgfutil@tempdima\c@pgf@counta%
%
\pgfutil@tempdimb0pt\relax%
\pgfmathloop%
\ifnum\pgfmathcounter>\c@pgf@counta%
\else%
{%
\pgf@xa.5\pgf@xa%
\pgf@ya.5\pgf@ya%
\edef\tempxradius{\the\pgf@xa}%
\edef\tempyradius{\the\pgf@ya}%
\pgfpathellipse%
{%
\calloutpointer%
\advance\pgf@x\cospointerangle\pgfutil@tempdimb%
\advance\pgf@y\sinpointerangle\pgfutil@tempdimb%
}%
{\pgfqpoint{\tempxradius}{0pt}}{\pgfqpoint{0pt}{\tempyradius}}%
}%
\advance\pgf@xa\pgf@xb%
\advance\pgf@ya\pgf@yb%
\advance\pgfutil@tempdimb\pgfutil@tempdima%
\repeatpgfmathloop%
}%
%
% Hack the puff anchors for the callout.
%
\expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@cloud callout\endcsname{%
\c@pgf@counta\puffs\relax%
\pgfmathloop%
\ifnum\c@pgf@counta>0\relax%
\pgfutil@ifundefined{pgf@anchor@cloud callout@puff\space\the\c@pgf@counta}{%
\expandafter\xdef\csname pgf@anchor@cloud callout@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%
}%
}%
\endinput