% \iffalse meta-comment
%
% makeshape.dtx
% 25 January 2013
%
% This is version 1.0 of makeshape.dtx
% It generates a style file (makeshape.sty), a sample shape (sampleshape.tex),
% and a user guide and documentation (makeshape.pdf).
%
% Generation of the makeshape.sty and sampleshape.tex is with
% pdflatex makeshape.ins
% which contains
% \generate{\file{makeshape.sty}
% {\from{makeshape.dtx}{package}}}
% \generate{\file{sampleshape.tex}
% {\from{makeshape.dtx}{sample}}}
%
% Generation of makeshape.pdf is with
% pdflatex makeshape.dtx
%
% The \OnlyDescription command is used to suppress implementation
% documentation.
%
% This is part of Silhouette 2.1
%
% -----------------------------------------------------------
% \fi
%
%^^A-------------------------------------------------------------------
%^^A .sty file header
%^^A-------------------------------------------------------------------
% \iffalse
%<package>\NeedsTeXFormat{LaTeX2e}[2011/06/27]
%^^A - ** Use package version number (not file version) **
%<package>\ProvidesPackage{makeshape}
%<package> [2013/01/25 2.1 Making custom shapes for PGF/TikZ]
%<package>\RequirePackage{tikz}
%<package>\usepgflibrary{intersections}
%
%^^A-------------------------------------------------------------------
%^^A Preamble for documentation
%^^A-------------------------------------------------------------------
%<*driver>
\documentclass[10pt,a4paper]{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{fancyvrb}
\usepackage{enumitem}
\usepackage{url}
\usepackage{bigstrut}
\usepackage[draft]{hyperref}
%\usepackage{hyperref}
\usepackage{tikz}
\usetikzlibrary{patterns}
\usetikzlibrary{arrows}
\usetikzlibrary{positioning}
\usepgflibrary{intersections}
\input{sampleshape} % includes makeshape.sty
\newcommand{\mnote}[1]
{\marginpar{\scriptsize \raggedright #1 }}
\newcommand{\pfgManCiteA}{\cite{pgfMan}, \emph{Constructing Paths}, \S71, pp 579-589}
\newcommand{\pfgManCiteB}{\cite{pgfMan}, \emph{Declaring New Shapes}, \S75.5, pp 625-631}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\OnlyDescription % comment out for code implementation
\begin{document}
\DocInput{makeshape.dtx}
\end{document}
%</driver>
% \fi
%
%^^A-------------------------------------------------------------------
%^^A Change log...
%^^A-------------------------------------------------------------------
%^^A
%^^A 0.0 - 5 January 2013
% \changes{0.0}{2013/01/05}{
% Experimental -
% Develop the style file and a sample shape.
% Write the user guide.
% Incorporate makeshape.sty generation and documentation.
% Generate the samplshape.tex file.
% }
%^^A
%^^A 0.1 - 11 January 2013
% \changes{0.1}{2013/01/11}{
% Experimental -
% Fix the sample shape's cardinal anchor points problem by
% correcting a bug in the north-east saved anchor.
% Correct errors in the user guide and fill in omissions.
% \emph{Experimental phase complete.}}
%^^A
%^^A 25 January 2013
% \changes{1.0}{2013/01/25}{
% Prepare for publication -
% Very minor changes made to the style file code.
% Standard path commands used in sample shape code.
% A lot of the report is rewritten.
% An abstract is added, and its contents removed. }
%^^A
%^^A-------------------------------------------------------------------
%^^A Check sums...
%^^A-------------------------------------------------------------------
%
%^^A \CheckSum{0} ^^A no checksum for development
% \CheckSum{272}
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
% Digits \0\1\2\3\4\5\6\7\8\9
% Exclamation \! Double quote \" Hash (number) \#
% Dollar \$ Percent \% Ampersand \&
% Acute accent \' Left paren \( Right paren \)
% Asterisk \* Plus \+ Comma \,
% Minus \- Point \. Solidus \/
% Colon \: Semicolon \; Less than \<
% Equals \= Greater than \> Question mark \?
% Commercial at \@ Left bracket \[ Backslash \\
% Right bracket \] Circumflex \^ Underscore \_
% Grave accent \` Left brace \{ Vertical bar \|
% Right brace \} Tilde \~}
%
%^^A===========================================================================
%^^A Generate figure files for input into this report
%^^A===========================================================================
%
%^^A---------------------------------------------------------------------------
%^^A Background path diagram file
%^^A---------------------------------------------------------------------------
% \begin{VerbatimOut}[gobble=5]{msbackground.tmp}
% %^^A - The background path diagram, part of makeshape,dtx
% %^^A - This is a temporary file and should be deleted
% %^^A
% \begin{tikzpicture}[>=latex',font={\sf \small}]
%
% %^^A-- diagram 1 --------------------------------------------
% \begin{scope}
%
% \def\ctbw{88pt}
% \def\ctbh{14pt}
%
% \def\ctbnex{\ctbw/2}
% \def\ctbney{\ctbh/2}
%
% \node (outer) at (0,0) [draw, rectangle, pattern=crosshatch dots,
% minimum width=\ctbw+20pt,
% minimum height=\ctbh+20pt,
% ] {} ;
%
% \node at (\ctbnex,\ctbney) [circle, fill=white] {};
%
% \node (ctb) at (0,0) [draw, rectangle, fill=white,
% minimum width=\ctbw,
% minimum height=\ctbh,
% ] {};
%
% \node (ctbne) at (\ctbnex,\ctbney) [draw, circle] {};
%
% %^^A - Labels
% \node (ctbneLabel) at (4cm,1cm)
% [inner sep = 0] {(\verb|\ctbnex|,\verb|\ctbney|)};
% \node (ctbLabel) at (2cm,-1.2cm)
% [inner sep = 0] {corrected text box};
% \node (innerLabel) at (-1.8cm,1.2cm)
% [] {inner surface};
% \node (outerLabel) at (-2cm,-1.2cm)
% [inner sep = 0] {outer surface};
%
% \draw [->] (ctbneLabel.south west) -- (ctbne);
% \draw [->] (ctbLabel.north west) -- (ctb.320);
% \draw [->] (innerLabel.320) -- (ctb.160);
% \draw [->] (outerLabel.north east) -- (outer);
%
% %^^A - xy axis
% \draw [dotted] (0,0) -- ++(2.5cm,0); % origin
% \draw [dotted] (0,0) -- ++(-2.5cm,0); % origin
% \draw [dotted] (0,0) -- ++(0,1cm); % origin
% \draw [dotted] (0,0) -- ++(0,-1cm); % origin
%
% \end{scope}
%
% %^^A-- diagram 2 --------------------------------------------
% \begin{scope}[yshift=-4cm]
%
% \def\ctbw{88pt}
% \def\ctbh{14pt}
%
% \def\ctbnex{\ctbw/2}
% \def\ctbney{\ctbh/2}
%
% \node (outer) at (0,0) [draw, rectangle, pattern=crosshatch dots,
% minimum width=\ctbw+40pt,
% minimum height=\ctbh+40pt,
% ] {} ;
%
% \node at (\ctbnex,\ctbney) [circle, fill=white] {};
%
% \node (inner) at (0,0) [draw, rectangle, fill=white,
% minimum width=\ctbw+20pt,
% minimum height=\ctbh+20pt,
% ] {};
%
% \node (ctb) at (0,0) [draw, rectangle, fill=white,
% minimum width=\ctbw,
% minimum height=\ctbh,
% ] {};
%
% \node at (\ctbnex,\ctbney) [draw, circle] (ctbne) {};
%
% %^^A - Labels
% \node (ctbneLabel) at (4cm,1cm)
% [inner sep = 0] {(\verb|\ctbnex|,\verb|\ctbney|)};
% \node (ctbLabel) at (2cm,-1.5cm)
% [inner sep = 0] {corrected text box};
% \node (innerLabel) at (-2cm,-2cm)
% [inner sep = 0] {inner surface};
% \node (outerLabel) at (-2.5cm,-1.5cm)
% [inner sep = 0] {outer surface};
%
% \draw [->] (ctbneLabel.south west) -- (ctbne);
% \draw [->] (ctbLabel.north west) -- (ctb.320);
% \draw [->] (innerLabel.north east) -- (inner.250);
% \draw [->] (outerLabel.north east) -- (outer);
%
% %^^A - minimum dimensions
% \node (a) [coordinate, left=15pt of outer.south west] {};
% \node (b) [coordinate, left=15pt of outer.north west] {};
% \draw [|<->|] (a) -- (b) node [midway,left] {\tt minimum height};
%
% \node (c) [coordinate, above=15pt of outer.north west] {};
% \node (d) [coordinate, above=15pt of outer.north east] {};
% \draw [|<->|] (c) -- (d) node [midway,above] {\tt minimum width};
%
% %^^A - xy axis
% \draw [dotted] (0,0) -- ++(2.8cm,0); % origin
% \draw [dotted] (0,0) -- ++(-2.5cm,0); % origin
% \draw [dotted] (0,0) -- ++(0,1.2cm); % origin
% \draw [dotted] (0,0) -- ++(0,-1.2cm); % origin
%
% \end{scope}
%
% \end{tikzpicture}
% \end{VerbatimOut}
%
%^^A---------------------------------------------------------------------------
%^^A Anchor path diagram file
%^^A---------------------------------------------------------------------------
% \begin{VerbatimOut}[gobble=5]{msanchor.tmp}
% %^^A - The anchor path diagram, part of makeshape,dtx
% %^^A - This is a temporary file and should be deleted
% %^^A
% \begin{tikzpicture}[>=latex',font={\sf \small}]
%
% \def\ctbw{88pt}
% \def\ctbh{14pt}
%
% \def\ctbnex{\ctbw/2}
% \def\ctbney{\ctbh/2}
%
% %^^A-- diagram 1 --------------------------------------------
% \begin{scope}
%
% \node (outer) at (0,0) [draw, rectangle, pattern=crosshatch dots,
% minimum width=\ctbw+20pt,
% minimum height=\ctbh+20pt,
% ] {};
%
% \node at (\ctbnex,\ctbney) [circle, fill=white] {};
%
% \node (ctb) at (0,0) [draw, rectangle, fill=white,
% minimum width=\ctbw,
% minimum height=\ctbh,
% ] {};
%
% \node (ctbne) at (\ctbnex,\ctbney) [draw, circle] {};
%
% %^^A - Labels
% \node (ctbneLabel) at (4cm,1cm)
% [inner sep = 0] {(\verb|\ctbnex|,\verb|\ctbney|)};
% \node (ctbLabel) at (2cm,-1.2cm)
% [inner sep = 0] {corrected text box};
% \node (spaceLabel) at (-1.8cm,1.2cm)
% [] {background path space};
% \node (outerLabel) at (-2.3cm,-1.2cm)
% [inner sep = 0] {outer shape surface};
% \node (anchorLabel) at (-1.5cm,-1.7cm)
% [inner sep = 0] {anchor surface};
%
% \draw [->] (ctbneLabel.south west) -- (ctbne);
% \draw [->] (ctbLabel.north west) -- (ctb.320);
% \draw [->, shorten >=5pt] (spaceLabel.320) -- (ctb.160);
% \draw [->] (outerLabel.north east) -- (outer);
% \draw [->] (anchorLabel.north east) -- (outer);
%
% %^^A - xy axis
% \draw [dotted] (0,0) -- ++(2.5cm,0); % origin
% \draw [dotted] (0,0) -- ++(-2.5cm,0); % origin
% \draw [dotted] (0,0) -- ++(0,1cm); % origin
% \draw [dotted] (0,0) -- ++(0,-1cm); % origin
%
% \end{scope}
%
% %^^A-- diagram 2 --------------------------------------------
% \begin{scope}[yshift=-5cm]
%
% \node (anchor) at (0,0) [draw, rectangle,
% minimum width=\ctbw+70pt,
% minimum height=\ctbh+70pt,
% ] {} ;
%
% \node (outer) at (0,0) [draw, rectangle, pattern=crosshatch dots,
% minimum width=\ctbw+40pt,
% minimum height=\ctbh+40pt,
% ] {} ;
%
% \node at (\ctbnex,\ctbney) [circle, fill=white] {};
%
% \node (inner) at (0,0) [draw, rectangle, fill=white,
% minimum width=\ctbw+20pt,
% minimum height=\ctbh+20pt,
% ] {};
%
% \node (ctb) at (0,0) [draw, rectangle, fill=white,
% minimum width=\ctbw,
% minimum height=\ctbh,
% ] {};
%
% \node at (\ctbnex,\ctbney) [draw, circle] (ctbne) {};
%
% %^^A - Labels
% \node (ctbneLabel) at (4.3cm,1cm)
% [inner sep = 0] {(\verb|\ctbnex|,\verb|\ctbney|)};
% \node (ctbLabel) at (2cm,-1.8cm)
% [inner sep = 0] {corrected text box};
% \node (spaceLabel) at (-3.3cm,-1.8cm)
% [inner sep = 0] {background path space};
% \node (outerLabel) at (-2.8cm,-2.3cm)
% [inner sep = 0] {outer path surface};
% \node (anchorLabel) at (-2.7cm,-2.8cm)
% [inner sep = 0] {anchor path surface};
%
% \draw [->] (ctbneLabel.south west) -- (ctbne);
% \draw [->] (ctbLabel.north west) -- (ctb.320);
% \draw [->, shorten >=4pt] (spaceLabel.north east) -- (inner.210);
% \draw [->] (outerLabel.north east) -- (outer.227);
% \draw [->] (anchorLabel.north east) -- (anchor);
%
% %^^A - minimum dimensions
% \node (a) [coordinate, left=30pt of outer.south west] {};
% \node (b) [coordinate, left=30pt of outer.north west] {};
% \draw [|<->|] (a) -- (b) node [midway,left] {\tt minimum height};
%
% \node (c) [coordinate, above=30pt of outer.north west] {};
% \node (d) [coordinate, above=30pt of outer.north east] {};
% \draw [|<->|] (c) -- (d) node [midway,above] {\tt minimum width};
%
% \node (e) [coordinate, left=15pt of anchor.north west] {};
% \draw [<->|] (b) -- (e) node [midway,left] {\tt outer ysep};
%
% \node (f) [coordinate, above=15pt of anchor.north east] {};
% \draw [<->|] (d) -- (f) node [right,above] {\hspace{30pt}\tt outer xsep};
%
% \draw [dotted] (a) -- ++(30pt,0);
% \draw [dotted] (b) -- ++(30pt,0);
% \draw [dotted] (c) -- ++(0,-30pt);
% \draw [dotted] (d) -- ++(0,-30pt);
%
% %^^A - xy axis
% \draw [dotted] (0,0) -- ++(3cm,0); % origin
% \draw [dotted] (0,0) -- ++(-3cm,0); % origin
% \draw [dotted] (0,0) -- ++(0,1.2cm); % origin
% \draw [dotted] (0,0) -- ++(0,-1.2cm); % origin
%
% \end{scope}
%
% \end{tikzpicture}
% \end{VerbatimOut}
%
%^^A===========================================================================
%^^A Start report body
%^^A===========================================================================
%
% \GetFileInfo{makeshape.sty}
%
% \title{The {\sf makeshape} package\thanks{
% This document corresponds to \textsf{makeshape}~\fileversion,
% dated~\filedate.}\\
% and\\
% A Method for Creating Custom Shapes in PGF}
%
% \author{Adrian P. Robson\thanks{\texttt{
[email protected]}}}
% \date{25 January 2013}
%
% \maketitle
%
%^^A - Abstract
% \vspace{-3ex}
% \begin{quote}
% The {\sf makeshape} package simplifies writing PGF shapes.
% Declaring a custom shape with a correct anchor border can be difficult.
% Complex shapes often need complicated calculations to find the touching point
% of a connecting line.
% This package only requires that a developer write a PGF path describing the
% anchor border.
% It also provides macros that help with the management of shape parameters
% and the definition of anchor points.
% \end{quote}
%
%
%^^A \tableofcontents
%
%\section{Introduction}
%
% The |\pgfdeclareshape| command can be used to create new shapes with the PGF package
% (\pfgManCiteB).
% The following are typically needed:
% \begin{itemize} [itemsep=-0.5ex]
% \item A shape name.
% \item Code for computing saved anchors and saved dimensions.
% \item Code for computing anchor positions in terms of the saved anchors.
% \item Code for computing border anchors (|\anchorborder|).
% \item Code for drawing a background path.
% \end{itemize}
% Writing these can be hard for completely new shapes, and in particular the declaration of a
% suitable |\anchorborder| command can be very difficult for complex shapes.
%
% \emph{This paper presents a method that makes the process of writing new shapes from scratch
% a little easier.}
% Its key features are:
% a mechanism for specifying the |\anchorborder| behaviour as a path;
% a package that provides a set of useful macros for writing and allocating anchor
% and background paths;
% and an example |\pgfdeclareshape| command that can be used as a template for new shapes.
%
% The method involves writing some original code and modifying the template.
% In brief, the process involves:
% \begin{enumerate} [itemsep=-0.5ex]
% \item Writing \emph{background path} and \emph{anchor path} macros.
% \item Writing one or more \emph{saved anchors}.
% \item Writing \emph{anchors} using the above saved anchors.
% \end{enumerate}
%
%
% \section{Preliminaries}
%
% \subsection{Background Path Macro}\label{sec:backgroundpath}
%
% \begin{figure}
% \begin{center}
% \input{msbackground.tmp}
% \end{center}
% \caption{The Background Path}\label{fig:backgroundpath}
% \end{figure}
%
% The \emph{background path}, as illustrated in figure~\ref{fig:backgroundpath},
% describes the curves that form the actual shape.
% It can be just a single line and does not have to be closed.
% However, there are no limits on is complexity.
% If it is more than a simple outline, then its \emph{inner} and \emph{outer} surfaces
% need to be considered separately.
%
% The inner surface should contain the \emph{corrected text box},
% which is the shape's text box surrounded by the space specified by its
% {\tt inner xsep} and {\tt inner ysep} keys.
% The coordinates of this box are given by the package's |\ctbnex| and |\ctbnex| macros,
% which are described in \S\ref{sec:corrctdTextBox}.
%
% The outer surface should have height and width dimensions that are the same as
% the shape's {\tt minimum} {\tt width} and {\tt minimum} {\tt height}
% keys if these are larger than the basic dimensions.
% These keys can be obtained with the |\pgfshapeminwidth| and |\pgfshapeminheight| macros,
% as described in \S\ref{sec:keycommands}.
% The |\mincorrect| macro described in \S\ref{sec:mincorrmacro} can be used make the necessary
% comparison and assignment.
%
% \subsubsection{Background Path Algorithm}\label{sec:backgroundpathmacro}
%
% The background path should be implemented as a macro with the following structure:
% \begin{enumerate}
%
% \item \label{item:ctb} Use |\ctbnex| and |\ctbnex|,
% which give the north east corner of the corrected text box,
% to calculate significant reference coordinates.
%
% \item \label{item:mindim} Use |\mincorrect| to modify the reference coordinates to
% take account of the shape's minimum dimension keys,
% which are given by |\pgfshapeminwidth| and |\pgfshapeminheight|.
%
%
% \item Use the reference coordinates from step \ref{item:mindim} to draw the actual path
% using PGF path commands (\pfgManCiteA). Typical commands are
% |\pgfpathmoveto|,
% |\pgfpathlineto| and
% |\pgfpathclose|.
% The |\pgfpoint| command will also be needed.
% Do this for
% \begin{enumerate}
% \item the outer surface curve, and \label{item:outer}
% \item curves in the shape's inner path space
% \end{enumerate}
% Usually when a path is defined, it is displayed with |\pgfusepath{stroke}|.
% However, it is not needed here.
%
% \end{enumerate}
%
% \subsection{Anchor Path Macro}\label{sec:anchorpath}
%
% The \emph{anchor path}, as illustrated in figure~\ref{fig:anchorpath},
% describes the curve that forms the surface where connecting lines meet the shape.
% It it must be a single closed path, and it is normally strongly related to
% background path's outer surface (see \S\ref{sec:backgroundpath}).
%
% Like the background path, it should use the fundamental reference point of the
% \emph{corrected text box}, which automatically includes the shape's inner
% separation.
% It should also take regard of the shape's {\tt minimum} {\tt width}
% and {\tt minimum} {\tt height} keys if these are larger than the basic dimensions.
% Furthermore, it should compensate for the {\tt outer} {\tt xsep} and {\tt outer} {\tt ysep}
% keys as shown in figure~\ref{fig:anchorpath}.
%
% The corrected text box macros are decribed in \S\ref{sec:corrctdTextBox}.
% The minimum dimension keys are given by |\pgfshapeminwidth| and |\pgfshapeminheight|,
% and the outer separation keys are given by |\pgfshapeouterxsep| and
% |\pgfshapeouterysep|, as described in \S\ref{sec:keycommands}.
% The minimum dimension comparision and assignment is provided by |\mincorect| macro,
% which is discussed in \S\ref{sec:mincorrmacro}.
%
% \subsubsection{Anchor Path Algorithm}\label{sec:anchorpathmacro}
%
%
% The anchor path should be implemented as a macro with the following structure:
% \begin{enumerate}
%
% \item Use |\ctbnex| and |\ctbnex|,
% which give the north east corner of the corrected text box,
% to calculate significant reference coordinates. (Normally the same as
% \S\ref{sec:backgroundpathmacro} step \ref{item:ctb}).
% \label{item:apctb}
%
% \item Use |\mincorrect| to modify the reference coordinates to
% take account of the shape's minimum dimension keys,
% which given by |\pgfshapeminwidth| and |\pgfshapeminheight|.
% (Normally the same as \S\ref{sec:backgroundpathmacro} step \ref{item:mindim}).
% \label{item:apmindim}
%
% \item Modify the reference coordinates to take account of outer separation,
% which is given by |\pgfshapeouterxsep| and |\pgfshapeouterysep|.
% \label{item:apouter}
%
% \item Use the corrected reference coordinates from step \ref{item:apouter} to specify
% the anchor path using PGF path commands (\pfgManCiteA).
% The path should be closed so a |\pgfpathclose| command is required.
% The path will not actually be drawn, and the |\pgfusepath{stroke}| macro
% should not be used.
% (Normally the same as \S\ref{sec:backgroundpathmacro} step \ref{item:outer}).
% \label{item:appath}
%
% \end{enumerate}
%
% \subsection{Anchors}
%
% A PGF shape requires the definition of a set of anchor point commands,
% and these need \emph{saved anchors} to provide necessary coordinates.
% All anchor macros should return a point coordinate by assigning values to the
% registers |\pgf@x| and |\pgf@y|.
%
% Like the anchor path macro, saved anchors should use the fundamental reference point of the
% \emph{corrected text box}, which automatically includes the shape's inner
% separation.
% They should also take regard of the shape's {\tt minimum} {\tt width}
% and {\tt minimum} {\tt height} keys if these are larger than the basic dimensions.
% Furthermore, they should compensate for the {\tt outer} {\tt xsep} and {\tt outer} {\tt ysep}
% keys as shown in figure~\ref{fig:anchorpath}.
%
% The corrected text box macros are decribed in \S\ref{sec:corrctdTextBox}.
% The minimum dimension keys are given by |\pgfshapeminwidth| and |\pgfshapeminheight|,
% and the outer separation keys are given by |\pgfshapeouterxsep| and
% |\pgfshapeouterysep|, as described in \S\ref{sec:keycommands}.
% The minimum dimension comparision and assignment is provided by |\mincorect| macro,
% which is discussed in \S\ref{sec:mincorrmacro}.
%
% \begin{figure}
% \begin{center}
% \input{msanchor.tmp}
% \end{center}
% \caption{The Anchor Path}\label{fig:anchorpath}
% \end{figure}
%
% \subsubsection{Saved Anchor Algorithm}
%
% A saved anchor must set the PGF registers |\pgf@x| and |\pgf@y|
% with the required coordinates.
% It has a structure similar to the anchor path.
%
% \begin{enumerate}
%
% \item Use |\ctbnex| and |\ctbnex|,
% which give the north east corner of the corrected text box,
% to calculate significant reference coordinates.
% (Normally similar to \S\ref{sec:anchorpathmacro} step \ref{item:apctb}).
%
% \item Use |\mincorrect| to modify the reference coordinates to
% take account of the shape's minimum dimension keys,
% which given by |\pgfshapeminwidth| and |\pgfshapeminheight|.
% (Normally the same as \S\ref{sec:anchorpathmacro} step \ref{item:apmindim}).
%
% \item Modify the reference coordinates to take account of outer separation,
% which is given by |\pgfshapeouterxsep| and |\pgfshapeouterxsep|.
% (Normally the same as \S\ref{sec:anchorpathmacro} step \ref{item:apouter}).
% \label{item:sanchosep}
%
% \item Use the reference coordinates from step \ref{item:sanchosep} to calculate the
% location of the anchor point, and assign values to the |\pgf@x| and |\pgf@y|
% registers.
%
% \end{enumerate}
%
% \section{Making a Shape}
%
% \subsection{Helper Macros}\label{sec:macros}
%
% The following macros are available for use in the anchor path,
% background path and saved anchors.
%
% \subsubsection{Corrected text box}\label{sec:corrctdTextBox}
%
% The \emph{corrected text box} is a bounding box for the
% shape's text that includes the shape's {\tt inner} {\tt xsep} and {\tt inner} {\tt ysep} keys.
% The box is symmetric about the origin.
% Its x and y coordinates are given by the following commands:
%
% \begin{description} [itemsep=-0.5ex, labelindent=-0.5em]
%
% \item[] |\ctbnex|:
% The x-coordinate of the north east corner of the shape's corrected text box.
%
% \item[] |\ctbney|:
% The y-coordinate of the north east corner of the shape's
% corrected text box.
%
% \end{description}
%
% \subsubsection{Correcting for minimum dimensions}\label{sec:mincorrmacro}
%
% A shape's size should be corrected for its
% {\tt minimum} {\tt width} and {\tt minimum} {\tt height} keys.
% The |\mincorrect| macro is provided to help with this.
%
% \begin{description} [itemsep=-0.5ex, labelindent=-0.5em]
%
% \item[] |\mincorrect{|{\it dimreg\/}|}{|{\it minkey\/}|}|:
% Correct an x or y outer bound dimension for {\tt minimum} {\tt width} or
% {\tt minimum} {\tt height} keys.
%
% \vspace{-1.5ex}
% \begin{description}
%
% \item[{\it dimreg} \rm --] A dimension register.
% On entry, it should hold the normal dimension of the shape.
% On exit, $dimreg$ is assigned the larger of its original value or $minkey/2$.
%
% \item[{\it minkey} \rm--] A minimum dimension key value.
% In practice, one of the minimum height or width commands given in
% \S\ref{sec:keycommands} below.
%
% \end{description}
%
% \end{description}
%
% \subsubsection{Getting key values}\label{sec:keycommands}
%
% The shape's key values can be accesses with the following commands:
%
% \begin{center}
% \begin{tabular}{ll}
% \hline
% key & command \bigstrut\\\hline
% {\tt minimum} {\tt width} & |\pgfshapeminwidth| \bigstrut[t]\\
% {\tt minimum} {\tt height} & |\pgfshapeminheight| \\
% {\tt outer} {\tt xsep} & |\pgfshapeouterxsep| \\
% {\tt outer} {\tt ysep} & |\pgfshapeouterysep| \bigstrut[b]\\\hline
% \end{tabular}
% \end{center}
%
% \noindent
% The outer separation keys are not relevant to the background path,
% but should be used by the anchor path and saved anchors.
%
% The shape's inner separation keys are automatically included in the \emph{corrected text box}
% coordinates |\ctbnex| and |\ctbney|.
%
% \subsubsection{Testing support}
%
% There are a couple of macros can be used in the background path to delineate a
% shape's text box during development:
%\begin{description}[nosep]
% \item[{\tt \textbackslash path@textbox}] draws a line around the the shape's text
% that is the uncorrected text box.
% \item[{\tt \textbackslash path@ctextbox}] shows the shape's corrected text box,
% which includes inner separation.
% \end{description}
% These macros should not be used in `production' shapes.
%
% \subsection{Procedure}
%
% The procedure in outline for making a new shape is as follows:
% \medskip
%
% \begin{enumerate}[nosep]
% \item Create the border path
% \item Create the anchor path
%\item Declare the shape
% \begin{enumerate}[nosep]
% \item Use |\setpaths| to employ the paths
% \item Create the anchors
% \end{enumerate}
% \end{enumerate}
% \medskip
%
% The sample shape given in \S\ref{sec:samplecode} can be used as a template to
% create a new shape.
% The code can be copied from there, or it can be acquired as the file |sampleshape.tex|,
% which is part of the package's distribution.
%
% The procedure for adapting the template code is as follows:
% \begin{enumerate}
%
% \item Change the name of the shape in the |\pgfdeclareshape| command
% from `{\tt sample}' to the name of the new shape.
%
% \item \label{item:steppaths} Write \emph{anchor path} and \emph{background path} macros.
%
% These and any sub macros are placed at the start of the file and replace
% the sample |\sampleanchor| and |\sampleborder| macros.
%
% As discussed in \S\ref{sec:backgroundpath} and \S\ref{sec:anchorpath},
% the background path should take account of the minimum dimension keys,
% and the anchor path should handle the minimum keys, and outer
% separation.
% The macros given in \S\ref{sec:macros} are provided to help with this,
% and the sample code gives an indication of how they can be used.
%
% \item Change the arguments of |\setpaths| in the template to the macros written
% in step \ref{item:steppaths}.
% The first is the anchor path and the second is the background path.
%
% \item \label{item:stepsavedanchors} Write the saved anchors that will needed by the anchors
% written in step~\ref{item:stepanchors}.
%
% Saved anchors, like the anchor path written in step \ref{item:steppaths},
% should correct for outer separation, and minimum dimensions
% using the macros in \S\ref{sec:macros}.
% They should set the |\pgf@x| and |\pgf@y| registers.
%
% \item \label{item:stepanchors}
% Write anchors that set |\pgf@x| and |\pgf@y| registers using
% the saved anchors from step \ref{item:stepsavedanchors}.
%
% \begin{enumerate}
%
% \item Write anchors for the cardinal and sub cardinal points:
%
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \anchor{north}{ ... }
% \anchor{north east}{ ... }
% \anchor{east}{ ... }
% \anchor{south east}{ ... }
% \anchor{south}{ ... }
% \anchor{south west}{ ... }
% \anchor{west}{ ... }
% \anchor{north west}{ ... }
% \end{VerbatimOut}
% \VerbatimInput{\jobname.tmp}
%
% \item Write any additional anchors that the shape needs.
%
% \end{enumerate}
%
% \end{enumerate}
%
% The PGF registers used throughout this method of declaring new shapes have the
% |@| character in their names.
% Unfortunately, this character has a special role in \LaTeX{}.
% So either the |\makeatletter| and |\makeatother| commands must be used as in
% |sampleshape.tex|, or the shape must be defined in a |sty| file.
%
% \section{Path and Anchor Examples}
%
% Here an example of an actual shape that is implemented using the {\sf makeshape} method:
%
% \bigskip
%
% \begin{tikzpicture}%[>=latex',font={\sf \small}]
% \node at (0,0) [draw, sample,
% minimum width=2cm,
% minimum height=1cm] {};
% \end{tikzpicture}
% \bigskip
%
% Its background path, anchor path, and anchor points use a common macro that gives
% the space between the outer and inner boundaries of the shape.
%
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \def\gap{4pt}
% \end{VerbatimOut}
% \VerbatimInput{\jobname.tmp}
%
% \subsection{Background Path}\label{sec:backgroundpathexmpl}
%
% In this example, the background path macro is called {\tt sampleshape}.
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \def\sampleshape{
% \end{VerbatimOut}
% \VerbatimInput[numbers=left]{\jobname.tmp}
% First we get the corrected text box coordinates,
% and add space for the shape using the |\gap| macro.
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \pgf@xa=\ctbnex
% \pgf@ya=\ctbney
% \advance\pgf@xa by \gap
% \advance\pgf@ya by \gap
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=2]{\jobname.tmp}
% Then the standard correction for minimum size is applied using the |\mincorrect| macro.
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \mincorrect{\pgf@xa}{\pgfshapeminwidth}
% \mincorrect{\pgf@ya}{\pgfshapeminheight}
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=6]{\jobname.tmp}
% Using these coordinates the outer boundary of the shape can be drawn
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
% \pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
% \pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
% \pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
% \pgfpathclose
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=8]{\jobname.tmp}
% Finally, the reference coordinates are moved to the inner boundary and the shape is completed
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \advance\pgf@xa by -\gap
% \advance\pgf@ya by -\gap
% \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
% \pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
% \pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
% \pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
% \pgfpathclose
% }
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=13]{\jobname.tmp}
%
% \subsection{Anchor Path}\label{sec:anchorpathexmpl}
%
% The shape's anchor path macro called {\tt sampleanchor},
% and is similar to the path macro in \S\ref{sec:backgroundpathexmpl},
% but it also handles outer separation.
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \def\sampleanchor{
% \end{VerbatimOut}
% \VerbatimInput[numbers=left]{\jobname.tmp}
% First we get the corrected text box coordinates, and add space for the shape using
% the |\gap| macro.
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \pgf@xa=\ctbnex
% \pgf@ya=\ctbney
% \advance\pgf@xa by \gap
% \advance\pgf@ya by \gap
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=2]{\jobname.tmp}
% Then corrections for minimum size and outer separation are applied:
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \mincorrect{\pgf@xa}{\pgfshapeminwidth}
% \advance\pgf@xa\pgfshapeouterxsep
% \mincorrect{\pgf@ya}{\pgfshapeminheight}
% \advance\pgf@ya\pgfshapeouterysep
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=6]{\jobname.tmp}
% Using these coordinates the anchor boundary path is finally drawn
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
% \pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
% \pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
% \pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
% \pgfpathclose
% }
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=10]{\jobname.tmp}
%
% \subsection{Shape Declaration and Anchor Points}
%
% The {\tt sample} shape declaration is started with
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \pgfdeclareshape{sample}{
% \end{VerbatimOut}
% \VerbatimInput[numbers=left]{\jobname.tmp}
% Then the shape and anchor paths, which were defined in \S\ref{sec:backgroundpathexmpl}
% and \S\ref{sec:anchorpathexmpl}, are employed with
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \setpaths{\sampleanchor}{\sampleshape}
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=2]{\jobname.tmp}
%
% \subsubsection{Anchors}
%
% Next in the shape's declaration are its saved anchors.
% In this case, we establish the north east anchor location with code that is equivalent
% to the first part of the anchor path macro (\S\ref{sec:anchorpathexmpl}).
% Note how the anchor point's coordinate is returned in |\pgf@x| and |\pgf@y|.
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \savedanchor{\northeast}{
% \pgf@x = \ctbnex
% \pgf@y = \ctbney
% \advance\pgf@xa by \gap
% \advance\pgf@ya by \gap
% \mincorrect{\pgf@x}{\pgfshapeminwidth}
% \mincorrect{\pgf@y}{\pgfshapeminheight}
% \advance\pgf@x\pgfshapeouterxsep
% \advance\pgf@y\pgfshapeouterysep
% }
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=3]{\jobname.tmp}
%
% \noindent
% The saved anchor is then used to construct the shape's anchors,
% and the declaration is ended as follows:
%
% \begin{VerbatimOut}[gobble=5]{\jobname.tmp}
% \anchor{north}{\northeast \pgf@x=0pt}
% \anchor{north east}{\northeast}
% \anchor{east}{\northeast \pgf@y=0pt}
% \anchor{south east}{\northeast \pgf@y=-\pgf@y}
% \anchor{south}{\northeast \pgf@x=0pt \pgf@y=-\pgf@y}
% \anchor{south west}{\northeast \pgf@x=-\pgf@x \pgf@y=-\pgf@y}
% \anchor{west}{\northeast \pgf@x=-\pgf@x \pgf@y=0pt}
% \anchor{north west}{\northeast \pgf@x=-\pgf@x}
% }
% \end{VerbatimOut}
% \VerbatimInput[numbers=left, firstnumber=13]{\jobname.tmp}
%
%
% \subsection{Sample Shape Code}\label{sec:samplecode}
%
% The following is a full listing of the code needed to make the sample shape
% described above.
% It can be used as a templete for new shapes.
% A copy of this code can be found in the the file {\tt sampleshape.tex},
% which is included in the package's distribution.
% Note the use of the |\makeatletter| and |\makeatother| commands, which are required
% because the sample shape is in a |tex| file.
%
%^^A - Code must be < 67 characters to fit on page at 10pt ...
% \VerbatimInput[ ^^A numbers=left,
% firstline=40, lastline=127]{sampleshape}
%
%
%^^A===========================================================================
%^^A References
%^^A===========================================================================
%
%^^A - Used in \StopEventually ...
%
% \def\printBib{
% \begin{thebibliography}{9}
% \raggedright
%
% \bibitem{pgfMan}
% Till Tantau,
% \emph{The TikZ and PGF Packages, Manual for version 2.10},
% 2010.
% Available as
% \href{
http://mirrors.ctan.org/graphics/pgf/base/doc/generic/pgf/pgfmanual.pdf}
% {\tt pgfmanual.pdf}
% from the \href{
http://ctan.org}{Comprehensive TeX Archive Network}.
%
%^^A in pgfMan \emph{Constructing Paths}, section 71, pp 579-589.
%^^A in pgfMan \emph{Declaring New Shapes}, section 75.5, pp 625-631.
%
% \end{thebibliography}
% }
%
%
%^^A===========================================================================
%^^A Start code implementation
%^^A===========================================================================
%
% \StopEventually{ \printBib }
%^^A \StopEventually{ \printBib \PrintChanges }
%^^A -> Run pdfLaTeX makeshape.dtx
%^^A makeindex -s gglo.ist -o makeshape.gls makeshape.glo
%^^A pdfLaTeX makeshape.dtx
%
% \section{Implementation}
%
% \subsection{Text Box Calculations}\label{sec:textboxcalc}
%
% The shape's text is at its centre for shape's made with this package.
% The text box position is defined by the shape's |text| anchor, which must give the coordinate
% of the west end of the text's base line.
% PGF provides three useful dimensions:
%
% \smallskip
% \begin{tabular}{lll}
% |\wd\pgfnodeparttextbox| & width & $wd$\\
% |\ht\pgfnodeparttextbox| & height & $ht$\\
% |\dp\pgfnodeparttextbox| & depth & $dp$\\
% \end{tabular}
%
% \smallskip\noindent
% These are related as follows:
% \medskip
%
%^^A----------------------------------
%^^A- Text box diagram - start
%^^A----------------------------------
% \begin{tikzpicture}[>=latex',font={\sf \small}]
%
% \def\tbht{30pt} ^^A - text box height
% \def\tbdp{15pt} ^^A - text box depth
% \def\tbwd{150pt} ^^A - text box width
%
% \def\blwx{-\tbwd/2} ^^A - baseline west x
% \def\blwy{-\tbht/2+\tbdp/2} ^^A - baseline west y
%
% \def\tbnex{\tbwd/2} ^^A - text box north east x
% \def\tbney{\tbht/2+\tbdp/2} ^^A - text box north east y
%
% \node (textbox) at (0,0) [draw, rectangle, fill=white,
% minimum width=\tbwd,
% minimum height=\tbht+\tbdp,
% ] {};
% \draw [] (\blwx,\blwy) -- ++(\tbwd,0);
%
% \node (textanchor) [coordinate] at (\blwx,\blwy){};
%
% \node at (textanchor) [draw, circle] (blinewest) {};
%
%^^A - Labels
% \node (blinelable) at (3.5cm,\blwy) [inner sep = 0] {baseline};
% \node (textanchlabel) at (\blwx+28pt,\blwy+8pt) [inner sep = 0] {text anchor};
%
%^^A - Dimensions
% \node (hta) [coordinate, left=15pt of textbox.south west] {};
% \node (htc) [coordinate, left=15pt of textbox.north west] {};
% \node (htb) [coordinate, left=15pt of textanchor] {};
% \draw [|<->|] (hta) -- (htb) node [midway,left] {depth};
% \draw [<->|] (htb) -- (htc) node [midway,left] {height};
% \node (wda) [coordinate, above=10pt of textbox.north west] {};
% \node (wdb) [coordinate, above=10pt of textbox.north east] {};
% \draw [|<->|] (wda) -- (wdb) node [midway,above] {width};
%
%^^A - xy axis
% \def\xaxisdim{0.5cm}
% \def\yaxisdim{0.5cm}
% \draw [dotted] (0,0) -- ++(\xaxisdim,0); ^^A - origin
% \draw [dotted] (0,0) -- ++(-\xaxisdim,0); ^^A - origin
% \draw [dotted] (0,0) -- ++(0,\yaxisdim); ^^A - origin
% \draw [dotted] (0,0) -- ++(0,-\yaxisdim); ^^A - origin
%
% \end{tikzpicture}
%^^A----------------------------------
%^^A- Text box diagram - end
%^^A----------------------------------
%\medskip
%
% For this box to be centred on the origin, we need to calculate suitable coordinates for
% the |text| anchor.
% So, if the box's south west corner is at $(x_{sw},y_{sw})$ and the box is centred, then
% $x_{sw} = -wd/2$ and $y_{sw}=-(ht+dp)/2$.
% If the |text| anchor is at $(x_{text},y_{text})$, then
% \vspace{-2ex}
%\begin{eqnarray}
% x_{text} & = & x_{sw} = -\frac{wd}{2}\label{eqn:xtext}\\
% y_{text} & = & y_{sw} + dp = -\frac{ht}{2} - \frac{dp}{2} + dp
% = \frac{dp}{2} - \frac{ht}{2} \label{eqn:ytext}
%\end{eqnarray}
%
% Furthermore, the shape's north east corner $(x_{ne},y_{ne})$ is at
%\begin{eqnarray}
% x_{ne} & = & \frac{wd}{2} \label{eqn:xne}\\[1ex]
% y_{ne} & = & \frac{ht+dp}{2} \label{eqn:yne}
%\end{eqnarray}
%
%\iffalse
%<*package>
%\fi
%
%\subsection{Symetric bounding box}\label{sec:symbbox}
%
% We require a rectangle that contains the anchor path, and has its centre at the origin.
% Such a rectangle, defined by the coordinate of its north east corner, is needed
% in the anchor border algorithm described in \S\ref{sec:anchoralgorithm}.
%
% \vspace{2ex}
%
%^^A----------------------------------
%^^A- Bounding box diagram - start
%^^A----------------------------------
% \begin{tikzpicture}[>=latex',font={\sf \small}]
%
% \def\bbnex{60pt} ^^A - box ne x
% \def\bbney{30pt} ^^A - box ne y
%
% \node (boundingbox) at (0,0) [draw, rectangle, dashed,
% minimum width=2*\bbnex,
% minimum height=2*\bbney,
% ] {};
%
% \node at (\bbnex,\bbney) [draw, circle] (boxne) {};
%
% \def\nx{0pt} \def\ny{20pt}
% \def\ex{30pt} \def\ey{-10pt}
% \def\sx{-20pt} \def\sy{-\bbney}
% \def\wx{-\bbnex} \def\wy{10pt}
%
%^^A - Anchor path
% \draw [] (\nx,\ny) -- (\ex,\ey);
% \draw [] (\ex,\ey) -- (\sx,\sy);
% \draw [] (\sx,\sy) -- (\wx,\wy);
% \draw [] (\wx,\wy) -- (\nx,\ny);
%
%^^A - mins and maxs with labels
% \draw [dotted] (\nx,\ny) -- (\bbnex+10pt,\ny);
% \draw [dotted] (\bbnex,\sy) -- (\bbnex+10pt,\sy);
% \draw [dotted] (\ex,\ey) -- (\ex,-\bbney-10pt);
% \draw [dotted] (\wx,-\bbney) -- (\wx,-\bbney-10pt);
% \node (maxy) at (\bbnex+24pt,\ny) [inner sep = 0] {$y_{max}$};
% \node (miny) at (\bbnex+24pt,\sy) [inner sep = 0] {$y_{min}$};
% \node (maxx) at (\wx,-\bbney-16pt) [inner sep = 0] {$x_{min}$};
% \node (maxx) at (\ex,-\bbney-16pt) [inner sep = 0] {$x_{max}$};%
%
%^^A - Labels
% \node (path) at (\wx-40pt,\wy-32pt) [inner sep = 0] {anchor path};
% \draw [->] (path.east) -- (-40pt,-10pt);
% \node (box) at (\wx-40pt,\wy+13pt) [inner sep = 0] {bounding box};
% \draw [->] (box.east) -- (\wx,23pt);
% \node (bbne) at (\bbnex+25pt,\bbney+10pt) [inner sep = 0] {$(x_{ne},y_{ne})$};
%
%^^A - xy axis
% \def\xaxisdim{0.2cm}
% \def\yaxisdim{0.2cm}
% \draw [] (0,0) -- ++(\xaxisdim,0); ^^A - origin
% \draw [] (0,0) -- ++(-\xaxisdim,0); ^^A - origin
% \draw [] (0,0) -- ++(0,\yaxisdim); ^^A - origin
% \draw [] (0,0) -- ++(0,-\yaxisdim); ^^A - origin
%
% \end{tikzpicture}
%^^A----------------------------------
%^^A- Bounding box diagram - end
%^^A----------------------------------
%
% \medskip
% The \emph{symmetric bounding box} is defined by the coordinate of its north east corner:
% \vspace{-3ex}
% \begin{eqnarray}
% x_{ne} &=& \max{(\vert x_{min} \vert \, ,\vert x_{max} \vert )} \label{eqn:bbx}\\
% y_{ne} &=& \max{(\vert y_{min} \vert \, ,\vert y_{max} \vert )} \label{eqn:bby}
% \end{eqnarray}
%
% \subsection{The Anchor Border Algorithm}\label{sec:anchoralgorithm}
%
% A shape's |\anchorborder| command must calculate the intersection of a line drawn
% between the origin and a target point, and the shape's border.
% The aim here is to do this calculation using an \emph{anchor path} that describes
% the shapes outer border.
%
% The |\pgfintersectionofpaths| command can be used to do this, but it will only work
% for points that are outside the anchor path.
% The solution is to \emph{externalise the point} using the |\pgfpointborderrectangle| command.
%
% \bigskip
%^^A------------------------------------------------
%^^A- Anchor border point algorithm diagram - start
%^^A------------------------------------------------
% \begin{tikzpicture}[>=latex',font={\sf \small}]
%
%^^A - xy axis
% \def\xaxisdim{0.2cm}
% \def\yaxisdim{0.2cm}
% \draw [] (0,0) -- ++(-\xaxisdim,0); ^^A - origin
% \draw [] (0,0) -- ++(0,\yaxisdim); ^^A - origin
% \draw [] (0,0) -- ++(0,-\yaxisdim); ^^A - origin
% \filldraw[white] (0,0) circle (2pt);
%
%^^A - Bounding box
% \def\bbnex{60pt} ^^A - box ne x
% \def\bbney{30pt} ^^A - box ne y
%
% \node (boundingbox) at (0,0) [draw, rectangle, dashed,
% minimum width=2*\bbnex,
% minimum height=2*\bbney,
% ] {};
%
% \draw ((\bbnex,\bbney) circle (2pt);
%
%^^A - Anchor path
% \def\nx{30pt} \def\ny{20pt}
% \def\ex{50pt} \def\ey{-20pt}
% \def\sx{-20pt} \def\sy{-\bbney}
% \def\wx{-\bbnex} \def\wy{10pt}
%
% \def\apath{
% \pgfpathmoveto{\pgfpoint{\nx}{\ny}}
% \pgfpathlineto{\pgfpoint{\ex}{\ey}}
% \pgfpathlineto{\pgfpoint{\sx}{\sy}}
% \pgfpathlineto{\pgfpoint{\wx}{\wy}}
% \pgfpathclose }
%
%^^A - Draw the anchor path
% \apath
% \pgfusepath{stroke}
%
%^^A - Target point and vectors
% \def\tx{20pt}
% \def\ty{5pt}
% \def\endx{3.5*\tx}
% \def\endy{3.5*\ty}
%
% \draw [] (0,0) -- (\tx,\ty);
% \draw [dotted] (\tx,\ty) -- (\endx,\endy);
% \filldraw (\tx,\ty) circle (2pt);
%
%^^A - Intersection with bounding box
% \pgfpathcircle{\pgfpointborderrectangle{\pgfpoint{\tx}{\ty}}
% {\pgfpoint{\bbnex}{\bbney}}}{2pt}
% \pgfusepath{stroke}
%
%^^A - intersection with anchor path
% \pgfintersectionofpaths{\apath}
% { \pgfpathmoveto{\pgfpoint{0}{0}}
% \pgfpathlineto{\pgfpoint{\endx}{\endy}} }
% \pgfpathcircle{\pgfpointintersectionsolution{1}}{2pt}
% \pgfusepath{stroke}
%
%^^A - Labels
% \node (path) at (\wx-40pt,\wy-32pt) [inner sep = 0] {anchor path};
% \draw [->] (path.east) -- (-40pt,-10pt);
% \node (box) at (\wx-40pt,\wy+13pt) [inner sep = 0] {bounding box};
% \draw [->] (box.east) -- (\wx,23pt);
% \node (p1) at (\tx+5pt,\ty-8pt) [inner sep = 0] {p1};
% \node (p2) at (\bbnex+10pt,\bbney+5pt) [inner sep = 0] {p2};
% \node (p3) at (\bbnex+10pt,8pt) [inner sep = 0] {p3};
% \node (p4) at (40pt,18pt) [inner sep = 0] {p4};
%
%^^A - point key
%^^A \def\pkeyx{90pt}
%^^A \def\pkeyy{10pt}
%^^A \def\pkeystep{-10pt}
%^^A \node (key1) at (\pkeyx,\pkeyy) [right, inner sep = 0] {p1 = target point};
%^^A \node (key2) at (\pkeyx,\pkeyy+\pkeystep) [right, inner sep = 0] {p2 = bounding box corner};
%^^A \node (key3) at (\pkeyx,\pkeyy+2*\pkeystep) [right, inner sep = 0]
%^^A {p3 = bounding box intersection};
%^^A \node (key4) at (\pkeyx,\pkeyy+3*\pkeystep) [right, inner sep = 0]
%^^A {p4 = anchor path intersection};
%
% \end{tikzpicture}
%^^A------------------------------------------------
%^^A- Anchor border point algorithm diagram - end
%^^A------------------------------------------------
%
%\bigskip
%
%\begin{description}
%
% \item[Step 1 - Externalise the target point]
%
% The vector to the target point {\sf p1} is extended to the bounding box to find
% the intersection {\sf p3}.
% The bounding box is by definition outside the anchor path.
% Thus point {\sf p3} must also be outside the anchor path.
%
% To achieve this, the |\pgfpointborderrectangle| command is applied to the target point {\sf p1}
% and the centred rectangle defined by {\sf p2}, which is the symmetric bounding box defined
% in \S\ref{sec:symbbox}.
%
% \item[Step 2 - Find the border intersection]
%
% The line from the origin to the point {\sf p3} passes through {\sf p1},
% and its intersection with the anchor path is the required point {\sf p4}.
%
% The intersection is found with the |\pgfintersectionofpaths| command,
% which takes the anchor path and the path of the line from the origin to {\sf p3} as input.
% Since {\sf p3} is always outside the anchor path, such an intersection will always be found.
%
% \end{description}
%
% \subsection{Declare Shape Commands}
%
% \begin{macro}{\setpaths}
% The |\setpaths| macro is used in |\pgfdeclareshape| definitions to specify the shape's paths.
% It has two parameters:
% \begin{description}[nosep]
% \item[\tt ~\#1] is a macro defining the anchor path.
% \item[\tt ~\#2] is a macro defining the background path.
% \end{description}
%
% \begin{macrocode}
\def\setpaths#1#2{
% \end{macrocode}
%
% \noindent
% It defines saved macros for use in the shape's path macros and saved anchors.
% There are also macros defined that are only used within the packages other macros.
%
% \subsubsection{Corrected text box saved macros}
%
% These two saved macros give the x and y coordinates of the corrected text box's north east corner.
% They are invoked by users of the package to define a shape's path macros.
%
% \begin{macro}{\ctbnex}
% The |\ctbnex| saved macro gives the x-coordinate,
% which is calculated as described by equation \ref{eqn:xne} in \S\ref{sec:textboxcalc}.
% \begin{macrocode}
\savedmacro\ctbnex{
\pgf@x=.5\wd\pgfnodeparttextbox
\pgfmathsetlength\pgf@xa{\pgfshapeinnerxsep}
\advance\pgf@x\pgf@xa
\edef\temp@x{\the\pgf@x}
\let\ctbnex\temp@x
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ctbney}
% The y-coordinate is given by the |\ctbney| saved macro,
% which implements equation \ref{eqn:yne} in \S\ref{sec:textboxcalc}.
% \begin{macrocode}
\savedmacro\ctbney{
\pgf@y=.5\ht\pgfnodeparttextbox
\advance\
[email protected]\dp\pgfnodeparttextbox
\pgfmathsetlength\pgf@ya{\pgfshapeinnerysep}
\advance\pgf@y\pgf@ya
\edef\temp@y{\the\pgf@y}
\let\ctbney\temp@y
}
% \end{macrocode}
% \end{macro}
%
% \subsubsection{Key value saved macros}
%
% These saved macros give the values of significant shape keys.
% They have the same names as the standard PGF macros,
% and allow the user's anchor and background path macros to use the standard names.
%
% \begin{macro}{\pgfshapeouterxsep}
% The value of the x outer separation key is given by |\pgfshapeouterxsep|.
% \begin{macrocode}
\savedmacro\pgfshapeouterxsep{
\pgfkeysgetvalue{/pgf/outer xsep}{\temp@sep}
\let\pgfshapeouterxsep\temp@sep
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pgfshapeouterysep}
% The value of the y outer separation key is given by |\pgfshapeouterysep|.
% \begin{macrocode}
\savedmacro\pgfshapeouterysep{
\pgfkeysgetvalue{/pgf/outer ysep}{\temp@sep}
\let\pgfshapeouterysep\temp@sep
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pgfshapeminwidth}
% The value of the minimum width key is given by |\pgfshapeminwidth|.
% \begin{macrocode}
\savedmacro{\pgfshapeminwidth}{
\pgfkeysgetvalue{/pgf/minimum width}{\temp@wd}
\let\pgfshapeminwidth\temp@wd
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pgfshapeminheight}
% The value of the minimum height key is given by |\pgfshapeminheight|.
% \begin{macrocode}
\savedmacro{\pgfshapeminheight}{
\pgfkeysgetvalue{/pgf/minimum height}{\temp@ht}
\let\pgfshapeminheight\temp@ht
}
% \end{macrocode}
% \end{macro}
%
% \subsubsection{Saved anchors}\label{sec:savedanchors}
%
% The saved anchors are used to implement the anchors provided by the package,
% but can be used by the user to define custom anchors if required.
% They are required to return the coordinates of a point in |\pgf@x| and |\pgf@y|.
%
% \begin{macro}{\centre}
% The |\centre| saved anchor is used to implement the package |center| anchor.
% The |\pgfpointorigin| command sets |\pgf@x| and |\pgf@y|.
% \begin{macrocode}
\savedanchor{\centre}{
\pgfpointorigin
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\text}
% The |\text| saved anchor is used to implement the package |text| anchor.
% It gives the coordinate of the west end of the text base line.
% The calculation it uses is explained in \S\ref{sec:textboxcalc}.
% Equation \ref{eqn:xtext} gives the x-coordinate
% and equation \ref{eqn:ytext} gives the y-coordinate.
% \begin{macrocode}
\savedanchor{\text}{
\pgf@y=-0.5\ht\pgfnodeparttextbox
\advance\pgf@y by 0.5\dp\pgfnodeparttextbox
\pgf@x=-0.5\wd\pgfnodeparttextbox
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\boundbox@ne}
% The |\boundbox@ne| saved anchor gives the north east corner of the
% anchor path's symmetric bounding rectangle (see \S\ref{sec:symbbox}).
% \begin{macrocode}
\savedanchor{\boundbox@ne}{
% \end{macrocode}
%
% First clear any existing path, and then execute the anchor path macro given as
% the first parameter of |\setpaths|.
% \begin{macrocode}
\pgfusepath{}
#1
% \end{macrocode}
% Store the path's minimum and maximum coordinates, and then discard the path.
% \begin{macrocode}
\pgf@xb=\pgf@pathmaxx
\pgf@yb=\pgf@pathmaxy
\pgf@xc=\pgf@pathminx
\pgf@yc=\pgf@pathminy
\pgfusepath{}
% \end{macrocode}
%
% The north east corner x-coordinate of the symmetric bounding box is calculated using
% equation \ref{eqn:bbx} from \S\ref{sec:symbbox}.
%
% \begin{macrocode}
\ifdim\pgf@xb<0pt \pgf@xb=-\pgf@xb \fi
\ifdim\pgf@xc<0pt \pgf@xc=-\pgf@xc \fi
\ifdim\pgf@xb<\pgf@xc
\pgf@x=\pgf@xc
\else
\pgf@x=\pgf@xb
\fi
% \end{macrocode}
% The y-coordinate is calculated with equation \ref{eqn:bby}:
% \begin{macrocode}
\ifdim\pgf@yb<0pt \pgf@yb=-\pgf@yb \fi
\ifdim\pgf@yc<0pt \pgf@yc=-\pgf@yc \fi
\ifdim\pgf@yb<\pgf@yc
\pgf@y=\pgf@yc
\else
\pgf@y=\pgf@yb
\fi
}
% \end{macrocode}
% \end{macro}
%
% \subsubsection{Anchors}
%
% \begin{macro}{center}
% \begin{macro}{text}
% PGF shapes require |center| and |text| anchors.
% They are implemented by the saved anchors |\center| and |\text| (see \ref{sec:savedanchors}),
% and in effect centre the shape's text on the origin.
% \begin{macrocode}
\anchor{center}{\centre}
\anchor{text}{\text}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\anchorborder}
% The |\anchorborder| anchor is critically responsible for calculating points on
% the shape's boundary
% Its algoritm is explained in \S\ref{sec:anchoralgorithm}.
% \begin{macrocode}
\anchorborder{
% \end{macrocode}
% On entry, the coordinates of the target point are supplied in |\pgf@x| and |\pgf@y|,
% and these are immediately saved:
% \begin{macrocode}
\edef\targpointx{\the\pgf@x}
\edef\targpointy{\the\pgf@y}
% \end{macrocode}
%
% A couple of settings are needed to support shapes that are not centred on the origin:
% \begin{macrocode}
\pgf@relevantforpicturesizefalse
\pgftransformreset
% \end{macrocode}
% The first suppresses updating of the picture bounding box and ensures correct positioning
% of the shape.
% The second stops coordinate transformations being applied,
% which is needed for the correct behaviour of points relying on the |\anchorborder| command.
%
% Start the computation by finding the north east corner of the anchor path's bounding box:
% \begin{macrocode}
\boundbox@ne
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
% \end{macrocode}
% Perform step 1 of the algorithm described in \S\ref{sec:anchoralgorithm} to externalise
% the target to a point on the bounding box:
% \begin{macrocode}
\pgfpointborderrectangle{\pgfpoint{\targpointx}{\targpointy}}
{\pgfpoint{\pgf@xa}{\pgf@ya}}
\edef\corrx{\the\pgf@x}
\edef\corry{\the\pgf@y}
% \end{macrocode}
% Next, use this externalised point to find the required boundary point with step 2 of
% the algorithm.
% The anchor path is |#1|, which is the first argument |setpaths|.
% \begin{macrocode}
\pgfintersectionofpaths {
#1
}{
\pgfpathmoveto{\pgfpoint{0}{0}}
\pgfpathlineto{\pgfpoint{\corrx}{\corry}}
}
% \end{macrocode}
% Finally, the command |\pgfpointintersectionsolution| puts the point's coordinates in
% |\pgf@x| and |\pgf@y|.
% \begin{macrocode}
\pgfpointintersectionsolution{1}
}
% \end{macrocode}
% \end{macro}
%
% \subsubsection{Background path}
%
% \begin{macro}{\backgroundpath}
% The shape is actually drawn by |\backgroundpath|, which executes the second argument of
% |\setpaths|, which is the shape's background path.
% \begin{macrocode}
\backgroundpath{
#2
}
% \end{macrocode}
% \end{macro}
% Finally, |setpaths| is completed.
% \begin{macrocode}
}
% \end{macrocode}
% \end{macro}
%
% \subsection{Utility macros}
%
% \subsubsection{Dimension correction}
%
% \begin{macro}{\mincorrect}
% The |\mincorrect| macro finds the larger of two dimensions.
% It is applied to shape coordinates and keys.
% It uses a working dimension register, and has two parameters
% \begin{macrocode}
\newdimen\crct@dim
\def\mincorrect#1#2{
% \end{macrocode}
% The parameters have the following roles:
% \begin{description}[nosep]
% \item[\tt ~\#1] A register holding the normal outer bound dimension of the shape,
% and then the largest value, in a PGF register such as |\pgf@xa|.
% \item[\tt ~\#2] A key value, normally one of |\pgfshapeminwidth| or |\pgfshapeminheight|.
% \end{description}
% The |\crct@dim| register is used to calculate half of |#2|:
% \begin{macrocode}
\pgfmathsetlength\crct@dim{#2}
\pgfmathsetlength\crct@dim{0.5\crct@dim}
% \end{macrocode}
%
% Then if |#1| is larger than |\crct@dim|, |#1| is assigned this value
% otherwise |#1| remains unchanged.
% \begin{macrocode}
\ifdim#1<\crct@dim
#1=\crct@dim
\fi
}
% \end{macrocode}
% \end{macro}
%
% \subsubsection{Macros for testing}
%
% There are a couple of macros can be used to delineate a shape's text box during development.
% They should not be used in `production' shapes.
%
% \begin{macro}{\path@textbox}
% The |\path@textbox| macro draws a line around the the shape's text that is the
% uncorrected text box.
% \begin{macrocode}
\def\path@textbox{
\pgf@xa=.5\wd\pgfnodeparttextbox
\pgf@ya=.5\ht\pgfnodeparttextbox
\advance\
[email protected]\dp\pgfnodeparttextbox
\typeout{**** TEST text box (x,y) = (\the\pgf@xa,\the\pgf@ya) }
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
\pgfpathclose
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\path@ctextbox}
% The |\path@ctextbox| macro shows the shape's corrected text box,
% which includes inner separation.
% \begin{macrocode}
\def\path@ctextbox{
\pgf@xa=.5\wd\pgfnodeparttextbox
\pgfmathsetlength\pgf@xc{\pgfshapeinnerxsep}
\advance\pgf@xa\pgf@xc
\pgf@ya=.5\ht\pgfnodeparttextbox
\advance\
[email protected]\dp\pgfnodeparttextbox
\pgfmathsetlength\pgf@yc{\pgfshapeinnerysep}
\advance\pgf@ya\pgf@yc
\typeout{**** TEST corrected text box (x,y) =
(\the\pgf@xa,\the\pgf@ya) }
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
\pgfpathclose
}
% \end{macrocode}
% \end{macro}
%
%\iffalse
%</package>
%\fi
%
% \Finale
%
%^^A###########################################################################
%^^A# Additional installed files #
%^^A###########################################################################
%
%^^A - Option = sample ...
%^^A - This is the package's sample shape.
%^^A - It is included in the report, and it is given as a file to be used as
%^^A - a template for new shapes.
%\iffalse
%<*sample>
%%--------------------------------------------------
%%
%% This is a sample shape for the makeshape package
%%
%% It can be adapted for other shapes. See
%% makeshape.pdf for instructions.
%%
%% 25 January 2013
\usepackage{makeshape}
\makeatletter
%% Constant for sample shape
\def\gap{4pt}
%% Anchor path <- change and rename as required
\def\sampleanchor{
% get corrected text box
\pgf@xa=\ctbnex
\pgf@ya=\ctbney
% make room for shape
\advance\pgf@xa by \gap
\advance\pgf@ya by \gap
% correct for minheight and minwidth and
% for outerxsep or outerysep
\mincorrect{\pgf@xa}{\pgfshapeminwidth}
\advance\pgf@xa\pgfshapeouterxsep
\mincorrect{\pgf@ya}{\pgfshapeminheight}
\advance\pgf@ya\pgfshapeouterysep
% draw the path
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
\pgfpathclose
}
%% Background path <- change and rename as required
\def\sampleborder{
% get corrected text box
\pgf@xa=\ctbnex
\pgf@ya=\ctbney
% make room for shape
\advance\pgf@xa by \gap
\advance\pgf@ya by \gap
% correct for minheight and minwidth but
% not for outerxsep or outerysep
\mincorrect{\pgf@xa}{\pgfshapeminwidth}
\mincorrect{\pgf@ya}{\pgfshapeminheight}
% draw outer shape
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
\pgfpathclose
% draw inner shape
\advance\pgf@xa by -\gap
\advance\pgf@ya by -\gap
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
\pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
\pgfpathclose
}
%%------------------------------------------------
%% Shape declaration <- Change name as required
\pgfdeclareshape{sample}{
% Set paths <- change path macros as required
\setpaths{\sampleanchor}{\sampleborder}
% Saved anchors <- change as required
\savedanchor{\northeast}{
\pgf@x = \ctbnex
\pgf@y = \ctbney
\advance\pgf@x by \gap
\advance\pgf@y by \gap
\mincorrect{\pgf@x}{\pgfshapeminwidth}
\mincorrect{\pgf@y}{\pgfshapeminheight}
\advance\pgf@x\pgfshapeouterxsep
\advance\pgf@y\pgfshapeouterysep
}
% Anchors <- change as required
\anchor{north}{\northeast \pgf@x=0pt}
\anchor{north east}{\northeast}
\anchor{east}{\northeast \pgf@y=0pt}
\anchor{south east}{\northeast \pgf@y=-\pgf@y}
\anchor{south}{\northeast \pgf@x=0pt \pgf@y=-\pgf@y}
\anchor{south west}{\northeast \pgf@x=-\pgf@x \pgf@y=-\pgf@y}
\anchor{west}{\northeast \pgf@x=-\pgf@x \pgf@y=0pt}
\anchor{north west}{\northeast \pgf@x=-\pgf@x}
}
\makeatother
%</sample>
%\fi
%
\endinput