diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/modules')
10 files changed, 2995 insertions, 1448 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex new file mode 100644 index 00000000000..f0a28bfff68 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex @@ -0,0 +1,355 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulebending.code.tex,v 1.18 2013/09/30 18:30:15 tantau Exp $ + + +% +% This file defines commands for drawing bending arrows and lines. +% + +\usepgfmodule{nonlineartransformations} +\usepgflibrary{curvilinear} + + +% Configuration options for arrow tips: + +\pgfkeys{ + /pgf/arrow keys/flex/.code=\pgfarrowsaddtooptions{\pgf@arrows@the@rigidity#1pt\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex}, + /pgf/arrow keys/flex/.default=1, + /pgf/arrow keys/flex'/.code=\pgfarrowsaddtooptions{\pgf@arrows@the@rigidity#1pt\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex@prime}, + /pgf/arrow keys/flex'/.default=1, + /pgf/arrow keys/bend/.code=\pgfarrowsaddtooptions{\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@bend} +} + + +\def\pgf@arrow@mode@is@flex{1} +\def\pgf@arrow@mode@is@flex@prime{2} +\def\pgf@arrow@mode@is@bend{3} + +\newdimen\pgf@arrows@the@rigidity + +% +% +% Handle the end of a curve +% +% + +% First, the preparation. This is, essenatially, setting up the +% nonlinear transformation + +\def\pgf@prep@curveend{ + \pgftransformreset% + \pgfsetcurvilinearbeziercurve{\pgfpointlastonpath}{\pgfpointsecondlastonpath}{\pgfpointthirdlastonpath}{\pgfpointfourthlastonpath} +} + +% Second, the shortening. + +\def\pgf@do@shorten@curvedend{% + \expandafter\expandafter\expandafter\pgf@do@shorten@curvedend@unpack\expandafter\pgfpointfourthlastonpath\pgfpointthirdlastonpath% +} +\def\pgf@do@shorten@curvedend@unpack\pgfqpoint#1#2\pgfqpoint#3#4{% + \pgf@process{\pgfcurvilineardistancetotime{\pgf@path@shortening@distance}}% + % Compute new curve: + \pgfpointcurveattime{\pgf@x}{\pgfpointlastonpath}{\pgfpointsecondlastonpath}{\pgfpointthirdlastonpath}{\pgfpointfourthlastonpath}% + % \pgfx/y and \pgf xa/xb already correct. Need to setup remaining vector... + \pgf@xb#3% + \pgf@yb#4% + \pgf@xb\pgf@time@t\pgf@xb% + \pgf@yb\pgf@time@t\pgf@yb% + \advance\pgf@xb by\pgf@time@s\pgf@xc% + \advance\pgf@yb by\pgf@time@s\pgf@yc% + \edef\pgfprocessresultsubpathsuffix{% + \expandafter\noexpand\pgfsubpathfourthlasttoken{#1}{#2}% + \noexpand\pgfsyssoftpath@curvetosupportatoken{\the\pgf@xb}{\the\pgf@yb}% + \noexpand\pgfsyssoftpath@curvetosupportbtoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@curvetotoken{\the\pgf@x}{\the\pgf@y}}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}% +} + +% Third, the drawing + +\def\pgf@do@draw@curvedend{% + \pgf@do@draw@curved\pgf@end@tip@sequence% +} + +\def\pgf@do@draw@curved#1{% + {% + \pgftransformreset% + \pgf@xb\pgf@arrow@tip@total@length% xb will keep track of the total length + \let\pgf@arrow@handle\pgf@draw@curved% + \let\pgf@arrow@handle@dot\relax% + #1% + }% +} + +\def\pgf@draw@curved#1#2{% + % Prepare: + {% + \pgfarrows@getid{#1}{#2}% + % Do shift: + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname% + \expandafter\let\expandafter\pgf@arrow@bending@mode\csname pgf@ar@bending@mode@#1\endcsname% + \ifx\pgf@arrow@bending@mode\pgfutil@empty\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex\fi% + % do swap: + {% + \csname pgf@ar@saves@\pgf@arrow@id\endcsname% + \ifcase\pgf@arrow@flex@mode\relax% + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname% like flex + \or% + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname% + \or% + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@ends@\pgf@arrow@id\endcsname% + \or% + \pgf@arrow@drawer@bend% + \fi% + % hull points inside the above + }% + \expandafter}% + % Transform to next tip: + \expandafter\pgf@xb\the\pgf@xb% +} +\def\pgf@falsetext{false} + +\def\pgf@arrow@drawer@rigid@shift#1#2#3{% tip end, back end, line end, sep + % Let xa be the actual back end of the current arrow plus the back end: + \advance\pgf@xb by#2% + \pgf@xa\pgf@xb% + % Update the xb: + \pgf@x#1% + \advance\pgf@x by\pgfarrowsep% + \advance\pgf@xb by-\pgf@x% +} + + +\def\pgf@arrow@drawer@bend{% + \pgftransformnonlinear{\pgf@arrow@bending@mode{\pgf@x}{\pgf@y}} + \pgftransformscale{-1}% + \pgftransformxshift{-\pgf@xa}% + % Do slant: + \ifdim\pgfarrows@slant pt=0pt% + \else% + \pgftransformxslant{\pgfarrows@slant}% + \fi% + \ifpgfarrowswap% + \pgftransformyscale{-1}% + \fi% + {% + \pgf@relevantforpicturesizefalse% + \pgfscope% + \pgf@arrows@color@setup% + \csname pgf@ar@inst@code@\pgf@arrow@id\endcsname% + \endpgfscope% + }% + \pgf@arrows@bending@hull% +} + +\def\pgf@arrow@drawer@rigid#1#2#3{% (rigid) start, (rigid) end, dummy + % Compute the rigid positions: + \pgf@x#1% start + \pgf@y#2% flexibility*(end-start) + start + \advance\pgf@y by-\pgf@x% + \pgf@y\pgf@sys@tonumber\pgf@arrows@the@rigidity\pgf@y% + \advance\pgf@y by\pgf@x% + % Are they equal? + \ifdim\pgf@x=\pgf@y% + % Yes, do tangent: + \pgf@bending@do@tangent% + \else% + \pgf@bending@do@flex% + \fi% + \pgf@xc#1% + \pgf@xc-\pgf@xc% + \pgftransformxshift{+\pgf@xc}% + % Do slant: + \ifdim\pgfarrows@slant pt=0pt% + \else% + \pgftransformxslant{\pgfarrows@slant}% + \fi% + % do swap: + \ifpgfarrowswap% + \pgftransformyscale{-1}% + \fi% + \pgfscope% + \pgf@arrows@color@setup% + \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname% + \endpgfscope% + \pgf@arrows@rigid@hull% +} + +\def\pgf@bending@do@tangent{% + \pgf@xb\pgf@xa% + \advance\pgf@xb by-\pgf@x% + \pgfcurvilineardistancetotime{\pgf@xb}% + \pgf@xb\pgf@x% + % Compute points: + \ifdim\pgf@xb=0pt% + \pgf@bending@possible@degenerate% + \else% + \pgf@bending@do@tangent@normal% + \fi% + \pgf@ya-\pgf@y% + \pgfsettransformentries% + {\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% + {\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@x}{\pgf@xc}{\pgf@yc}% +}% + +\def\pgf@bending@do@tangent@normal{% + \pgfpointcurveattime{\pgf@xb}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}% + \pgf@xc\pgf@x% save + \pgf@yc\pgf@y% save + % compute normal: + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \pgf@process{\pgfpointnormalised{\pgf@x=\pgf@xb\pgf@y=\pgf@yb}} +} + +\def\pgf@bending@possible@degenerate{% + \ifx\pgf@curvilinear@line@a\pgf@curvilinear@line@b% degenerate! + \ifx\pgf@curvilinear@line@a\pgf@curvilinear@line@c% double degenerate! + \let\pgf@ref\pgf@curvilinear@line@d% + \else + \let\pgf@ref\pgf@curvilinear@line@c% + \fi% + \pgf@process{\pgf@curvilinear@line@a}% + \pgf@xc\pgf@x% save + \pgf@yc\pgf@y% save + \pgf@process{\pgf@ref}% + \advance\pgf@x by-\pgf@xc + \advance\pgf@y by-\pgf@yc + \pgf@process{\pgfpointnormalised{}} + \pgf@x-\pgf@x + \pgf@y-\pgf@y + \else% + \pgf@bending@do@tangent@normal% + \fi% +} + +\def\pgf@bending@do@flex{ + \pgf@xb\pgf@xa% + \pgf@xc\pgf@xa% + \advance\pgf@xc by-\pgf@x% + \advance\pgf@xb by-\pgf@y% + \pgfcurvilineardistancetotime{\pgf@xc}% + \pgf@xc\pgf@x% + \pgfcurvilineardistancetotime{\pgf@xb}% + \pgf@xb\pgf@x% + % Compute points: + \pgf@process{\pgfpointcurveattime{\pgf@xc}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \pgf@process{\pgfpointcurveattime{\pgf@xb}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \pgftransformarrow{\pgfqpoint{\pgf@xb}{\pgf@yb}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}% +} + + + + + + +% Convex hull stuff: + +\def\pgf@arrows@bending@hull{% + \ifpgf@relevantforpicturesize% + % Do bb update: + \expandafter\let\expandafter\pgf@temp\csname pgf@ar@hull@\pgf@arrow@id\endcsname% + \ifx\pgf@temp\pgfutil@empty\else% + \let\pgf@arrow@hull@point\pgf@arrow@bending@hull@point@first% + \pgf@temp% + \pgf@arrow@bending@update@bb% + \fi% + \fi% +} + +\def\pgf@arrow@bending@hull@point@first#1#2{% + \pgfpointtransformednonlinear{\pgfqpoint{#1}{#2}}% + \pgf@xa\pgf@x\pgf@xb\pgf@x% + \pgf@ya\pgf@y\pgf@yb\pgf@y% + \let\pgf@arrow@hull@point\pgf@arrow@bending@hull@point@other% +} +\def\pgf@arrow@bending@hull@point@other#1#2{% + \pgfpointtransformednonlinear{\pgfqpoint{#1}{#2}}% + \ifdim\pgf@x<\pgf@xa\pgf@xa\pgf@x\else\ifdim\pgf@x>\pgf@xb\pgf@xb\pgf@x\fi\fi% + \ifdim\pgf@y<\pgf@ya\pgf@ya\pgf@y\else\ifdim\pgf@y>\pgf@yb\pgf@yb\pgf@y\fi\fi% +} + +\def\pgf@arrow@bending@update@bb{% + \ifdim\pgf@picmaxx=-16000pt\relax% + \global\pgf@picminx\pgf@xa% + \global\pgf@picmaxx\pgf@xb% + \global\pgf@picminy\pgf@ya% + \global\pgf@picmaxy\pgf@yb% + \else% + \ifdim\pgf@xa<\pgf@picminx\global\pgf@picminx\pgf@xa\fi% + \ifdim\pgf@ya<\pgf@picminy\global\pgf@picminy\pgf@ya\fi% + \ifdim\pgf@xb>\pgf@picmaxx\global\pgf@picmaxx\pgf@xb\fi% + \ifdim\pgf@yb>\pgf@picmaxy\global\pgf@picmaxy\pgf@yb\fi% + \fi% +} + + + + +% +% +% Handle the start of a curve +% +% + + +% First, the preparation. + +\def\pgf@prep@curvedstart{ + \pgftransformreset% + \pgfsetcurvilinearbeziercurve{\pgfpointfirstonpath}{\pgfpointsecondonpath}{\pgfpointthirdonpath}{\pgfpointfourthonpath}% +} + +% Second, the shortening. + +\def\pgf@do@shorten@curvedstart{% + \expandafter\expandafter\expandafter\pgf@do@shorten@curvedstart@unpack\expandafter\pgfpointthirdonpath\pgfpointfourthonpath% +} +\def\pgf@do@shorten@curvedstart@unpack\pgfqpoint#1#2\pgfqpoint#3#4{% + \pgf@process{\pgfcurvilineardistancetotime{\pgf@path@shortening@distance}}% + % Compute new curve: + \pgfpointcurveattime{\pgf@x}{\pgfpointfirstonpath}{\pgfpointsecondonpath}{\pgfpointthirdonpath}{\pgfpointfourthonpath}% + % \pgfx/y and \pgf xa/xb already correct. Need to setup remaining vector... + \pgf@xb#1% + \pgf@yb#2% + \pgf@xb\pgf@time@t\pgf@xb% + \pgf@yb\pgf@time@t\pgf@yb% + \advance\pgf@xb by\pgf@time@s\pgf@xc% + \advance\pgf@yb by\pgf@time@s\pgf@yc% + \edef\pgfpointfirstonpath{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \edef\pgfpointsecondonpath{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \edef\pgfprocessresultpathsuffix{% + \noexpand\pgfsyssoftpath@movetotoken{\the\pgf@x}{\the\pgf@y}% + \noexpand\pgfsyssoftpath@curvetosupportatoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@curvetosupportbtoken{\the\pgf@xb}{\the\pgf@yb}% + \noexpand\pgfsyssoftpath@curvetotoken{#3}{#4}% + } + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathsuffix\pgfsubpathend}% +} + + +% Third, the drawing + +\def\pgf@do@draw@curvedstart{% + \pgf@do@draw@curved\pgf@start@tip@sequence% +} + + + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex index 1c78bb221e6..243f8ce225d 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduledatavisualization.code.tex,v 1.37 2010/08/24 21:28:58 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduledatavisualization.code.tex,v 1.47 2013/07/19 13:16:48 tantau Exp $ \usepgfmodule{oo,shapes} \usepgflibrary{fpu} @@ -156,6 +156,7 @@ \def\pgfdvpathlinetotoken{6} \def\pgfdvdirectionfromtoken{7} \def\pgfdvdirectiontotoken{8} + \def\pgfdvdirectionattoken{9} % Method % @@ -169,7 +170,10 @@ % Add data that is to be visualized. The code #1 should call the % \pgfdatapoint macro for each data point it creates. \method add data(#1) { - \pgfooappend{data}{#1} + \pgf@dv@stripped@add#1\pgf@stop + } + \def\pgf@dv@stripped@add#1\pgf@stop{% + \pgfooappend{data}{#1}% } @@ -480,20 +484,22 @@ -% Compute a normalized vector pointing from some point to another. +% Compute a normalized vector at the current point pointing along a +% line from #1 to #2. % % #1 = code for setting the attributes of the first point % #2 = code for setting the attributes of the second point % -% Using #1 and #2 you specify two data points. These are then -% localized on the canvas and a vector pointing from the first data -% point to the second one is returned. However, for instance in polar +% The current point should be a point on a line from #1 to +% #2. Both points as well as the current point are +% localized on the canvas and a vector pointing from the first point +% to the second one is returned. However, for instance in polar % coordinates the vector may actually "point along" the angle axis. % % Internally, this command first sets up the first data point and then -% emits a "path" signal with the \pgfdvpathdirectionfromtoken set and +% emits a "direction" signal with the \pgfdvpathdirectionfromtoken set and % then sets up the second point and emits the corresponding -% ...totoken. +% ...totoken. Finally, the \pgfdvpathdirectionattoken is emitted. % \def\pgfpointdvdirection#1#2{% @@ -504,16 +510,14 @@ } { #2 - \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{ - \edef\pgf@dv@dir@xa{\the\pgf@x} - \edef\pgf@dv@dir@ya{\the\pgf@y} + \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{\xdef\pgf@dv@to{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}} + } + {\pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectionattoken}{% \pgf@process{ \pgfpointnormalised{% - \pgfpointdiff{\pgf@dv@from}{\pgfqpoint{\pgf@dv@dir@xa}{\pgf@dv@dir@ya}} + \pgfpointdiff{\pgf@dv@from}{\pgf@dv@to} } - } - } - } + }}} } } @@ -529,7 +533,7 @@ -% Run the rendering pipeline on a dataset. +% Run the rendering pipeline on a dataset and/or save the dataset. % % #1 = options with path /pgf/data/ % #2 = optionally data given inline in curly braces. @@ -541,14 +545,27 @@ % accumulate. Data can be in different formats, as specified by the % "format" key, and you can define new formats. % -% The setting of the following keys is important: +% The settings of the following keys are important: +% +% /pgf/data visualization/obj +% contains a handle to the dv-object +% +% /pgf/data/format +% stores the format (see below) +% +% /pgf/data/read from file +% determines where the data is. +% +% /pgf/data/store in group +% when nonempty, the data is stored here instead of being fed to the +% rendering pipeline % -% /pgf/data visualization/obj contains a handle to the dv-object -% /pgf/data/format stores the format (see below) -% /pgf/data/source determines where the data is. +% /pgf/data/use group +% when nonempty, data that has previsouly been stored here using +% |define group| is read from here and all other keys are ignored % -% If source is empty, the data is stored in the argument that -% follows. Otherwise, the file whose name is stored in source is read. +% If "read from file" is empty, the data is stored in the argument that +% follows. Otherwise, the data is read from the specified source file. % This data is stored in an internal variable, which is local to the % current group. % @@ -594,51 +611,78 @@ % 2200, 2300, 2250, 2260 % } % -% \pgfdata[source=data,format=comma separated columns] +% \pgfdata[read from file=data.csv,format=comma separated columns] % % \dv.survey() % \dv.visualize() -\def\pgfdata{\pgfutil@ifnextchar[{\pgf@dataset@data@opt}{\pgf@dataset@data@opt[]}}%} -\def\pgf@dataset@data@opt[#1]{% +\def\pgfdata{\pgfutil@ifnextchar[{\pgf@datagroup@data@opt}{\pgf@datagroup@data@opt[]}}%} +\def\pgf@datagroup@data@opt[#1]{% % Ok, add one data thing... - \pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgf@do@data{#1})% \begingroup% \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}% \pgfkeysgetvalue{/pgf/data/continue code}\pgf@dv@cont@code% \global\let\pgf@dv@cont@code\pgf@dv@cont@code% - \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format% - \expandafter\let\expandafter\pgf@dv@format@catcodes\csname pgfdv@format@\pgf@dv@format @catcodes\endcsname% - \ifx\pgf@dv@format@catcodes\relax - \PackageError{pgf}{Unknown data format '\pgf@dv@format'}{}% + \pgfkeysgetvalue{/pgf/data/use group}\pgf@dv@use@group% + \ifx\pgf@dv@use@group\pgfutil@empty% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgf@do@data{#1})}% + \expandafter\pgf@datagroup@data@opt@cont% \else% - \pgfkeysgetvalue{/pgf/data/source}\pgf@dv@source% - \ifx\pgf@dv@source\pgfutil@empty% - \let\pgf@next\pgf@dataset@grab@inline% + \expandafter\ifx\csname pgf@dv@group@@\pgf@dv@use@group\endcsname\relax% + \pgferror{Undefined data group '\pgf@dv@use@group'}% \else% - \let\pgf@next\pgf@dataset@grab@external% + {% + \pgfkeys{/pgf/data/define group/.code=}% no redefinitions during use + \csname pgf@dv@group@@\pgf@dv@use@group\endcsname% + }% \fi% - \pgf@next% + \endgroup% + \expandafter\pgf@dv@cont@code% + \fi% +} +\def\pgf@datagroup@data@opt@cont{% + \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format% + \expandafter\let\expandafter\pgf@dv@format@catcodes\csname pgfdv@format@\pgf@dv@format @catcodes\endcsname% + \ifx\pgf@dv@format@catcodes\relax + \pgferror{Unknown data format '\pgf@dv@format'}% + \else% + \pgfkeysgetvalue{/pgf/data/read from file}\pgf@dv@source% + \ifx\pgf@dv@source\pgfutil@empty% + \let\pgf@next\pgf@datagroup@grab@inline% + \else% + \let\pgf@next\pgf@datagroup@grab@external% + \fi% + \pgf@next% } -\def\pgf@dataset@grab@inline{% + +\def\pgf@datagroup@grab@inline{% \pgfutil@ifnextchar\bgroup{% \begingroup% \catcode`\^^M=\active% \pgf@dv@format@catcodes% - \pgf@dataset@grab@@inline}% - {\PackageError{pgf}{Opening brace expected}{}}% + \pgf@datagroup@grab@@inline}% + {\pgferror{Opening brace expected}}% } -\def\pgf@dataset@grab@external{% +\def\pgf@datagroup@grab@external{% \fi% \endgroup% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@external}}})% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@external}}})}% \pgf@dv@cont@code% } +\def\pgf@dv@do@adddata#1{% + \pgfkeysgetvalue{/pgf/data/store in group}\pgf@dv@temp% + \ifx\pgf@dv@temp\pgfutil@empty% + #1% + \else% + \expandafter\pgfutil@g@addto@macro\csname pgf@dv@group@@\pgf@dv@temp\endcsname{#1}% + \fi% +} + {\catcode`\^^M=\active% - \gdef\pgf@dataset@grab@@inline#1{% + \gdef\pgf@datagroup@grab@@inline#1{% \endgroup% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@inline#1^^M\pgf@@eol}}})% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@inline#1^^M\pgf@@eol}}})}% \fi% \endgroup% \pgf@dv@cont@code% @@ -663,19 +707,19 @@ % Read external file % -\def\pgf@dataset@do@external{% +\def\pgf@datagroup@do@external{% \csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@catcodes\endcsname% - \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/source} % + \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/read from file} % \ifeof\r@pgf@reada\relax - \PackageError{pgf}{Data source '\pgfkeysvalueof{/pgf/data/source}' not found}{}% + \pgferror{Data file '\pgfkeysvalueof{/pgf/data/read from file}' not found}% \else - \pgf@dataset@readline% + \pgf@datagroup@readline% \fi \immediate\closein\r@pgf@reada% } \def\pgf@partext{\par}% -\def\pgf@dataset@readline{% +\def\pgf@datagroup@readline{% \immediate\read\r@pgf@reada to \pgf@temp% \ifx\pgf@temp\pgf@partext% \pgf@dv@format@emptyline% @@ -686,7 +730,7 @@ \expandafter\pgf@dv@format@line\pgf@temp\pgfeol% \fi% \fi% - \ifeof\r@pgf@reada\else\expandafter\pgf@dataset@readline\fi% + \ifeof\r@pgf@reada\else\expandafter\pgf@datagroup@readline\fi% } @@ -694,7 +738,7 @@ % Read inline data % -\def\pgf@dataset@do@inline{% +\def\pgf@datagroup@do@inline{% \pgf@dv@handle@line% } @@ -712,8 +756,12 @@ \pgfkeys{ /pgf/data/data visualization obj/.initial=\undefined, /pgf/data/format/.initial=table,% the default format - /pgf/data/source/.initial=, - /pgf/data/continue code/.initial= + /pgf/data/read from file/.initial=, + /pgf/data/inline/.style={read from file=}, + /pgf/data/continue code/.initial=, + /pgf/data/store in group/.initial=, + /pgf/data/new group/.code={\expandafter\global\expandafter\let\csname pgf@dv@group@@#1\endcsname\pgfutil@empty}, + /pgf/data/use group/.initial=, } @@ -737,7 +785,7 @@ % a data set is visualized and the format is set to #1, this handler % is used to parse the data. % -% In detail, the \dataset command will select a source. Before this +% In detail, the \pgfdata command will select a source. Before this % source is read, #2 will be executed to setup the % catcodes. Additionally, each time the data is parsed, #3 will be % called. Then, for each nonempty line of the source, the @@ -791,12 +839,23 @@ % % Example: % -% \data[format=key value pairs] { +% \data[format=named] { % x=5, y=6, hi=9 % x=7, y=6, lo=10 % } -\pgfdeclaredataformat{key value pairs}{}{}{#1}{{\pgfkeys{/data point/.cd,#1}\pgfdatapoint}}{}{} +\pgfdeclaredataformat{named}{}{}{#1}{\pgf@dv@parse@named#1,\pgf@stop}{}{} +\def\pgf@dv@parse@named{% + \pgfutil@ifnextchar\pgf@stop{\pgfdatapoint\pgfutil@gobble}{\pgf@dv@parse@named@} +} +\def\pgf@dv@parse@named@#1=#2,#3\pgf@stop{% + \foreach \pgf@dv@temp in {#2} {% + \def\pgf@dv@tempb{/data point/#1=}% + \expandafter\expandafter\expandafter\pgfkeys% + \expandafter\expandafter\expandafter{\expandafter\pgf@dv@tempb\pgf@dv@temp}% + \pgf@dv@parse@named#3\pgf@stop% + } +} @@ -892,7 +951,7 @@ \def\pgf@dv@parse@table{% \pgfutil@ifnextchar"% Special, but ignored right now... - {\PackageError{pgf}{csv with quotes not yet implemented}{}} + {\pgferror{csv with quotes not yet implemented}} {\pgf@dv@till@separator} } \def\pgf@dv@table@handle#1{% @@ -924,7 +983,7 @@ \def\pgf@dv@doparse@headline{% \pgfutil@ifnextchar"% Special, but ignored right now... - {\PackageError{pgf}{csv with quotes not yet implemented}{}} + {\pgferror{csv with quotes not yet implemented}} {\pgf@dv@till@separator@head} } \def\pgf@dv@head@handle#1{% @@ -1158,6 +1217,27 @@ \let#1=\pgfmathresult% } +% Multiply by small number +% +% #1 = macro that should store the result of applying the +% corresponding operation to the following: +% #2 = entered number +% #3 = fixed point number like 2 or 0.5, but not 10000000000 +% +% Description: +% +% Sets #1 to the result of applying an operation to #2 and #3 +% +% Example: +% +% \pgfdvmathenter{\a}{2000} +% \pgfdvmathadd{\b}{\a}{0.2} +% % \b now stores 400 + +\def\pgfdvmathmulfixed#1#2#3{% + \pgfmathfloatmultiplyfixed{#2}{#3}% + \let#1=\pgfmathresult% +} @@ -1457,12 +1537,15 @@ \attribute out min; % Start of the second range (the value of c). + \attribute out min; + % End of the second range (the value of d). + \attribute trans in min; % Transformed value of the start of the first range (the value % f(a)). \attribute scale; - % The scaling factor, that is, the value of (f(d)-f(c))/(b-a). + % The scaling factor, that is, the value of (f(b)-f(a))/(d-c). % Constructor @@ -1540,6 +1623,7 @@ \pgfdvmathenter{\pgf@out@interval@max}{#4} % Let's start with the output, it's easier... \pgfoolet{out min}{\pgf@out@interval@min} + \pgfoolet{out max}{\pgf@out@interval@max} \pgfdvmathsub{\pgf@out@diff}{\pgf@out@interval@max}{\pgf@out@interval@min} \let\pgfvalue=\pgf@in@interval@min \pgfoovalueof{trans} @@ -1568,8 +1652,10 @@ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}}\pgf@dv@external@value% \fi% \ifx\pgf@dv@external@value\pgfutil@empty% + \pgf@dv@mapper@pos@check% \else% \ifx\pgf@dv@external@value\relax% + \pgf@dv@mapper@pos@check% \else% % % Clip? \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% @@ -1581,20 +1667,20 @@ % \fi% \fi% \fi% - \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/min}\pgf@dv@external@value% - \ifx\pgf@dv@external@value\relax\else% - \ifx\pgf@dv@external@value\pgfutil@empty\else% - \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% - \pgf@dv@mapper@trans{/min} - \fi - \fi - \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/max}\pgf@dv@external@value% - \ifx\pgf@dv@external@value\relax\else% - \ifx\pgf@dv@external@value\pgfutil@empty\else% - \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% - \pgf@dv@mapper@trans{/max} - \fi - \fi +% \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/min}\pgf@dv@external@value% +% \ifx\pgf@dv@external@value\relax\else% +% \ifx\pgf@dv@external@value\pgfutil@empty\else% +% \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% +% \pgf@dv@mapper@trans{/min} +% \fi +% \fi +% \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/max}\pgf@dv@external@value% +% \ifx\pgf@dv@external@value\relax\else% +% \ifx\pgf@dv@external@value\pgfutil@empty\else% +% \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% +% \pgf@dv@mapper@trans{/max} +% \fi +% \fi \fi% } @@ -1616,6 +1702,22 @@ \pgfdvmathexitbyserializing{\pgf@temp}{\pgfvalue}% \pgfkeyslet{/data point/\pgfoovalueof{out}#1}\pgf@temp% } + + \def\pgf@dv@mapper@pos@check{% + \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/out pos}\pgf@dv@pos@value% + \ifx\pgf@dv@pos@value\relax\else\if\pgf@dv@pos@value\pgfutil@empty\else% + \pgfmathsetmacro{\pgf@dv@pos@num}{\pgf@dv@pos@value}% + \pgfmathsetmacro{\pgf@dv@pos@num@prime}{1-\pgf@dv@pos@num}% + % Ok, compute transformed min position: + \pgfooget{out min}{\pgf@out@interval@min} + \pgfooget{out max}{\pgf@out@interval@max} + \pgfdvmathmulfixed{\pgf@out@interval@min}{\pgf@out@interval@min}{\pgf@dv@pos@num@prime} + \pgfdvmathmulfixed{\pgf@out@interval@max}{\pgf@out@interval@max}{\pgf@dv@pos@num} + \pgfdvmathadd{\pgf@out@val}{\pgf@out@interval@min}{\pgf@out@interval@max}% + \pgfdvmathexitbyserializing{\pgf@temp}{\pgf@out@val}% + \pgfkeyslet{/data point/\pgfoovalueof{out}}\pgf@temp% + \fi\fi% + } } @@ -1868,8 +1970,15 @@ % "seen" during the survey phase. Based on this value, the size of, % say, an axis can be detemined later on. % - % In case the attribute has the sub-attributes "min" and "max", they - % are also taken into account. + % You can also set the key "sub attributes" of the attribute. In + % this case, this key should contain -- as the name suggests -- a + % list of subkeys that should also be taken into account for the + % computation of the minimum and maximum value. Inside the "sub + % attributes" key, each subkey should be surrounded by a call of + % \pgfdvsub. For instance, if there are two sub attributes "/data + % point/velocity/min" and "/data point/velocity/max" for a key + % "/data point/velocity", then "/data point/velocity/sub attributes" + % should be set to "\pgfdvsub{/min}\pgfdvsub{/max}". \attribute attribute; % The to-be-surveyed attribute @@ -1902,9 +2011,12 @@ % Adjust the interval as if during the survey this value were % encountered \method include attribute value(#1) { - \def\pgf@dv@val{#1} + \pgf@dv@assign@val@stripped#1\pgf@stop% \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) } + \def\pgf@dv@assign@val@stripped#1\pgf@stop{% + \def\pgf@dv@val{#1} + } % Slot % @@ -1913,34 +2025,36 @@ % interval. % \method survey() { - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}\pgf@dv@val% - \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/min}\pgf@dv@val% - \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/max}\pgf@dv@val% - \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) + \let\pgfdvsub\pgf@dv@range@surv@sub + \pgfdvsub{}% + \pgfkeysvalueof{/data point/\pgfoovalueof{attribute}/sub attributes} } - \def\pgf@dv@range@surv{% + \def\pgf@dv@range@surv@sub#1{ + \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}#1}\pgf@dv@val% \ifx\pgf@dv@val\relax% \else% \edef\pgf@dv@val{\pgf@dv@val}% \ifx\pgf@dv@val\pgfutil@empty% \else% - \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}% - % Now, protocol value - \ifx\pgfdvmin\pgfutil@empty% - \let\pgfdvmin\pgf@dv@value% - \else% - \pgfdvmathifless{\pgf@dv@value}{\pgfdvmin}{\let\pgfdvmin\pgf@dv@value}{}% - \fi% - \ifx\pgfdvmax\pgfutil@empty% - \let\pgfdvmax\pgf@dv@value% - \else% - \pgfdvmathifless{\pgfdvmax}{\pgf@dv@value}{\let\pgfdvmax\pgf@dv@value}{}% - \fi% + \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)% \fi% - \fi + \fi% + } + + \def\pgf@dv@range@surv{% + \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}% + % Now, protocol value + \ifx\pgfdvmin\pgfutil@empty% + \let\pgfdvmin\pgf@dv@value% + \else% + \pgfdvmathifless{\pgf@dv@value}{\pgfdvmin}{\let\pgfdvmin\pgf@dv@value}{}% + \fi% + \ifx\pgfdvmax\pgfutil@empty% + \let\pgfdvmax\pgf@dv@value% + \else% + \pgfdvmathifless{\pgfdvmax}{\pgf@dv@value}{\let\pgfdvmax\pgf@dv@value}{}% + \fi% } } @@ -1976,6 +2090,10 @@ % filter should set \pgfdvfilterpassedfalse for to-be-filtered data % point. % + % You can specify "projection code" that changes the canvas x and + % canvas y positions. This projection code allows you to draw, say, + % projected points instead of the actual data point. + % % The keys /data point/<name>/execute at begin and /data % point/<name>/execute at end, where <name> is the name of % the visualizer, should store code that is to be executed directly @@ -1987,7 +2105,7 @@ % The to-be-used handlers \attribute name; - % Filter code + % The attribute \attribute filter=\pgfdvnamedvisualizerfilter; % Filter code @@ -2000,7 +2118,15 @@ % cache. Every 100 steps this cache is moved to positions. The idea % behind this is that it will avoid the quadratic time increase that % is normally caused when a protocol is build in TeX. - + + \attribute projection code; + % This code is empty by default. However, you can set it for + % instance to the following + % + % \pgfkeyssetvalue{/data point/y=0}\pgfdvmapdatapointtocanvas + % + % in order to visualize the data point with its y-coordinate + % replaced by 0. % Constructor % @@ -2025,6 +2151,11 @@ \pgfooset{filter}{#1} } + % Setter + \method set projection code(#1) { + \pgfooset{projection code}{#1} + } + % Slot \method protocol() { \pgfdvfilterpassedtrue @@ -2037,7 +2168,17 @@ \def\pgf@dv@line@cache@it{ % Cache it \pgfooget{cache}\pgf@dv@cache - \edef\pgf@dv@add{\noexpand\pgf@dv@ph{\pgfkeysvalueof{/data point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}}% + \pgfkeysgetvalue{/data point/outlier}\pgf@temp% + \ifx\pgf@temp\pgfutil@empty + {% + \pgfoovalueof{projection code} + \xdef\pgf@dv@add{\noexpand\pgf@dv@ph{\pgfkeysvalueof{/data + point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}}% + } + \else% + % An outlier! + \gdef\pgf@dv@add{\pgf@dv@outliner}% + \fi% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\pgf@dv@cache% \expandafter\expandafter\expandafter{\expandafter\pgf@dv@cache\pgf@dv@add}% @@ -2072,10 +2213,10 @@ \else \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin} \tikz@dv@temp - \pgfplotstreamstart + \pgfdvnewstreamtrue \pgfoovalueof{positions} \pgfoovalueof{cache} - \pgfplotstreamend + \ifpgfdvnewstream\else\pgfplotstreamend\fi \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end} \fi } @@ -2084,15 +2225,22 @@ \pgfoolet{cache}\pgfutil@empty } - \def\pgf@dv@ph#1#2{\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} + \def\pgf@dv@ph#1#2{\ifpgfdvnewstream\pgfplotstreamstart\pgfdvnewstreamfalse\fi\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} + \def\pgf@dv@outliner{\ifpgfdvnewstream\else\pgfplotstreamend\pgfdvnewstreamtrue\fi} } +\newif\ifpgfdvnewstream \newcount\pgf@lib@dv@cache@count +\pgfkeys{% + /data point/outlier/.initial=, + /data point/outlier/.default=true +} + % A possible filter for unnamed visualizers % -% #1 = Text to be compared with key /data point/visualizer +% #1 = Text to be compared with key /data point/set % % Description: % @@ -2103,10 +2251,10 @@ % point/visualizer. % % When objects allow you to set a filter, you can use this filter to -% test against /data point/visualizer being equal to #1. +% test against /data point/set being equal to #1. \def\pgfdvvisualizerfilter#1{% - \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer% + \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer% \def\pgf@temp{#1}% \ifx\pgf@temp\pgf@dv@visualizer% \else @@ -2122,10 +2270,10 @@ % % This filter works like \pgfdvvisualizerfilter, only it assumes the % the object defines a "name" attribute. In this case, the value of -% /data point/visualizer is tested against this attribute. +% /data point/set is tested against this attribute. \def\pgfdvnamedvisualizerfilter{% - \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer% + \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer% \pgfooget{name}\pgf@temp% \ifx\pgf@temp\pgf@dv@visualizer% \else @@ -2140,16 +2288,19 @@ % Class rectangle visualizer % % This visualizer visualizes a datapoint as a rectangle. It needs - % two attributes a1 and a2, each of which must have min and max - % subattributes. Then, it draws a rectangle between (a1/min,a2/min) - % and (a1/max,a2/max). - - \attribute attribute 1; - \attribute attribute 2; - % The attributes + % a name, so that /data point/<name>/attribute 1 and /data + % point/<name>/attribute 2 store two attributes names a1 to a2. Then, + % provided the current value of /data point/set equals name, for + % each data point a rectangle between (a1/min,a2/min) and + % (a1/max,a2/max) is created. + - \attribute use path attribute; - % The attribute that stores the to-be-taken action + \attribute name; + % The name + + \attribute a1; + \attribute a2; + % The attributes, filled from /data point/<name>/attribute 1 and 2 % Constructor @@ -2157,47 +2308,65 @@ % #1 = first attribute % #2 = second attribute % - \method rectangle visualizer(#1,#2,#3) { - \pgfooset{attribute 1}{#1} - \pgfooset{attribute 2}{#2} - \pgfooset{use path attribute}{#3} + \method rectangle visualizer(#1) { + \pgfooset{name}{#1} } % Method \method default connects() { \pgfoothis.get handle(\pgf@dv@me) \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,visualize,visualize datapoint signal) + \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal) } - + + % Slot + \method phase(#1) {% + \ifx#1\pgfdvbeginsurvey% + \pgfooeset{a1}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 1}} + \pgfooeset{a2}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 2}} + \pgfkeyssetvalue{\pgfoovalueof{a1}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}} + \pgfkeyssetvalue{\pgfoovalueof{a2}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}} + \fi% + } + % Slot \method visualize() { { - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 1}/min}\pgf@dv@amin - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 1}/max}\pgf@dv@amax - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 2}/min}\pgf@dv@bmin - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 2}/max}\pgf@dv@bmax + \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer% + \pgfooget{name}\pgf@temp% + \ifx\pgf@temp\pgf@dv@visualizer% + \pgf@dv@rect@do + \fi + } + } + + \def\pgf@dv@rect@do{ + \pgfkeysgetvalue{\pgfoovalueof{a1}/min}\pgf@dv@amin \ifx\pgf@dv@amin\relax\else\ifx\pgf@dv@amin\pgfutil@empty\else - \ifx\pgf@dv@bmin\relax\else\ifx\pgf@dv@bmin\pgfutil@empty\else + \pgfkeysgetvalue{\pgfoovalueof{a1}/max}\pgf@dv@amax \ifx\pgf@dv@amax\relax\else\ifx\pgf@dv@amax\pgfutil@empty\else + \pgfkeysgetvalue{\pgfoovalueof{a2}/min}\pgf@dv@bmin + \ifx\pgf@dv@bmin\relax\else\ifx\pgf@dv@bmin\pgfutil@empty\else + \pgfkeysgetvalue{\pgfoovalueof{a2}/max}\pgf@dv@bmax \ifx\pgf@dv@bmax\relax\else\ifx\pgf@dv@bmax\pgfutil@empty\else - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amin} - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmin} - \pgfpathdvmoveto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmax} - \pgfpathdvlineto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amax} - \pgfpathdvlineto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmin} - \pgfpathdvlineto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amin} - \pgfpathdvlineto - \pgfpathclose - \pgfkeysvalueof{/data point/\pgfoovalueof{use path attribute}} + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin} + \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin} + \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin} + \pgfpathdvmoveto + \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmax} + \pgfpathdvlineto + \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amax} + \pgfpathdvlineto + \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin} + \pgfpathdvlineto + \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin} + \pgfpathdvlineto + \pgfpathclose + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end} \fi\fi \fi\fi \fi\fi \fi\fi - } } } @@ -2253,10 +2422,7 @@ % \method label visualizer(#1,#2,#3,#4) { \pgfooset{attribute}{#1} - \ifx#2\pgfutil@empty - \else - \pgfdvmathenter{\pgf@temp}{#2} - \fi + \expandafter\pgfdvmathenter\expandafter{\expandafter\pgf@temp\expandafter}\expandafter{#2} \pgfoolet{threshold}\pgf@temp \pgfooset{code}{#3} \pgfooset{filter}{#4} @@ -2532,6 +2698,10 @@ } % Method + \method default connects() { + } + + % Method \method add entry(#1) { \pgfooappend{entries}{{#1}} \c@pgf@counta=\pgfoovalueof{number of entries}\relax% @@ -2795,6 +2965,12 @@ \method set max(#1) { \pgfooset{max}{#1} } + \method let min(#1) { + \pgfoolet{min}{#1} + } + \method let max(#1) { + \pgfoolet{max}{#1} + } % Getter % @@ -2835,16 +3011,9 @@ % present or that have a certain property. By default, for every % data point a counter is incremented and the value of this counter % is stored in an attribute. You can also specify an increment for - % the counter and some action that should be taken when the counter - % reaches zero. You can also specify that certain data points should + % the counter. You can specify that certain data points should % not have an effect on the counter. - % - % Counters can serve different purposes. - % - % 1. For plotting points in a table or sequence, the counter can be - % used to provide the position along one axis. - % 2. By using the counter as a repetitive count down one can for - % instance have only every 10th data point be marked. + \attribute attribute; % The attribute that will be set to the current value of the counter @@ -2852,6 +3021,9 @@ \attribute val=0; % The current value of the counter + \attribute max=0; + % The current value of the counter + \attribute step=1; % The stepping by which the counter is incremented for each % datapoint @@ -2880,6 +3052,11 @@ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal) } + % Getter + \method get max(#1) { + \pgfooget{max}{#1} + } + % Setter \method set value(#1) { \pgfooset{val}{#1} @@ -2889,6 +3066,7 @@ % Setter \method set start value(#1) { \pgfooset{start val}{#1} + \pgfooset{max}{#1} } % Setter @@ -2909,6 +3087,11 @@ \pgfmathparse{\pgfoovalueof{val}+\pgfoovalueof{step}}% \pgfoolet{val}\pgfmathresult% \pgfkeyslet{/data point/\pgfoovalueof{attribute}}\pgfmathresult% + \ifdim\pgfmathresult pt>\pgfoovalueof{max}pt\relax% + \pgfoolet{max}\pgfmathresult% + \fi% + \pgfooget{max}\pgfmathresult% + \pgfkeyslet{/data point/\pgfoovalueof{attribute}/max}\pgfmathresult% \fi% } diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex index 9834e91f0ec..c2bf2582a29 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex @@ -92,8 +92,8 @@ \long\def\pgfdeclaredecoration#1#2#3{% \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone% \pgfifmetadecoration{#1}{% - \PackageError{pgf}{You cannot declare a decoration of the same - name as a meta-decoration}{}% + \pgferror{You cannot declare a decoration of the same + name as a meta-decoration}% \let\pgf@mod@dec@next=\pgfutil@gobble% }{}% \pgf@mod@dec@next @@ -141,8 +141,8 @@ \long\def\pgfdeclaremetadecoration#1#2#3{% \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone% \pgfifdecoration{#1}{% - \PackageError{pgf}{You cannot declare a meta-decoration of the - same name as a decoration}{}% + \pgferror{You cannot declare a meta-decoration of the + same name as a decoration}% \let\pgf@mod@dec@next=\pgfutil@gobble% }{}% \pgf@mod@dec@next{% @@ -193,38 +193,38 @@ % % Example: % -% \pgfdeclaredecoration{circles}{red circles}{ -% \state{red circles}[width=10pt, repeat state=2, next state=blue circles] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetstrokecolor{red!\pgfmathresult!brown} -% \pgfsetfillcolor{orange!\pgfmathresult!yellow} -% \pgfpathcircle{\pgfpointorigin}{2.5pt} -% \pgfusepath{stroke,fill} -% } -% \state{blue circles}[width=10pt, repeat state=1, next state=red circles] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetstrokecolor{blue!\pgfmathresult!gray} -% \pgfsetfillcolor{blue!\pgfmathresult!white} -% \pgfpathcircle{\pgfpointorigin}{2.5pt} -% \pgfusepath{stroke,fill} -% } -% \state{final}{} -% } -% -% \pgfpicture -% \pgfdecoratepath{circles} -% { -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{3cm}}{\pgfpoint{4cm}{0cm}}{\pgfpoint{4cm}{3cm}} -% } -% \endpgfpicture +% \pgfdeclaredecoration{circles}{red circles}{ +% \state{red circles}[width=10pt, repeat state=2, next state=blue circles] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetstrokecolor{red!\pgfmathresult!brown} +% \pgfsetfillcolor{orange!\pgfmathresult!yellow} +% \pgfpathcircle{\pgfpointorigin}{2.5pt} +% \pgfusepath{stroke,fill} +% } +% \state{blue circles}[width=10pt, repeat state=1, next state=red circles] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetstrokecolor{blue!\pgfmathresult!gray} +% \pgfsetfillcolor{blue!\pgfmathresult!white} +% \pgfpathcircle{\pgfpointorigin}{2.5pt} +% \pgfusepath{stroke,fill} +% } +% \state{final}{} +% } +% +% \pgfpicture +% \pgfdecoratepath{circles} +% { +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{3cm}}{\pgfpoint{4cm}{0cm}}{\pgfpoint{4cm}{3cm}} +% } +% \endpgfpicture % \long\def\pgfdecoratepath#1#2{% - \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% - #2% - \endpgfdecoration} + \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% + #2% + \endpgfdecoration} @@ -240,37 +240,37 @@ % % Example: % -% \pgfdeclaredecoration{stars}{move}{ -% \state{move}[width=7.5pt, next state=star]{} -% \state{star}[width=7.5pt, next state=move] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetfillcolor{yellow!\pgfmathresult!orange} -% \pgfsetstrokecolor{yellow!\pgfmathresult!red} -% \pgfmathparse{rnd*.75+.25} -% \pgftransformscale{\pgfmathresult} -% \pgfnode{star}{center}{}{}{\pgfusepath{stroke,fill}} -% } -% \state{final} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathlast} -% } -% } -% -% \pgfpicture -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} -% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} -% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} -% \pgfdecoratecurrentpath{stars} -% \endpgfpicture +% \pgfdeclaredecoration{stars}{move}{ +% \state{move}[width=7.5pt, next state=star]{} +% \state{star}[width=7.5pt, next state=move] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetfillcolor{yellow!\pgfmathresult!orange} +% \pgfsetstrokecolor{yellow!\pgfmathresult!red} +% \pgfmathparse{rnd*.75+.25} +% \pgftransformscale{\pgfmathresult} +% \pgfnode{star}{center}{}{}{\pgfusepath{stroke,fill}} +% } +% \state{final} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathlast} +% } +% } +% +% \pgfpicture +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} +% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} +% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} +% \pgfdecoratecurrentpath{stars} +% \endpgfpicture % \def\pgfdecoratecurrentpath#1{% - \pgfgetpath\pgf@decorate@currentpath% - \pgfsetpath\pgfutil@empty% - \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% - \pgfsetpath\pgf@decorate@currentpath% - \endpgfdecoration} + \pgfgetpath\pgf@decorate@currentpath% + \pgfsetpath\pgfutil@empty% + \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% + \pgfsetpath\pgf@decorate@currentpath% + \endpgfdecoration} @@ -282,22 +282,22 @@ % Definitions: % % `existing path' -% - any unsed path exsiting prior to the environment. +% - any unsed path exsiting prior to the environment. % % `decorated path' -% - the path that is being decorated. +% - the path that is being decorated. % -% `decoration path' -% - any unused path left by the decoration automaton. +% `decoration path' +% - any unused path left by the decoration automaton. % % The action of the environment is as follows: % -% 1. Any existing path is saved. -% 2. Construction commands are executed forming the decorated path. -% 3. If the first command in the decorated path is not a `move to', +% 1. Any existing path is saved. +% 2. Construction commands are executed forming the decorated path. +% 3. If the first command in the decorated path is not a `move to', % the last known position from the exisiting path is inserted. -% 4. The saved existing path is reinstalled. -% 5. The decoration automaton is executed along the decorated path. +% 4. The saved existing path is reinstalled. +% 5. The decoration automaton is executed along the decorated path. % % Parameters: % @@ -322,142 +322,142 @@ % <before code> is executed just before the decoration automaton % starts and <after code> is executed just after the automaton stops. % If <before code> or <after code> are empty, they can be omitted. -% The macros \pgfdecoratedpathfirst and \pgfdecoratedpathlast +% The macros \pgfdecoratedpathfirst and \pgfdecoratedpathlast % will be set up as the first and last points on the current section % of the decorated path. % % When the environment exits, the following macros will be set up: % -% \pgfdecorateexistingpath -% - the existing path. +% \pgfdecorateexistingpath +% - the existing path. % -% \pgfdecoratedpath -% - the decorated path. +% \pgfdecoratedpath +% - the decorated path. % -% \pgfdecorationpath -% - any unused decoration path. +% \pgfdecorationpath +% - any unused decoration path. % -% \pgfpointdecoratedpathlast +% \pgfpointdecoratedpathlast % - the last point on the decorated path. % % Examples (require pgfdecorations library): % -% \pgfpicture -% \pgfdecoration -% { -% {lineto}{\pgfdecoratedpathlength/3}, -% {zigzag}{\pgfdecoratedpathlength/3}, -% {lineto}{\pgfdecoratedpathlength/3} -% } -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \endpgfdecoration -% \pgfusepath{stroke} -% \endpgfpicture -% -% -% \pgfpicture -% \pgfdecoration -% { -% {lineto}{\pgfdecoratedpathlength/5}{}{\pgfusepath{stroke}}, -% {zigzag}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% }, -% {lineto}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% }, -% {zigzag}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% }, -% {lineto}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% } -% } -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \endpgfdecoration -% -% \endpgfpicture -% -% -% -% \pgfdeclaredecoration{polygons}{move}{ -% \state{move}[width=7.5pt, next state=polygon]{} -% \state{polygon}[width=7.5pt, next state=move] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetfillcolor{green!\pgfmathresult!yellow} -% \pgfsetstrokecolor{green!\pgfmathresult!brown} -% \pgfnode{regular polygon}{center}{}{}{\pgfusepath{stroke,fill}} -% } -% \state{final} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathlast} -% } -% } -% -% \pgfpicture -% \pgfdecoration -% { -% {polygons}{45pt}, -% {lineto}{30pt} -% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% { -% \pgfsetstrokecolor{yellow!50!orange} -% \pgfusepath{stroke} -% }, -% {polygons}{45pt}, -% {lineto}{30pt} -% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% { -% \pgfsetstrokecolor{green!50!blue} -% \pgfusepath{stroke} -% }, -% {polygons}{\pgfdecoratedremainingdistance} -% } -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \endpgfdecoration -% \endpgfpicture -% -% -% \pgfpicture -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \pgfgetpath\temppath -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% -% \pgfset{decoration text={Here is some text all the way along this curve!}} -% \pgfdecoration{{text}{\pgfdecoratedremainingdistance}} -% \pgfsetpath\temppath -% \endpgfdecoration -% \endpgfpicture +% \pgfpicture +% \pgfdecoration +% { +% {lineto}{\pgfdecoratedpathlength/3}, +% {zigzag}{\pgfdecoratedpathlength/3}, +% {lineto}{\pgfdecoratedpathlength/3} +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% \pgfusepath{stroke} +% \endpgfpicture +% +% +% \pgfpicture +% \pgfdecoration +% { +% {lineto}{\pgfdecoratedpathlength/5}{}{\pgfusepath{stroke}}, +% {zigzag}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% }, +% {lineto}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% }, +% {zigzag}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% }, +% {lineto}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% +% \endpgfpicture +% +% +% +% \pgfdeclaredecoration{polygons}{move}{ +% \state{move}[width=7.5pt, next state=polygon]{} +% \state{polygon}[width=7.5pt, next state=move] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetfillcolor{green!\pgfmathresult!yellow} +% \pgfsetstrokecolor{green!\pgfmathresult!brown} +% \pgfnode{regular polygon}{center}{}{}{\pgfusepath{stroke,fill}} +% } +% \state{final} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathlast} +% } +% } +% +% \pgfpicture +% \pgfdecoration +% { +% {polygons}{45pt}, +% {lineto}{30pt} +% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% { +% \pgfsetstrokecolor{yellow!50!orange} +% \pgfusepath{stroke} +% }, +% {polygons}{45pt}, +% {lineto}{30pt} +% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% { +% \pgfsetstrokecolor{green!50!blue} +% \pgfusepath{stroke} +% }, +% {polygons}{\pgfdecoratedremainingdistance} +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% \endpgfpicture +% +% +% \pgfpicture +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \pgfgetpath\temppath +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% +% \pgfset{decoration text={Here is some text all the way along this curve!}} +% \pgfdecoration{{text}{\pgfdecoratedremainingdistance}} +% \pgfsetpath\temppath +% \endpgfdecoration +% \endpgfpicture % \def\pgfdecoration#1{% \begingroup% \def\pgf@decorate@decorationlist{#1}% - \pgf@decoration@env% + \pgf@decoration@env% } \def\endpgfdecoration{% @@ -498,47 +498,47 @@ % % Example: % -% \pgfdeclaremetadecoration{fancy line}{line to}{ -% \state{line to}[width=1cm, next state=zigzag] -% { -% \decoration{lineto} -% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% \afterdecoration -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% } -% } -% \state{zigzag}[width=2cm, next state=line to] -% { -% \decoration{zigzag} -% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% \afterdecoration -% { -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% } -% } -% \state{final} -% { -% \decoration{lineto} -% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% \afterdecoration -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% } -% } -% } -% -% \pgfpicture -% \pgfmetadecoration{fancy line} -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} -% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} -% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} -% \endpgfmetadecoration -% \endpgfpicture +% \pgfdeclaremetadecoration{fancy line}{line to}{ +% \state{line to}[width=1cm, next state=zigzag] +% { +% \decoration{lineto} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% \state{zigzag}[width=2cm, next state=line to] +% { +% \decoration{zigzag} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% } +% } +% \state{final} +% { +% \decoration{lineto} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% } +% +% \pgfpicture +% \pgfmetadecoration{fancy line} +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} +% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} +% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} +% \endpgfmetadecoration +% \endpgfpicture % \def\pgfmetadecoration#1{% \begingroup% @@ -550,47 +550,47 @@ } \def\endpgfmetadecoration{% - \pgf@decoration@endenv% - \ifx\pgfdecoratedpath\pgfutil@empty% - \else% - \let\pgfmetadecoratedpathlength\pgf@decorate@totalpathlength% - \def\pgfmetadecoratedinputsegmentremainingdistance{\pgfdecoratedremainingdistance}% - \def\pgfmetadecoratedinputsegmentcompleteddistance{\pgfdecoratedcompleteddistance}% - % - % Perform the meta decoration... - % - \expandafter\let\expandafter\pgf@metadecoration@current@state% - \csname pgf@metadecoration@@\pgf@metadecoration@name @initial\endcsname% - \pgf@metadecoration@run% - % - % ..until the final state. - % - \let\pgf@decorate@tempname\pgfutil@empty% - \let\pgf@decorate@tempbefore\pgfutil@empty% - \let\pgf@decorate@tempafter\pgfutil@empty% - \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% - \ifx\pgf@decorate@tempname\pgfutil@empty% - \def\pgf@decorate@tempname{moveto} - \fi% - \pgf@decorate@invoke{% - {\pgf@decorate@tempname}{\pgfdecoratedremainingdistance}% - {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% - }% - \fi% - \pgfgetpath\pgfdecorationpath% - % - % Take stuff outside the group. - % - \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath% - \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath% - \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath% - \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast% - \endgroup% - % - % Are we in LaTeX? - % - \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}% - {\pgf@decorate@installmacrosatend}% + \pgf@decoration@endenv% + \ifx\pgfdecoratedpath\pgfutil@empty% + \else% + \let\pgfmetadecoratedpathlength\pgf@decorate@totalpathlength% + \def\pgfmetadecoratedinputsegmentremainingdistance{\pgfdecoratedremainingdistance}% + \def\pgfmetadecoratedinputsegmentcompleteddistance{\pgfdecoratedcompleteddistance}% + % + % Perform the meta decoration... + % + \expandafter\let\expandafter\pgf@metadecoration@current@state% + \csname pgf@metadecoration@@\pgf@metadecoration@name @initial\endcsname% + \pgf@metadecoration@run% + % + % ..until the final state. + % + \let\pgf@decorate@tempname\pgfutil@empty% + \let\pgf@decorate@tempbefore\pgfutil@empty% + \let\pgf@decorate@tempafter\pgfutil@empty% + \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% + \ifx\pgf@decorate@tempname\pgfutil@empty% + \def\pgf@decorate@tempname{moveto} + \fi% + \pgf@decorate@invoke{% + {\pgf@decorate@tempname}{\pgfdecoratedremainingdistance}% + {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% + }% + \fi% + \pgfgetpath\pgfdecorationpath% + % + % Take stuff outside the group. + % + \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath% + \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath% + \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath% + \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast% + \endgroup% + % + % Are we in LaTeX? + % + \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}% + {\pgf@decorate@installmacrosatend}% } @@ -606,26 +606,26 @@ \let\pgfdecorationpath\pgfutil@empty% \let\pgfdecoratedpath\pgfutil@empty% \let\pgfpoint@decorated@pathlast\pgfpointorigin% - \edef\pgfpoint@decorate@existingpathlast{\pgf@x\the\pgf@path@lastx\pgf@y\the\pgf@path@lasty}% + \edef\pgfpoint@decorate@existingpathlast{\pgf@x\the\pgf@path@lastx\pgf@y\the\pgf@path@lasty}% % % Begin a group so transformations don't mess things up. % - \bgroup% + \bgroup% } \def\pgf@decorate@path@check@moveto#1{% - \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop} + \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop} \def\pgf@decorate@token@stop{\pgf@decorate@stop}% \def\pgf@decorate@path@@check@moveto#1#2#3#4\pgf@decorate@@stop#5#6{% - \def\pgf@decorate@temp{#4}% - \pgf@x=#2\relax% - \pgf@y=#3\relax% - \ifx\pgf@decorate@temp\pgf@decorate@token@stop% - #5% - \else% - #6% - \fi% + \def\pgf@decorate@temp{#4}% + \pgf@x=#2\relax% + \pgf@y=#3\relax% + \ifx\pgf@decorate@temp\pgf@decorate@token@stop% + #5% + \else% + #6% + \fi% } \def\pgf@decoration@endenv{% @@ -638,20 +638,20 @@ \pgfsetpath\pgfdecorateexistingpath% % \ifx\pgfdecoratedpath\pgfutil@empty% - \PackageError{PGF}{I cannot decorate an empty path}{}% + \pgferror{I cannot decorate an empty path}% \else% - % - % If the path consists of a single moveto token, make it - % a very small horizontal line. - % - \pgf@decorate@path@check@moveto\pgfdecoratedpath{% - \advance\pgf@x by0.0001pt\relax% - \edef\pgfdecoratedpath{% - \expandafter\noexpand\pgfdecoratedpath% - \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@x}{\the\pgf@y}% - }% - }% - {}% + % + % If the path consists of a single moveto token, make it + % a very small horizontal line. + % + \pgf@decorate@path@check@moveto\pgfdecoratedpath{% + \advance\pgf@x by0.0001pt\relax% + \edef\pgfdecoratedpath{% + \expandafter\noexpand\pgfdecoratedpath% + \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@x}{\the\pgf@y}% + }% + }% + {}% % % Remove special round tokens and get points. % @@ -668,7 +668,7 @@ % Reverse objects if necessary. % \ifpgf@decorate@inputsegmentobjects@reverse% - \pgf@decorate@inputsegmentobjects@reverse{\pgf@decorate@inputsegmentobjects}{\pgf@decorate@inputsegmentobjects}% + \pgf@decorate@inputsegmentobjects@reverse{\pgf@decorate@inputsegmentobjects}{\pgf@decorate@inputsegmentobjects}% \fi% % \let\pgf@decorated@remainingdistance\pgf@decorate@totalpathlength% @@ -687,13 +687,13 @@ \pgf@decorate@processnextinputsegmentobject% \pgf@decorate@distancetomove0pt\relax% \fi% -}% +}% \def\pgf@decorate@installmacrosatend{% - \let\pgfdecorationpath\pgf@decorate@decorationpathtemp% + \let\pgfdecorationpath\pgf@decorate@decorationpathtemp% \let\pgfdecoratedpath\pgf@decorate@decoratedpathtemp% \let\pgfdecorateexistingpath\pgf@decorate@existingpathtemp% \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@pathlasttemp% @@ -710,18 +710,18 @@ % A version of \pgfutil@for which doesn't expand each value in #3. % \def\pgf@decorate@for#1:=#2\do#3{% - \def\pgf@decorate@for@var{#1}% - \def\pgf@decorate@for@action{#3}% - \expandafter\pgf@decorate@@for#2,\pgf@stop,} - + \def\pgf@decorate@for@var{#1}% + \def\pgf@decorate@for@action{#3}% + \expandafter\pgf@decorate@@for#2,\pgf@stop,} + \def\pgf@decorate@@for#1,{% - \ifx#1\pgf@stop% - \expandafter\let\pgf@decorate@for@var\pgfutil@empty% - \else% - \expandafter\def\pgf@decorate@for@var{#1}% - \pgf@decorate@for@action% - \expandafter\pgf@decorate@@for% - \fi% + \ifx#1\pgf@stop% + \expandafter\let\pgf@decorate@for@var\pgfutil@empty% + \else% + \expandafter\def\pgf@decorate@for@var{#1}% + \pgf@decorate@for@action% + \expandafter\pgf@decorate@@for% + \fi% } @@ -730,97 +730,97 @@ % #1 - {<name>}{<distance>}{<before code>}{<after code>} % \def\pgf@decorate@invoke#1{% - \pgf@decorate@@invoke#1\pgf@decorate@invoke\pgf@decorate@invoke\pgf@decorate@invoke\pgf@stop} - + \pgf@decorate@@invoke#1\pgf@decorate@invoke\pgf@decorate@invoke\pgf@decorate@invoke\pgf@stop} + \def\pgf@decorate@@invoke#1#2#3#4#5\pgf@stop{% - \pgfutil@ifundefined{pgf@decorate@@#1@initial}% - {% - \PackageError{PGF}{Unknown decoration `#1'}{}% - }% - {% - \def\pgf@decorate@name{#1}% - \ifx\pgf@decorate@invoke#3% - \let\pgf@decorate@beforecode\pgfutil@empty% - \else% - \def\pgf@decorate@beforecode{#3}% - \fi% - \ifx\pgf@decorate@invoke#4% - \let\pgf@decorate@aftercode\pgfutil@empty% - \else% - \def\pgf@decorate@aftercode{#4}% - \fi% - % - % Make remaining distance and the decorated path length `public'. - % - \pgfdecoratedremainingdistance\pgf@decorated@remainingdistance\relax% - \let\pgfdecoratedpathlength\pgf@decorate@totalpathlength% - % - \pgfmathsetlength\pgf@xa{#2}% - \ifdim\pgf@xa>\pgf@decorated@remainingdistance\relax% - \pgf@xa\pgf@decorated@remainingdistance\relax% - \fi% - \edef\pgf@decorate@currentpathlength{\the\pgf@xa}% - % - % Calculate the distance remaining to the end of the entire path. - % - \pgf@xa-\pgf@decorate@currentpathlength\relax% - \advance\pgf@xa\pgf@decorated@remainingdistance\relax% - \edef\pgf@decorated@remainingdistance{\the\pgf@xa}% - % - % Set up the macros and distances for the current section - % of the decorated path. - % - \let\pgfdecoratedpathlength\pgf@decorate@currentpathlength% - \pgfdecoratedremainingdistance\pgfdecoratedpathlength\relax% - \pgfdecoratedcompleteddistance0pt\relax% - % - % Execute user-defined code beore decoration. - % - \pgf@decorate@beforecode% - % - % Run the decoration... - % - \expandafter\let\expandafter\pgf@decorate@current@state% - \csname pgf@decorate@@\pgf@decorate@name @initial\endcsname% - \pgf@decorate@run% - % - % ...until the final state. - % - \ifdim\pgf@decorated@remainingdistance<1pt\relax% Should be =0pt, but need to control for inaccuracies. - \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast% - \else% - % - % Set up \pgfpoint@decorated@pathlast if the end of - % the total decorated path has not been reached. - % - {% - \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% - \pgf@decorate@transformtoinputsegment% - \pgfpointorigin% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% - \edef\pgfpoint@decorated@pathlast{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}% - \fi% - {% - \pgftransformreset% - \pgf@decorate@transformtoinputsegment% - \pgf@decorate@additionaltransform% - \csname pgf@decorate@@\pgf@decorate@name @final@code\endcsname% - }% - \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% - % - % Execute user-defined code after decoration. - % - \pgf@decorate@aftercode% - % - % Update the input segment objects. - % - \let\pgf@decorate@additionaltransform\pgfutil@empty% - \let\pgf@decorate@inputsegmentobjects\pgf@decorate@inputsegmentobjects@aftersplit% - \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@pathlast% - }% + \pgfutil@ifundefined{pgf@decorate@@#1@initial}% + {% + \pgferror{Unknown decoration `#1'}% + }% + {% + \def\pgf@decorate@name{#1}% + \ifx\pgf@decorate@invoke#3% + \let\pgf@decorate@beforecode\pgfutil@empty% + \else% + \def\pgf@decorate@beforecode{#3}% + \fi% + \ifx\pgf@decorate@invoke#4% + \let\pgf@decorate@aftercode\pgfutil@empty% + \else% + \def\pgf@decorate@aftercode{#4}% + \fi% + % + % Make remaining distance and the decorated path length `public'. + % + \pgfdecoratedremainingdistance\pgf@decorated@remainingdistance\relax% + \let\pgfdecoratedpathlength\pgf@decorate@totalpathlength% + % + \pgfmathsetlength\pgf@xa{#2}% + \ifdim\pgf@xa>\pgf@decorated@remainingdistance\relax% + \pgf@xa\pgf@decorated@remainingdistance\relax% + \fi% + \edef\pgf@decorate@currentpathlength{\the\pgf@xa}% + % + % Calculate the distance remaining to the end of the entire path. + % + \pgf@xa-\pgf@decorate@currentpathlength\relax% + \advance\pgf@xa\pgf@decorated@remainingdistance\relax% + \edef\pgf@decorated@remainingdistance{\the\pgf@xa}% + % + % Set up the macros and distances for the current section + % of the decorated path. + % + \let\pgfdecoratedpathlength\pgf@decorate@currentpathlength% + \pgfdecoratedremainingdistance\pgfdecoratedpathlength\relax% + \pgfdecoratedcompleteddistance0pt\relax% + % + % Execute user-defined code beore decoration. + % + \pgf@decorate@beforecode% + % + % Run the decoration... + % + \expandafter\let\expandafter\pgf@decorate@current@state% + \csname pgf@decorate@@\pgf@decorate@name @initial\endcsname% + \pgf@decorate@run% + % + % ...until the final state. + % + \ifdim\pgf@decorated@remainingdistance<1pt\relax% Should be =0pt, but need to control for inaccuracies. + \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast% + \else% + % + % Set up \pgfpoint@decorated@pathlast if the end of + % the total decorated path has not been reached. + % + {% + \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% + \pgf@decorate@transformtoinputsegment% + \pgfpointorigin% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% + \edef\pgfpoint@decorated@pathlast{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}% + \fi% + {% + \pgftransformreset% + \pgf@decorate@transformtoinputsegment% + \pgf@decorate@additionaltransform% + \csname pgf@decorate@@\pgf@decorate@name @final@code\endcsname% + }% + \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% + % + % Execute user-defined code after decoration. + % + \pgf@decorate@aftercode% + % + % Update the input segment objects. + % + \let\pgf@decorate@additionaltransform\pgfutil@empty% + \let\pgf@decorate@inputsegmentobjects\pgf@decorate@inputsegmentobjects@aftersplit% + \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@pathlast% + }% } @@ -832,25 +832,25 @@ % \pgfpointdecoratedpathfirst % \def\pgfpointdecoratedpathfirst{% - {% - \pgftransforminvert% - \pgfpoint@decorated@pathfirst% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% + {% + \pgftransforminvert% + \pgfpoint@decorated@pathfirst% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% }% % \pgfpointdecoratedpathlast % \def\pgfpointdecoratedpathlast{% - {% - \pgftransforminvert% - \pgfpoint@decorated@pathlast% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% + {% + \pgftransforminvert% + \pgfpoint@decorated@pathlast% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% }% % \pgfpointdecoratedinputsegmentfirst @@ -858,27 +858,27 @@ % The first point of the current sub-path. % \def\pgfpointdecoratedinputsegmentfirst{% - {% - \pgftransforminvert% - \pgf@decorate@inputsegment@first% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% -}% + {% + \pgftransforminvert% + \pgf@decorate@inputsegment@first% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% +}% % \pgfpointdecoratedinputsegmentlast % % The final point of the current sub-path. % \def\pgfpointdecoratedinputsegmentlast{% - {% - \pgftransforminvert% - \pgf@decorate@inputsegment@last% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% + {% + \pgftransforminvert% + \pgf@decorate@inputsegment@last% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% }% @@ -887,7 +887,7 @@ % Run a normal decoration. % \def\pgf@decorate@run{% - \let\pgf@decorate@next\pgf@decorate@do@state% + \let\pgf@decorate@next\pgf@decorate@do@state% \ifx\pgf@decorate@current@state\pgf@final@text% \let\pgf@decorate@next\relax% \fi% @@ -931,10 +931,10 @@ % Next iteration. % \ifnum\pgf@decorate@repeatstate>0\relax% - \advance\pgf@decorate@repeatstate-1\relax% + \advance\pgf@decorate@repeatstate-1\relax% \else% - \pgf@decorate@repeatstate-1\relax% - \let\pgf@decorate@current@state\pgf@decorate@next@state% + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@current@state\pgf@decorate@next@state% \fi% \pgf@decorate@run% } @@ -1063,13 +1063,13 @@ \def\pgf@metadecoration@decoration#1{% - \edef\pgf@decorate@tempname{#1}% + \edef\pgf@decorate@tempname{#1}% } \def\pgf@metadecoration@beforedecoration#1{% - \def\pgf@decorate@tempbefore{#1}% + \def\pgf@decorate@tempbefore{#1}% } \def\pgf@metadecoration@afterdecoration#1{% - \def\pgf@decorate@tempafter{#1}% + \def\pgf@decorate@tempafter{#1}% } @@ -1078,7 +1078,7 @@ % Run a meta decoration. % \def\pgf@metadecoration@run{% - \let\pgf@metadecoration@next\pgf@metadecoration@do@state% + \let\pgf@metadecoration@next\pgf@metadecoration@do@state% \ifx\pgf@metadecoration@current@state\pgf@final@text% \let\pgf@metadecoration@next\relax% \fi% @@ -1086,7 +1086,7 @@ } \def\pgf@metadecoration@do@state{% - \let\pgf@metadecoration@next\relax% + \let\pgf@metadecoration@next\relax% \let\pgf@metadecoration@next@state\pgf@metadecoration@current@state% % % Set up some macros. @@ -1107,7 +1107,7 @@ } \def\pgf@metadecoration@do@code{% - % + % % Execute code. % \let\pgf@decorate@tempname\pgfutil@empty% @@ -1117,11 +1117,11 @@ \let\pgfpointmetadecoratedpathlast\pgfpointdecoratedpathlast% \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% \ifx\pgf@decorate@tempname\pgfutil@empty% - \def\pgf@decorate@tempname{moveto} - \fi% + \def\pgf@decorate@tempname{moveto} + \fi% \pgf@decorate@invoke{% - {\pgf@decorate@tempname}{\pgf@metadecoration@width}% - {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% + {\pgf@decorate@tempname}{\pgf@metadecoration@width}% + {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% }% % % Next iteration. @@ -1141,7 +1141,7 @@ \def\pgf@metadecoration@switch@if#1to #2\pgf@stop{% \ifx\pgf@metadecoration@next\relax% - \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetlength\pgf@x{#1}% \ifdim\pgf@decorated@remainingdistance<\pgf@x% \def\pgf@metadecoration@current@state{#2}% \let\pgf@metadecoration@next\pgf@metadecoration@run% @@ -1151,7 +1151,7 @@ \def\pgf@metadecoration@switch@ifinputsegment#1to #2\pgf@stop{% \ifx\pgf@metadecoration@next\relax% - \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetlength\pgf@x{#1}% \ifdim\pgfdecoratedinputsegmentremainingdistance<\pgf@x% \def\pgf@metadecoration@current@state{#2}% \let\pgf@metadecoration@next\pgf@metadecoration@run% @@ -1164,10 +1164,10 @@ % Move along the path by a specified distance. % \def\pgf@decorate@movealongpath#1{% - \pgfmathsetlength\pgf@decorate@distancetomove{#1}% - \advance\pgfdecoratedcompleteddistance\pgf@decorate@distancetomove% - \advance\pgfdecoratedremainingdistance-\pgf@decorate@distancetomove% - \pgf@decorate@@movealongpath% + \pgfmathsetlength\pgf@decorate@distancetomove{#1}% + \advance\pgfdecoratedcompleteddistance\pgf@decorate@distancetomove% + \advance\pgfdecoratedremainingdistance-\pgf@decorate@distancetomove% + \pgf@decorate@@movealongpath% } \def\pgf@decorate@@movealongpath{% \advance\pgfdecoratedinputsegmentcompleteddistance\pgf@decorate@distancetomove% @@ -1188,107 +1188,107 @@ } \def\pgf@decorate@@@movealongpath{% - % - % Move along input segment for real. - % - \pgf@decorate@movealonginputsegment{\the\pgf@decorate@distancetomove}% - \pgf@decorate@distancetomove0pt\relax% - % - % Grrr. Hacking to control some inaccuracies. - % - \ifdim\pgf@decorate@inputsegmenttime pt>1pt\relax% - \let\pgf@decorate@inputsegmenttimetemp\pgf@decorate@inputsegmenttime% - \pgf@decorate@processnextinputsegmentobject% - \pgf@x\pgf@decorate@inputsegmenttimetemp pt\relax% - \advance\pgf@x-1pt\relax% - \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@x}}% - \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% - \pgfdecoratedremainingdistance0pt\relax% - \fi% - \fi% + % + % Move along input segment for real. + % + \pgf@decorate@movealonginputsegment{\the\pgf@decorate@distancetomove}% + \pgf@decorate@distancetomove0pt\relax% + % + % Grrr. Hacking to control some inaccuracies. + % + \ifdim\pgf@decorate@inputsegmenttime pt>1pt\relax% + \let\pgf@decorate@inputsegmenttimetemp\pgf@decorate@inputsegmenttime% + \pgf@decorate@processnextinputsegmentobject% + \pgf@x\pgf@decorate@inputsegmenttimetemp pt\relax% + \advance\pgf@x-1pt\relax% + \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@x}}% + \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% + \pgfdecoratedremainingdistance0pt\relax% + \fi% + \fi% } % Return the next input segment object in a macro % \def\pgf@decorate@getnextinputsegmentobject#1{% - \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% - \let\pgf@next\relax% - \else% - \def\pgf@decorate@temp{#1}% - \let\pgf@next\pgf@decorate@@getnextinputsegmentobject% - \fi% - \pgf@next% + \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% + \let\pgf@next\relax% + \else% + \def\pgf@decorate@temp{#1}% + \let\pgf@next\pgf@decorate@@getnextinputsegmentobject% + \fi% + \pgf@next% } \def\pgf@decorate@@getnextinputsegmentobject{% - \expandafter\pgf@decorate@@@getnextinputsegmentobject\pgf@decorate@currentinputsegmentobjects\pgf@stop} + \expandafter\pgf@decorate@@@getnextinputsegmentobject\pgf@decorate@currentinputsegmentobjects\pgf@stop} \def\pgf@decorate@@@getnextinputsegmentobject#1#2\pgf@stop{% - \expandafter\def\pgf@decorate@temp{#1}% - \def\pgf@decorate@currentinputsegmentobjects{#2}} + \expandafter\def\pgf@decorate@temp{#1}% + \def\pgf@decorate@currentinputsegmentobjects{#2}} % Process the next input segment object. % \def\pgf@decorate@processnextinputsegmentobject{% - \let\pgfdecorationpreviousinputsegment\pgfdecoratecurrentinputsegment% - \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% - \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% - % - % If the current input segment object is a moveto, execute the - % object macro and get the next input segment object. - % - \pgf@decorate@is@closepath@false% - \pgf@decorate@currentinputsegmentobject% - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% - \pgfpathmoveto{\pgf@decorate@inputsegment@first}% - \let\pgfdecorationpreviousinputsegment\pgfdecorationcurrentinputsegment% - \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% - \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% - \pgf@decorate@is@closepath@false% - \pgf@decorate@currentinputsegmentobject% - \fi% - % - % Teensy hack in case a path goes nowhere. - % - \ifdim\pgfdecoratedinputsegmentlength=0pt\relax% - \def\pgfdecoratedinputsegmentlength{0.05pt}% Arbitrary choice >0pt. - \fi% - \pgfdecoratedinputsegmentremainingdistance\pgfdecoratedinputsegmentlength\relax% - \pgfdecoratedinputsegmentcompleteddistance0pt\relax% - \def\pgf@decorate@inputsegmenttime{0}% - % - % Get the angle at the start of the input segment. - % - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - \let\pgfdecoratedangle\pgfmathresult% - \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - \let\pgfdecoratedinputsegmentendangle\pgfmathresult% - \else% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% - \let\pgfdecoratedangle\pgfmathresult% - \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% - \let\pgfdecoratedinputsegmentendangle\pgfmathresult% - \fi% - % - % Get the angle to the next input segment. - % - \begingroup% - \pgf@decorate@nextinputsegmentobject% - \global\let\pgf@decorate@temp\pgfdecorationcurrentinputsegment% - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% - \expandafter\pgf@decorate@currentinputsegmentobject% - \fi% - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - \else% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% - \fi% - \pgf@x-\pgfdecoratedangle pt\relax% - \advance\pgf@x\pgfmathresult pt\relax% - \edef\pgfdecoratedangletonextinputsegment{\the\pgf@x}% - \pgfmath@smuggleone\pgfdecoratedangletonextinputsegment% - \endgroup% - \let\pgfdecorationnextinputsegmentobject\pgf@decorate@temp% + \let\pgfdecorationpreviousinputsegment\pgfdecoratecurrentinputsegment% + \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% + % + % If the current input segment object is a moveto, execute the + % object macro and get the next input segment object. + % + \pgf@decorate@is@closepath@false% + \pgf@decorate@currentinputsegmentobject% + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% + \pgfpathmoveto{\pgf@decorate@inputsegment@first}% + \let\pgfdecorationpreviousinputsegment\pgfdecorationcurrentinputsegment% + \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@is@closepath@false% + \pgf@decorate@currentinputsegmentobject% + \fi% + % + % Teensy hack in case a path goes nowhere. + % + \ifdim\pgfdecoratedinputsegmentlength=0pt\relax% + \def\pgfdecoratedinputsegmentlength{0.05pt}% Arbitrary choice >0pt. + \fi% + \pgfdecoratedinputsegmentremainingdistance\pgfdecoratedinputsegmentlength\relax% + \pgfdecoratedinputsegmentcompleteddistance0pt\relax% + \def\pgf@decorate@inputsegmenttime{0}% + % + % Get the angle at the start of the input segment. + % + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + \let\pgfdecoratedangle\pgfmathresult% + \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \let\pgfdecoratedinputsegmentendangle\pgfmathresult% + \else% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% + \let\pgfdecoratedangle\pgfmathresult% + \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% + \let\pgfdecoratedinputsegmentendangle\pgfmathresult% + \fi% + % + % Get the angle to the next input segment. + % + \begingroup% + \pgf@decorate@nextinputsegmentobject% + \global\let\pgf@decorate@temp\pgfdecorationcurrentinputsegment% + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% + \expandafter\pgf@decorate@currentinputsegmentobject% + \fi% + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + \else% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% + \fi% + \pgf@x-\pgfdecoratedangle pt\relax% + \advance\pgf@x\pgfmathresult pt\relax% + \edef\pgfdecoratedangletonextinputsegment{\the\pgf@x}% + \pgfmath@smuggleone\pgfdecoratedangletonextinputsegment% + \endgroup% + \let\pgfdecorationnextinputsegmentobject\pgf@decorate@temp% } @@ -1315,56 +1315,55 @@ % Input segment object moveto. % \def\pgf@decorate@inputsegmentobject@moveto#1{% - \def\pgf@decorate@inputsegment@first{#1}% - \def\pgf@decorate@inputsegment@supporta{#1}% - \def\pgf@decorate@inputsegment@supportb{#1}% - \def\pgf@decorate@inputsegment@last{#1}% - \edef\pgf@decorate@lastmoveto{#1}% - \def\pgfdecoratedinputsegmentlength{0pt}% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% + \def\pgf@decorate@inputsegment@first{#1}% + \def\pgf@decorate@inputsegment@supporta{#1}% + \def\pgf@decorate@inputsegment@supportb{#1}% + \def\pgf@decorate@inputsegment@last{#1}% + \edef\pgf@decorate@lastmoveto{#1}% + \def\pgfdecoratedinputsegmentlength{0pt}% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% } % Input segment object lineto. % \def\pgf@decorate@inputsegmentobject@lineto#1#2#3{% - \def\pgfdecoratedinputsegmentlength{#1}% - \def\pgf@decorate@inputsegment@first{#2}% - \def\pgf@decorate@inputsegment@last{#3}% - % - % Supports should be defined like this, so if treated as a curve, - % equal time steps will correspond to equal distances. - % - \pgfpointdiff{#2}{#3}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgfextract@process\pgf@decorate@inputsegment@supporta{% - \pgf@process{#2}% - \advance\pgf@x0.333333\pgf@xa% - \advance\pgf@y0.333333\pgf@ya% - }% - \pgfextract@process\pgf@decorate@inputsegment@supportb{% - \pgf@process{#2}% - \advance\pgf@x0.666666\pgf@xa% - \advance\pgf@y0.666666\pgf@ya% - }% - % - \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% - \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlineto% + \def\pgfdecoratedinputsegmentlength{#1}% + \def\pgf@decorate@inputsegment@first{#2}% + \def\pgf@decorate@inputsegment@last{#3}% + % + % Supports should be defined like this, so if treated as a curve, + % equal time steps will correspond to equal distances. + % + \pgfpointdiff{#2}{#3}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgfextract@process\pgf@decorate@inputsegment@supporta{% + \pgf@process{#2}% + \advance\pgf@x0.333333\pgf@xa% + \advance\pgf@y0.333333\pgf@ya% + }% + \pgfextract@process\pgf@decorate@inputsegment@supportb{% + \pgf@process{#2}% + \advance\pgf@x0.666666\pgf@xa% + \advance\pgf@y0.666666\pgf@ya% + }% + \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% + \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlineto% } % Input segment object curveto. % \def\pgf@decorate@inputsegmentobject@curveto#1#2#3#4#5{% - \def\pgfdecoratedinputsegmentlength{#1}% - \def\pgf@decorate@inputsegment@first{#2}% - \def\pgf@decorate@inputsegment@supporta{#3}% - \def\pgf@decorate@inputsegment@supportb{#4}% - \def\pgf@decorate@inputsegment@last{#5}% - % - \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@curve% - \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@curve% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% + \def\pgfdecoratedinputsegmentlength{#1}% + \def\pgf@decorate@inputsegment@first{#2}% + \def\pgf@decorate@inputsegment@supporta{#3}% + \def\pgf@decorate@inputsegment@supportb{#4}% + \def\pgf@decorate@inputsegment@last{#5}% + % + \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@curve% + \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@curve% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% } % Input segment object closepath. @@ -1377,31 +1376,31 @@ \def\pgfdecoratedinputsegmentlength{#1}% \def\pgf@decorate@inputsegment@first{#2}% \def\pgf@decorate@inputsegment@last{#3}% - % - \pgfpointdiff{#2}{#3}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgfextract@process\pgf@decorate@inputsegment@supporta{% - \pgf@process{#2}% - \advance\pgf@x0.333333\pgf@xa% - \advance\pgf@y0.333333\pgf@ya% - }% - \pgfextract@process\pgf@decorate@inputsegment@supportb{% - \pgf@process{#2}% - \advance\pgf@x0.666666\pgf@xa% - \advance\pgf@y0.666666\pgf@ya% - }% - % + % + \pgfpointdiff{#2}{#3}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgfextract@process\pgf@decorate@inputsegment@supporta{% + \pgf@process{#2}% + \advance\pgf@x0.333333\pgf@xa% + \advance\pgf@y0.333333\pgf@ya% + }% + \pgfextract@process\pgf@decorate@inputsegment@supportb{% + \pgf@process{#2}% + \advance\pgf@x0.666666\pgf@xa% + \advance\pgf@y0.666666\pgf@ya% + }% + % \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentclosepath% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentclosepath% } % Input segment object endofinputsegments. % \def\pgf@decorate@inputsegmentobject@endofinputsegments{% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlast% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlast% } @@ -1414,93 +1413,92 @@ % This macro controls how the automaton moves along a curve sub-path. % \def\pgf@decorate@movealonginputsegment@curve#1{% - \ifdim#1=0pt\relax% - \else% - \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgf@xb\pgf@decorate@inputsegmenttime pt\relax% - % - % Reduce the initial time step, depending on the length - % of the path. To do: Optimise this step (should also depend on #1). - % - \ifdim\pgf@decorate@currentpathlength<128pt\relax% - \pgf@yb.03125pt\relax% - \else% - \ifdim\pgf@decorate@currentpathlength<512pt\relax% - \pgf@yb.015625pt\relax% - \else% - \ifdim\pgf@decorate@currentpathlength<2048pt\relax% - \pgf@yb.00390625pt\relax% - \else% - \pgf@yb.0009765625pt\relax% - \fi% - \fi% - \fi% - \c@pgf@counta1\relax% - \pgfutil@tempdima0pt\relax% - \pgfmathloop% - \advance\pgf@xb\c@pgf@counta\pgf@yb% - % - % We would like to use \pgfpointcurveattime. However, we must not - % overuse \pgf@process or \pgfmath stuff within this loop, - % otherwise we increase the chances of save stack overflow. - % - \edef\pgf@decorate@temp{% - \pgf@xa\the\pgf@xa% - \pgf@xb\the\pgf@xb% - \pgf@ya\the\pgf@ya% - \pgf@yb\the\pgf@yb% - }% - % - \pgfpoint@decorate@curveattime{\pgfmath@tonumber{\pgf@xb}}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - % - \pgf@decorate@temp% - % - \pgf@xc\pgf@xa% - \pgf@yc\pgf@ya% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \advance\pgf@x-\pgf@xc% - \advance\pgf@y-\pgf@yc% - \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% - \pgfutil@tempdimb\pgfmathresult pt\relax% - \advance\pgfutil@tempdima\c@pgf@counta\pgfutil@tempdimb% - \ifnum\c@pgf@counta>0\relax% - \ifdim\pgfutil@tempdima>#1\relax% - \c@pgf@counta-\c@pgf@counta% - \pgf@yb.5\pgf@yb% - \fi% - \else% - \ifdim\pgfutil@tempdima<#1\relax% - \c@pgf@counta-\c@pgf@counta% - \pgf@yb.5\pgf@yb% - \fi% - \fi% - \ifdim\pgf@yb=0pt\relax% *Should* be OK. - \else% - \repeatpgfmathloop% - \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@xb}}% - % - % Now calculate the angle at the new time on the curve. - % - % We can use \pgfpointcurveattime safely here. - % - \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - \edef\pgf@marshal{% - \noexpand\pgfmathanglebetweenpoints% - {\pgf@x\the\pgf@xb\pgf@y\pgf@yb}% - {\pgf@x\the\pgf@xa\pgf@y\pgf@ya}% - }% - \pgf@marshal% - \let\pgfdecoratedangle\pgfmathresult% - \fi% + \ifdim#1=0pt\relax% + \else% + \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@xb\pgf@decorate@inputsegmenttime pt\relax% + % + % Reduce the initial time step, depending on the length + % of the path. To do: Optimise this step (should also depend on #1). + % + \ifdim\pgf@decorate@currentpathlength<128pt\relax% + \pgf@yb.03125pt\relax% + \else% + \ifdim\pgf@decorate@currentpathlength<512pt\relax% + \pgf@yb.015625pt\relax% + \else% + \ifdim\pgf@decorate@currentpathlength<2048pt\relax% + \pgf@yb.00390625pt\relax% + \else% + \pgf@yb.0009765625pt\relax% + \fi% + \fi% + \fi% + \c@pgf@counta1\relax% + \pgfutil@tempdima0pt\relax% + \pgfmathloop% + \advance\pgf@xb\c@pgf@counta\pgf@yb% + % + % We would like to use \pgfpointcurveattime. However, we must not + % overuse \pgf@process or \pgfmath stuff within this loop, + % otherwise we increase the chances of save stack overflow. + % + \edef\pgf@decorate@temp{% + \pgf@xa\the\pgf@xa% + \pgf@xb\the\pgf@xb% + \pgf@ya\the\pgf@ya% + \pgf@yb\the\pgf@yb% + }% + % + \pgfpoint@decorate@curveattime{\pgfmath@tonumber{\pgf@xb}}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgf@decorate@temp% + % + \pgf@xc\pgf@xa% + \pgf@yc\pgf@ya% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \advance\pgf@x-\pgf@xc% + \advance\pgf@y-\pgf@yc% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \advance\pgfutil@tempdima\c@pgf@counta\pgfutil@tempdimb% + \ifnum\c@pgf@counta>0\relax% + \ifdim\pgfutil@tempdima>#1\relax% + \c@pgf@counta-\c@pgf@counta% + \pgf@yb.5\pgf@yb% + \fi% + \else% + \ifdim\pgfutil@tempdima<#1\relax% + \c@pgf@counta-\c@pgf@counta% + \pgf@yb.5\pgf@yb% + \fi% + \fi% + \ifdim\pgf@yb=0pt\relax% *Should* be OK. + \else% + \repeatpgfmathloop% + \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@xb}}% + % + % Now calculate the angle at the new time on the curve. + % + % We can use \pgfpointcurveattime safely here. + % + \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \edef\pgf@marshal{% + \noexpand\pgfmathanglebetweenpoints% + {\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}% + }% + \pgf@marshal% + \let\pgfdecoratedangle\pgfmathresult% + \fi% } % \pgfpoint@decorate@curveattime @@ -1549,141 +1547,140 @@ % Applies the necessary transform for a line sub-path. % \def\pgf@decorate@transformtoinputsegment@line{% - \pgftransformshift{% - \pgfpointadd{\pgf@decorate@inputsegment@first}% - {\pgfpointpolar{\pgfdecoratedangle}{\pgfdecoratedinputsegmentcompleteddistance}}% - }% - \pgftransformrotate{\pgfdecoratedangle}% + \pgftransformshift{% + \pgfpointlineatdistance{\pgfdecoratedinputsegmentcompleteddistance}{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last} + }% + \pgftransformrotate{\pgfdecoratedangle}% } % Applies the necessary transform for a curve sub-path. % \def\pgf@decorate@transformtoinputsegment@curve{% - \pgfslopedattimetrue% - \pgfallowupsidedownattimetrue% - \pgftransformcurveattime{\pgf@decorate@inputsegmenttime}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgfslopedattimetrue% + \pgfallowupsidedownattimetrue% + \pgftransformcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% } -% \pgf@decorate@parsesoftpath -% -% Parses an instance of a soft path into intermediate line and curve -% sub-path objects which the decoration automaton can use to traverse +% \pgf@decorate@parsesoftpath +% +% Parses an instance of a soft path into intermediate line and curve +% sub-path objects which the decoration automaton can use to traverse % the decorated path. -% -% The soft path should be well formed and only contain `primative' -% soft path tokens, that is: moveto, lineto, curvetosupporta, -% curvetosupportb, curveto, rectcorner, rectsize, and closepath. -% (i.e., all specialround tokens should have removed using -% \pgfprocessround) -% -% The overall length of the path is also calculated and returned -% in the macro \pgfdecoratedpathlength. -% -% Parameters: -% -% #1 - a macro containing a well formed soft path. -% #2 - a macro to store the intermediate sub-path representations. -% -% Example: -% -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathlineto{\pgfpoint{0pt}{12pt}} -% \pgfpathlineto{\pgfpoint{12pt}{0pt}} -% \pgfgetpath\softpath -% -% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath} -% -% results in: -% -% \parsedsoftpath -> -% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 0pt}{\pgf@x 0pt\pgf@y 12pt}} -% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 12pt}{\pgf@x 12pt\pgf@y 12pt}} -% -% \pgfdecoratedpathlength -> -% 24pt +% +% The soft path should be well formed and only contain `primative' +% soft path tokens, that is: moveto, lineto, curvetosupporta, +% curvetosupportb, curveto, rectcorner, rectsize, and closepath. +% (i.e., all specialround tokens should have removed using +% \pgfprocessround) +% +% The overall length of the path is also calculated and returned +% in the macro \pgfdecoratedpathlength. +% +% Parameters: +% +% #1 - a macro containing a well formed soft path. +% #2 - a macro to store the intermediate sub-path representations. +% +% Example: +% +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathlineto{\pgfpoint{0pt}{12pt}} +% \pgfpathlineto{\pgfpoint{12pt}{0pt}} +% \pgfgetpath\softpath +% +% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath} +% +% results in: +% +% \parsedsoftpath -> +% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 0pt}{\pgf@x 0pt\pgf@y 12pt}} +% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 12pt}{\pgf@x 12pt\pgf@y 12pt}} +% +% \pgfdecoratedpathlength -> +% 24pt % \def\pgf@decorate@parsesoftpath#1#2{% - \def\pgf@decorate@inputsegmentobjectsmacro{#2}% - \let\pgf@decorate@inputsegmentobjects\pgfutil@empty% - \pgfutil@tempdima0pt\relax% - \let\pgfpoint@decorate@lastparsed\pgfpoint@decorate@existingpathlast% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@origin% - \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% - \let\pgfpoint@decorated@firstparsed\pgfutil@empty% - \expandafter\pgf@decorate@@parsesoftpath#1\pgf@stop% + \def\pgf@decorate@inputsegmentobjectsmacro{#2}% + \let\pgf@decorate@inputsegmentobjects\pgfutil@empty% + \pgfutil@tempdima0pt\relax% + \let\pgfpoint@decorate@lastparsed\pgfpoint@decorate@existingpathlast% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@origin% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \let\pgfpoint@decorated@firstparsed\pgfutil@empty% + \expandafter\pgf@decorate@@parsesoftpath#1\pgf@stop% } \def\pgf@decorate@@parsesoftpath#1{% - \ifx#1\pgf@stop% - \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% <- removes final moveto (may not be desirable). - \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% - \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% - \expandafter\let\pgf@decorate@inputsegmentobjectsmacro\pgf@decorate@inputsegmentobjects% - \edef\pgf@decorate@totalpathlength{\the\pgfutil@tempdima}% - \let\pgf@next\relax% - \else% - \ifx#1\pgfsyssoftpath@movetotoken% - \let\pgf@next\pgf@decorate@parsemoveto% - \else% - \ifx#1\pgfsyssoftpath@linetotoken% - \let\pgf@next\pgf@decorate@parselineto% - \else% - \ifx#1\pgfsyssoftpath@curvetosupportatoken% - \let\pgf@next\pgf@decorate@parsecurveto% - \else% - \ifx#1\pgfsyssoftpath@closepathtoken% - \let\pgf@next\pgf@decorate@parseclosepath% - \else% - \ifx#1\pgfsyssoftpath@rectcornertoken% - \let\pgf@next\pgf@decorate@parserect% - \else% - \PackageError{PGF}{Unrecognised soft path token `#1'}{}% - \fi% - \fi% - \fi% - \fi% - \fi% - \fi% - \pgf@next} + \ifx#1\pgf@stop% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% <- removes final moveto (may not be desirable). + \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% + \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% + \expandafter\let\pgf@decorate@inputsegmentobjectsmacro\pgf@decorate@inputsegmentobjects% + \edef\pgf@decorate@totalpathlength{\the\pgfutil@tempdima}% + \let\pgf@next\relax% + \else% + \ifx#1\pgfsyssoftpath@movetotoken% + \let\pgf@next\pgf@decorate@parsemoveto% + \else% + \ifx#1\pgfsyssoftpath@linetotoken% + \let\pgf@next\pgf@decorate@parselineto% + \else% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \let\pgf@next\pgf@decorate@parsecurveto% + \else% + \ifx#1\pgfsyssoftpath@closepathtoken% + \let\pgf@next\pgf@decorate@parseclosepath% + \else% + \ifx#1\pgfsyssoftpath@rectcornertoken% + \let\pgf@next\pgf@decorate@parserect% + \else% + \pgferror{Unrecognised soft path token `#1'}% + \fi% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgf@next} \def\pgf@decorate@addtoinputsegmentobjects#1{% - % - % If there is an input segment object waiting (i.e. a moveto), insert it here. - % - \ifx\pgf@decorate@queueinputsegmentobject\pgfutil@empty% - \else% - \let\pgf@decorate@temp\pgf@decorate@queueinputsegmentobject% - \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \fi% - \ifx\pgfpoint@decorated@firstparsed\pgfutil@empty% - #1% - \let\pgfpoint@decorated@firstparsed\pgf@decorate@inputsegment@first% - \fi% - \expandafter\def\expandafter\pgf@decorate@inputsegmentobjects\expandafter% - {\pgf@decorate@inputsegmentobjects{#1}}% -} - -% Convert \pgfsyssoftpath@movetotoken{<X>}{<Y>} into the following + % + % If there is an input segment object waiting (i.e. a moveto), insert it here. + % + \ifx\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \else% + \let\pgf@decorate@temp\pgf@decorate@queueinputsegmentobject% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \fi% + \ifx\pgfpoint@decorated@firstparsed\pgfutil@empty% + #1% + \let\pgfpoint@decorated@firstparsed\pgf@decorate@inputsegment@first% + \fi% + \expandafter\def\expandafter\pgf@decorate@inputsegmentobjects\expandafter% + {\pgf@decorate@inputsegmentobjects{#1}}% +} + +% Convert \pgfsyssoftpath@movetotoken{<X>}{<Y>} into the following % representation: -% -% \pgf@decorate@inputsegmentobject@moveto{\pgf@x X\pgf@y Y} +% +% \pgf@decorate@inputsegmentobject@moveto{\pgf@x X\pgf@y Y} % -% The moveto input segment object is not added immediately, so that -% only the last of multiple movetos is inserted. -% +% The moveto input segment object is not added immediately, so that +% only the last of multiple movetos is inserted. +% \def\pgf@decorate@parsemoveto#1#2{% - \def\pgf@decorate@queueinputsegmentobject{\pgf@decorate@inputsegmentobject@moveto{\pgf@x#1\pgf@y#2}}% - \def\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% - \pgf@decorate@@parsesoftpath% + \def\pgf@decorate@queueinputsegmentobject{\pgf@decorate@inputsegmentobject@moveto{\pgf@x#1\pgf@y#2}}% + \def\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \pgf@decorate@@parsesoftpath% } % Convert \pgfsyssoftpath@linetotoken{<X>}{<Y>} into the following @@ -1692,47 +1689,47 @@ % \pgf@decorate@inputsegmentobject@lineto{<length>}{\pgf@x <Last X> \pgf@y <Last Y}{\pgf@x <X> \pgf@y <Y>} % \def\pgf@decorate@parselineto#1#2{% - \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - \advance\pgfutil@tempdima\pgfmathresult pt\relax% - \edef\pgf@decorate@temp{% - \noexpand\pgf@decorate@inputsegmentobject@lineto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - }% - \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \pgf@decorate@@parsesoftpath% -} - + \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@lineto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + }% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \pgf@decorate@@parsesoftpath% +} + % Convert \pgfsyssoftpath@curvetosupportatoken{<Xa>}{<Ya>}...etc % into the following representation: % % \pgf@decorate@inputsegmentobject@curveto{<length>}{\pgf@x <Last X> \pgf@y <Last Y} -% {\pgf@x <Xa> \pgf@y <Ya>}{\pgf@x <Xb> \pgf@y <Yb>}{\pgf@x <X> \pgf@y <Y>} +% {\pgf@x <Xa> \pgf@y <Ya>}{\pgf@x <Xb> \pgf@y <Yb>}{\pgf@x <X> \pgf@y <Y>} % \def\pgf@decorate@parsecurveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{% - \pgf@decorate@curvelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% - \advance\pgfutil@tempdima\pgfmathresult pt\relax% - \edef\pgf@decorate@temp{% - \noexpand\pgf@decorate@inputsegmentobject@curveto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}% - {\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% - }% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \edef\pgfpoint@decorate@lastparsed{\pgf@x#5\pgf@y#6}% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% - \pgf@decorate@@parsesoftpath% + \pgf@decorate@curvelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@curveto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}% + {\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% + }% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#5\pgf@y#6}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \pgf@decorate@@parsesoftpath% } \def\pgf@decorate@parseclosepath#1#2{% - \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - \advance\pgfutil@tempdima\pgfmathresult pt\relax% - \edef\pgf@decorate@temp{% - \noexpand\pgf@decorate@inputsegmentobject@closepath{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - }% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% - \pgf@decorate@@parsesoftpath% + \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@closepath{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + }% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \pgf@decorate@@parsesoftpath% } % Convert \pgfsyssoftpath@rectcornertoken{<X>}{<Y>}\pgfsyssoftpath@rectsizetoken{<Xa>}{<Ya>} @@ -1756,52 +1753,52 @@ % \newif\ifpgfdecoraterectangleclockwise \def\pgf@decorate@parserect#1#2\pgfsyssoftpath@rectsizetoken#3#4{% - % - % Subvert \pgf@decorate@parsesoftpath so parsing macros will - % return here instead of continuing to parse the soft path. - % - \let\pgf@decorate@orig@@parsesoftpath\pgf@decorate@@parsesoftpath% - \let\pgf@decorate@@parsesoftpath\relax% - \pgf@decorate@parsemoveto{#1}{#2}% - \pgf@xa#1\relax% - \pgf@ya#2\relax% - \ifpgfdecoraterectangleclockwise% - \advance\pgf@ya#4% - \pgf@yb\pgf@ya% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@xa#3% - \pgf@xb\pgf@xa% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@ya-#4% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@xa-#3% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parseclosepath\pgf@temp% - \else% - \advance\pgf@xa#3% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \pgf@xb\pgf@xa% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@ya#4% - \pgf@yb\pgf@ya% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@xa-#3% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@ya-#4% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parseclosepath\pgf@temp% - \fi% - % - % Restore the parsing. - % - \let\pgf@decorate@@parsesoftpath\pgf@decorate@orig@@parsesoftpath% - \edef\pgf@marshal{\noexpand\pgf@decorate@parsemoveto{\the\pgf@xb}{\the\pgf@yb}}% - \pgf@marshal% + % + % Subvert \pgf@decorate@parsesoftpath so parsing macros will + % return here instead of continuing to parse the soft path. + % + \let\pgf@decorate@orig@@parsesoftpath\pgf@decorate@@parsesoftpath% + \let\pgf@decorate@@parsesoftpath\relax% + \pgf@decorate@parsemoveto{#1}{#2}% + \pgf@xa#1\relax% + \pgf@ya#2\relax% + \ifpgfdecoraterectangleclockwise% + \advance\pgf@ya#4% + \pgf@yb\pgf@ya% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa#3% + \pgf@xb\pgf@xa% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya-#4% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa-#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parseclosepath\pgf@temp% + \else% + \advance\pgf@xa#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \pgf@xb\pgf@xa% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya#4% + \pgf@yb\pgf@ya% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa-#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya-#4% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parseclosepath\pgf@temp% + \fi% + % + % Restore the parsing. + % + \let\pgf@decorate@@parsesoftpath\pgf@decorate@orig@@parsesoftpath% + \edef\pgf@marshal{\noexpand\pgf@decorate@parsemoveto{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@marshal% } @@ -1812,8 +1809,8 @@ % Define \pgfmathresult as the distance between #1 and #2 (without units). % \def\pgf@decorate@linelength#1#2{% - \pgf@process{\pgfpointdiff{#1}{#2}}% - \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \pgf@process{\pgfpointdiff{#1}{#2}}% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% } % \pgf@decorate@curvelength @@ -1824,138 +1821,138 @@ % To approximate the length of the curve P (sort of) use: % % curveLength(P,q) -% Q = subdivideLeft(P); -% R = subdivideRight(P); +% Q = subdivideLeft(P); +% R = subdivideRight(P); % return curveLength'(Q,q) + curveLength'(R,q); % % curveLength'(P,q) -% <P1,P2,P3,P4> <- P; +% <P1,P2,P3,P4> <- P; % P' = P4 - P1; % x = P'.x(); -% y = P'.y(); +% y = P'.y(); % if (x < q) && (y < q) -% return |P'|; -% else% -% Q = subdivideLeft(P); -% R = subdivideRight(P); +% return |P'|; +% else% +% Q = subdivideLeft(P); +% R = subdivideRight(P); % return curveLength'(Q,q) + curveLength'(R,q); % % Where q is some small value (`tolerance'). % \newif\ifpgf@decorate@subdivide \def\pgf@decorate@curvelength#1#2#3#4{% - % - % Always begin with a subdivision in case #1 = #4. - % - \begingroup% - \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% - \pgfutil@tempdimb\pgfmathresult pt\relax% - \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% - \advance\pgfutil@tempdimb\pgfmathresult pt\relax% - \pgfmath@returnone\pgfutil@tempdimb% - \endgroup% -} - + % + % Always begin with a subdivision in case #1 = #4. + % + \begingroup% + \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% + \advance\pgfutil@tempdimb\pgfmathresult pt\relax% + \pgfmath@returnone\pgfutil@tempdimb% + \endgroup% +} + \def\pgf@decorate@@curvelength#1#2#3#4{% - \begingroup% - \pgf@decorate@curvecordlength{#1}{#2}{#3}{#4}% - \ifpgf@decorate@subdivide% - \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% - \pgfutil@tempdimb\pgfmathresult pt\relax% - \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% - \advance\pgfutil@tempdimb\pgfmathresult pt\relax% - \expandafter\pgfmath@returnone\expandafter\pgfutil@tempdimb% - \else% - \expandafter\pgfmath@returnone\expandafter\pgfmathresult\expandafter p\expandafter t\expandafter% - \fi% - \endgroup% + \begingroup% + \pgf@decorate@curvecordlength{#1}{#2}{#3}{#4}% + \ifpgf@decorate@subdivide% + \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% + \advance\pgfutil@tempdimb\pgfmathresult pt\relax% + \expandafter\pgfmath@returnone\expandafter\pgfutil@tempdimb% + \else% + \expandafter\pgfmath@returnone\expandafter\pgfmathresult\expandafter p\expandafter t\expandafter% + \fi% + \endgroup% } \def\pgf@decorate@curvelength@tolerance{1pt} \def\pgf@decorate@curvecordlength#1#2#3#4{% - % - % Calculate the curve cord vector. - % - #4\relax% - \pgf@xa\pgf@x\pgf@ya\pgf@y% - #1\relax% - \advance\pgf@xa-\pgf@x% - \advance\pgf@ya-\pgf@y% - \ifdim\pgf@xa<0pt\relax\pgf@xa-\pgf@xa\fi% - \ifdim\pgf@ya<0pt\relax\pgf@ya-\pgf@ya\fi% - % - % Always subdivide, unless... - % - \pgf@decorate@subdividetrue% - % - % The cord vector is small. - % - \ifdim\pgf@xa<\pgf@decorate@curvelength@tolerance\relax% - \ifdim\pgf@ya<\pgf@decorate@curvelength@tolerance\relax% - \pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% - \pgf@decorate@subdividefalse% - \fi% - \fi% + % + % Calculate the curve cord vector. + % + #4\relax% + \pgf@xa\pgf@x\pgf@ya\pgf@y% + #1\relax% + \advance\pgf@xa-\pgf@x% + \advance\pgf@ya-\pgf@y% + \ifdim\pgf@xa<0pt\relax\pgf@xa-\pgf@xa\fi% + \ifdim\pgf@ya<0pt\relax\pgf@ya-\pgf@ya\fi% + % + % Always subdivide, unless... + % + \pgf@decorate@subdividetrue% + % + % The cord vector is small. + % + \ifdim\pgf@xa<\pgf@decorate@curvelength@tolerance\relax% + \ifdim\pgf@ya<\pgf@decorate@curvelength@tolerance\relax% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% + \pgf@decorate@subdividefalse% + \fi% + \fi% } \def\pgf@decorate@recursive@subdividecurve@left#1#2#3#4{% - {% - % - % The left curve (from t=0 to t=.5) - % - #1\relax% - \pgfutil@tempdima\pgf@x% - \pgfutil@tempdimb\pgf@y% - \pgf@xa.5\pgf@x\pgf@ya.5\pgf@y% - \pgf@xb.25\pgf@x\pgf@yb.25\pgf@y% - \pgf@xc.125\pgf@x\pgf@yc.125\pgf@y% - #2\relax% - \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% - \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% - \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% - #3\relax% - \advance\pgf@xb.25\pgf@x\advance\pgf@yb.25\pgf@y% - \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% - #4\relax% - \advance\pgf@xc.125\pgf@x\advance\pgf@yc.125\pgf@y% - \xdef\pgf@marshal{% - \noexpand\pgf@decorate@@curvelength% - {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% - {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} - {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% - }% - }% - \pgf@marshal% + {% + % + % The left curve (from t=0 to t=.5) + % + #1\relax% + \pgfutil@tempdima\pgf@x% + \pgfutil@tempdimb\pgf@y% + \pgf@xa.5\pgf@x\pgf@ya.5\pgf@y% + \pgf@xb.25\pgf@x\pgf@yb.25\pgf@y% + \pgf@xc.125\pgf@x\pgf@yc.125\pgf@y% + #2\relax% + \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% + \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% + \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% + #3\relax% + \advance\pgf@xb.25\pgf@x\advance\pgf@yb.25\pgf@y% + \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% + #4\relax% + \advance\pgf@xc.125\pgf@x\advance\pgf@yc.125\pgf@y% + \xdef\pgf@marshal{% + \noexpand\pgf@decorate@@curvelength% + {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} + {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + }% + }% + \pgf@marshal% } \def\pgf@decorate@recursive@subdividecurve@right#1#2#3#4{% - {% - % - % The right curve (from t=0.5 to t=1) - % - #1\relax% - \pgfutil@tempdima.125\pgf@x\pgfutil@tempdimb.125\pgf@y% - #2\relax% - \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% - \pgf@xa.25\pgf@x\pgf@ya.25\pgf@y% - #3\relax% - \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% - \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% - \pgf@xb.5\pgf@x\pgf@yb.5\pgf@y% - #4\relax% - \advance\pgfutil@tempdima.125\pgf@x\advance\pgfutil@tempdimb.125\pgf@y% - \advance\pgf@xa.25\pgf@x\advance\pgf@ya.25\pgf@y% - \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% - \pgf@xc\pgf@x\pgf@yc\pgf@y% - \xdef\pgf@marshal{% - \noexpand\pgf@decorate@@curvelength% - {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% - {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} - {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% - }% - }% - \pgf@marshal% + {% + % + % The right curve (from t=0.5 to t=1) + % + #1\relax% + \pgfutil@tempdima.125\pgf@x\pgfutil@tempdimb.125\pgf@y% + #2\relax% + \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% + \pgf@xa.25\pgf@x\pgf@ya.25\pgf@y% + #3\relax% + \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% + \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% + \pgf@xb.5\pgf@x\pgf@yb.5\pgf@y% + #4\relax% + \advance\pgfutil@tempdima.125\pgf@x\advance\pgfutil@tempdimb.125\pgf@y% + \advance\pgf@xa.25\pgf@x\advance\pgf@ya.25\pgf@y% + \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \xdef\pgf@marshal{% + \noexpand\pgf@decorate@@curvelength% + {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} + {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + }% + }% + \pgf@marshal% } @@ -1965,138 +1962,138 @@ % #2 - a macro holding the reversed input segment objects. % \def\pgf@decorate@inputsegmentobjects@reverse#1#2{% - \def\pgf@decorate@path@storein{#2}% - \def\pgf@decorate@inputsegments@@temp{}% - \expandafter\pgf@decorate@inputsegments@@reverse@pass@first#1\pgf@stop} + \def\pgf@decorate@path@storein{#2}% + \def\pgf@decorate@inputsegments@@temp{}% + \expandafter\pgf@decorate@inputsegments@@reverse@pass@first#1\pgf@stop} \def\pgf@decorate@inputsegments@@reverse@pass@first#1#2\pgf@stop{% - \def\pgf@decorate@temp{#1}% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% - {\expandafter\pgf@decorate@temp\pgf@decorate@inputsegments@@temp}% - \def\pgf@decorate@test{#2} - \ifx\pgf@decorate@test\pgfutil@empty% - \def\pgf@decorate@next{% - \expandafter\pgf@decorate@inputsegmentobjects@reverse@pass@second\pgf@decorate@inputsegments@@temp\pgf@stop% - }% - \else% - \def\pgf@decorate@next{\pgf@decorate@inputsegments@@reverse@pass@first#2\pgf@stop}% - \fi% - \pgf@decorate@next% -} + \def\pgf@decorate@temp{#1}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% + {\expandafter\pgf@decorate@temp\pgf@decorate@inputsegments@@temp}% + \def\pgf@decorate@test{#2} + \ifx\pgf@decorate@test\pgfutil@empty% + \def\pgf@decorate@next{% + \expandafter\pgf@decorate@inputsegmentobjects@reverse@pass@second\pgf@decorate@inputsegments@@temp\pgf@stop% + }% + \else% + \def\pgf@decorate@next{\pgf@decorate@inputsegments@@reverse@pass@first#2\pgf@stop}% + \fi% + \pgf@decorate@next% +} \def\pgf@decorate@inputsegmentobjects@reverse@pass@second#1#2#3\pgf@stop{% - \def\pgf@decorate@inputsegments@temp{#3}% - \def\pgf@decorate@inputsegments@@temp{}% - \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty - \let\pgf@decorate@last@object=\pgfutil@empty - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% - \expandafter\pgf@decorate@path@@reverse@pass@second\pgf@decorate@inputsegments@temp\pgf@stop}% + \def\pgf@decorate@inputsegments@temp{#3}% + \def\pgf@decorate@inputsegments@@temp{}% + \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty + \let\pgf@decorate@last@object=\pgfutil@empty + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% + \expandafter\pgf@decorate@path@@reverse@pass@second\pgf@decorate@inputsegments@temp\pgf@stop}% \def\pgf@decorate@path@@reverse@pass@second#1{% - \ifx#1\pgf@stop% - \expandafter\def\expandafter\pgf@decorate@inputsegments@@temp\expandafter{% - \pgf@decorate@inputsegments@@temp% - {\pgf@decorate@inputsegmentobject@endofinputsegments}% - {\pgf@decorate@inputsegmentobject@endofinputsegments} - }% - \expandafter\let\pgf@decorate@path@storein=\pgf@decorate@inputsegments@@temp% - \let\pgf@decorate@next=\relax% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@moveto% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@moveto% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@lineto% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@lineto% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@curveto% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@curveto% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@closepath% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@closepath% - \else% - \fi% - \fi% - \fi% - \fi% - \fi% - \pgf@decorate@next% + \ifx#1\pgf@stop% + \expandafter\def\expandafter\pgf@decorate@inputsegments@@temp\expandafter{% + \pgf@decorate@inputsegments@@temp% + {\pgf@decorate@inputsegmentobject@endofinputsegments}% + {\pgf@decorate@inputsegmentobject@endofinputsegments} + }% + \expandafter\let\pgf@decorate@path@storein=\pgf@decorate@inputsegments@@temp% + \let\pgf@decorate@next=\relax% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@moveto% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@moveto% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@lineto% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@lineto% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@curveto% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@curveto% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@closepath% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@closepath% + \else% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgf@decorate@next% } \newif\ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting \def\pgf@decorate@inputsegmentobjects@reverse@moveto#1{% - \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% - \edef\pgf@decorate@current@inputsegmentobject{% - {\noexpand\pgf@decorate@inputsegmentobject@closepath% - {\pgf@decorate@reverse@closepath@length}% - {\pgf@decorate@last}% - {#1}% - }% - }% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% - \else% - \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% - \fi% - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% - \pgf@decorate@path@@@reverse@pass@second% + \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% + \edef\pgf@decorate@current@inputsegmentobject{% + {\noexpand\pgf@decorate@inputsegmentobject@closepath% + {\pgf@decorate@reverse@closepath@length}% + {\pgf@decorate@last}% + {#1}% + }% + }% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% + \else% + \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% + \fi% + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% + \pgf@decorate@path@@@reverse@pass@second% } \newif\ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting \def\pgf@decorate@inputsegmentobjects@reverse@closepath#1#2#3{% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingtrue% - \def\pgf@decorate@reverse@closepath@length{#1}% - \def\pgf@decorate@current@inputsegmentobject{}% - \pgf@decorate@inputsegmentobjects@reverse@lineto{#1}{#2}{#3}% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingtrue% + \def\pgf@decorate@reverse@closepath@length{#1}% + \def\pgf@decorate@current@inputsegmentobject{}% + \pgf@decorate@inputsegmentobjects@reverse@lineto{#1}{#2}{#3}% } \def\pgf@decorate@inputsegmentobjects@reverse@lineto#1#2#3#4{% - \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% - \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@moveto{#3}}}% - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% - \else% - \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% - \fi% - \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% - \ifx#4\pgf@decorate@inputsegmentobject@moveto% - \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% - \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@closepath{#1}{#3}{#2}}}% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% - \else% - \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% - \fi% - \fi% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgf@decorate@current@inputsegmentobject\expandafter\expandafter\expandafter% - {\expandafter\pgf@decorate@current@inputsegmentobject\pgf@decorate@append@inputsegmentobject} - \def\pgf@decorate@last{#2}% - \pgf@decorate@path@@@reverse@pass@second#4% + \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% + \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@moveto{#3}}}% + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% + \else% + \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% + \fi% + \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% + \ifx#4\pgf@decorate@inputsegmentobject@moveto% + \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% + \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@closepath{#1}{#3}{#2}}}% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% + \else% + \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% + \fi% + \fi% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgf@decorate@current@inputsegmentobject\expandafter\expandafter\expandafter% + {\expandafter\pgf@decorate@current@inputsegmentobject\pgf@decorate@append@inputsegmentobject} + \def\pgf@decorate@last{#2}% + \pgf@decorate@path@@@reverse@pass@second#4% } \def\pgf@decorate@inputsegmentobjects@reverse@curveto#1#2#3#4#5{% - \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% - \def\pgf@decorate@current@inputsegmentobject{% - {\pgf@decorate@inputsegmentobject@moveto{#5}}% - {\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}% - }% - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% - \else% - \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}}% - \fi% - \def\pgf@decorate@last{#2}% - \pgf@decorate@path@@@reverse@pass@second% + \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% + \def\pgf@decorate@current@inputsegmentobject{% + {\pgf@decorate@inputsegmentobject@moveto{#5}}% + {\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}% + }% + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% + \else% + \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}}% + \fi% + \def\pgf@decorate@last{#2}% + \pgf@decorate@path@@@reverse@pass@second% } \def\pgf@decorate@path@@@reverse@pass@second{% - \ifx\pgf@decorate@current@inputsegmentobject\pgfutil@empty% - \else% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% - {\expandafter\pgf@decorate@inputsegments@@temp\pgf@decorate@current@inputsegmentobject}% - \fi% - \pgf@decorate@path@@reverse@pass@second% + \ifx\pgf@decorate@current@inputsegmentobject\pgfutil@empty% + \else% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% + {\expandafter\pgf@decorate@inputsegments@@temp\pgf@decorate@current@inputsegmentobject}% + \fi% + \pgf@decorate@path@@reverse@pass@second% }% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex index 32024c047d6..a9344f6c95c 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulematrix.code.tex,v 1.4 2010/08/24 21:28:58 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulematrix.code.tex,v 1.8 2013/09/17 17:34:00 tantau Exp $ \usepgfmodule{shapes} @@ -156,7 +156,7 @@ \def\pgfmatrix#1#2#3#4#5#6{% \ifpgfmatrix% - \PackageError{pgf}{You cannot nest pgfmatrix environments, yet}{} + \pgferror{You cannot nest pgfmatrix environments, yet} \fi% \bgroup% \everycr{}% @@ -270,26 +270,7 @@ \pgfutil@ifnextchar[{\pgf@matrix@cell@cont}{\pgf@matrix@cell@cont[0pt]}}%} \def\pgf@matrix@cell@cont[#1]{% - \ifnum\pgfmatrixcurrentcolumn<\pgf@matrix@numberofcolumns% - \else% - {% - \global\pgf@matrix@fixedfalse% - \pgf@x=0pt% - \pgf@matrix@addtolength{\pgf@x}{\pgfmatrixcolumnsep}% - \pgf@matrix@addtolength{\pgf@x}{#1}% - \ifpgf@matrix@fixed% - \expandafter\pgfutil@g@addto@macro\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname% - {\global\pgf@picmaxx=0pt}% - \fi% - \advance\pgfmatrixcurrentcolumn by1\relax % only temporary for the following: - \expandafter\xdef\csname pgf@matrix@column@sep@\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@x}% - \ifpgf@matrix@fixed% - \expandafter\gdef\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname{\global\pgf@picminx=0pt}% - \else% - \expandafter\global\expandafter\let\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname=\pgfutil@empty% - \fi% - }% - \fi% + \xdef\pgf@matrix@last@nextcell@options{#1}% &\pgf@matrix@correct@calltrue&% }% @@ -402,19 +383,41 @@ \def\pgf@matrix@endcell{% \ifpgf@matrix@empty@cell@% \else% - \expandafter\pgfmatrixendcode% - \fi + \expandafter\expandafter\expandafter\pgfmatrixendcode% + \expandafter\ifpgf@matrix@last@cell@in@row\expandafter\pgf@matrix@last@cell@in@rowtrue\expandafter\fi% + \fi% \pgfsys@endpicture% + \ifnum\pgfmatrixcurrentcolumn<\pgf@matrix@numberofcolumns% + \else% + \ifpgf@matrix@last@cell@in@row\else% + {% + \global\pgf@matrix@fixedfalse% + \pgf@x=0pt% + \pgf@matrix@addtolength{\pgf@x}{\pgfmatrixcolumnsep}% + \pgf@matrix@addtolength{\pgf@x}{\pgf@matrix@last@nextcell@options}% + \ifpgf@matrix@fixed% + \expandafter\pgfutil@g@addto@macro\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname% + {\global\pgf@picmaxx=0pt}% + \fi% + \advance\pgfmatrixcurrentcolumn by1\relax % only temporary for the following: + \expandafter\xdef\csname pgf@matrix@column@sep@\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@x}% + \ifpgf@matrix@fixed% + \expandafter\gdef\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname{\global\pgf@picminx=0pt}% + \else% + \expandafter\global\expandafter\let\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname=\pgfutil@empty% + \fi% + }% + \fi\fi% + % Special case of the empty picture + \ifdim\pgf@picmaxx=-16000pt\relax% + \global\pgf@picmaxx=0pt\relax% + \global\pgf@picminx=0pt\relax% + \global\pgf@picmaxy=0pt\relax% + \global\pgf@picminy=0pt\relax% + \fi% \csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname% \pgf@matrix@row@finish% \egroup\egroup% - % Special case of the empty picture - \ifdim\pgf@picmaxx=-16000pt\relax% - \pgf@picmaxx=0pt\relax% - \pgf@picminx=0pt\relax% - \pgf@picmaxy=0pt\relax% - \pgf@picminy=0pt\relax% - \fi% % % Step 5: Horizontal gap % @@ -495,8 +498,7 @@ \def\pgf@matrix@padding{% \ifpgf@matrix@correct@call% \else% - \PackageError{pgfbasematrix}{Single ampersand used with wrong - catcode}{}% + \pgferror{Single ampersand used with wrong catcode}% \fi% \hskip\pgf@matrix@paddingskip\hfil% } @@ -599,13 +601,15 @@ % if the cell contains nothing, the following \let will be at the % beginning (macro expansion has stopped here since neither \omit % nor \span was found) - \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end% + \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end + \pgf@matrix@last@cell@in@rowtrue% &\pgf@matrix@correct@calltrue% \global\pgf@matrix@fixedfalse% \pgf@y=0pt% \pgf@matrix@addtolength\pgf@y{\pgfmatrixrowsep}% \pgfutil@ifnextchar[{\pgfmatrixendrow@skip}{\pgf@matrix@finish@line}% } +\newif\ifpgf@matrix@last@cell@in@row \def\pgf@matrix@signal@cell@end{\pgf@matrix@signal@cell@end} % exact definition does not matter, only needs to be unique. diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex new file mode 100644 index 00000000000..913f2edff9d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex @@ -0,0 +1,342 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex,v 1.4 2013/10/09 18:30:27 tantau Exp $ + + +% +% This file defines commands for nonlinear coordinate systems. This is +% needed, for instance, for bend arrow heads. +% +% +% Non-linear coordinate systems transform coordinates, in addition to +% the normal linear transformations, in a, well, non-linear way. An +% example are polar coordinates. +% +% Like the linear transformations, non-linear transformations are +% applied on a low level and they are integrated into the whole path +% construction mechanism. So, while \pgfpointpolar also "does +% something nonlinear", it just provides a way of computing a +% coordinate. In contrast, installing a polar transformation will +% transform everything being drawn using the \pgfpath... commands an +% will even turn a straight line into a circle. +% +% Since computing non-linear transformations is expensive, they are +% only applied "if really necessary". + + + + +% Return a transformed point +% +% #1 = a point +% +% Description: +% +% Applies the current transformation and the current nonlinear +% transformation to the given point and returns the result in \pgf@x/y. + +\def\pgfpointtransformednonlinear#1{% + \pgf@process{% + #1% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \pgf@nlt@list% + } +} + + + + +% Approximate the nonlinear translation locally +% +% Description: +% +% Does a "local syncronization" of the nonlinear transformation with +% the linear transformation regarding the translation part of the +% current nonlinear transformatoin. The *linear* transformation will be +% updated so that it translates things to the point to which the +% nonlinear transformation transforms the origin. The nonlinear +% transformation will be reset. +% +% The net effect is that you can now draw things near the origin as +% before, but with just a linear transformation in force. Note that +% the coordinate system will not be rotated, only a shift is done (use +% the "real" local sync for a full sync). + +\def\pgfapproximatenonlineartranslation{% + \ifx\pgf@nlt@list\pgfutil@empty% + \else% + \pgfpointtransformednonlinear{\pgfpointorigin}% + \pgf@pt@x=\pgf@x% + \pgf@pt@y=\pgf@y% + \let\pgf@nlt@list\pgfutil@empty% + \let\pgf@nlt@moveto\pgf@lt@moveto% + \let\pgf@nlt@lineto\pgf@lt@lineto% + \let\pgf@nlt@curveto\pgf@lt@curveto% + \let\pgf@nlt@closepath\pgf@lt@closepath% + \fi% +} + + + +% Local sync translation +% +% Description: +% +% Does a "complete local syncronization" of the nonlinear +% transformation with the linear transformation. The *linear* +% transformation will be updated so that it transforms things to the +% point to which the nonlinear transformation transforms the +% origin. The nonlinear transformation will be reset. +% +% The net effect is that you can now draw things near the origin as +% before, but with just a linear transformation in force. + +\def\pgfapproximatenonlineartransformation{% + \ifx\pgf@nlt@list\pgfutil@empty% + \else% + \pgfpointtransformednonlinear{\pgfpoint{1pt}{0pt}}% + \pgf@xa\pgf@x + \pgf@ya\pgf@y + \pgfpointtransformednonlinear{\pgfpoint{0pt}{1pt}}% + \pgf@xb\pgf@x + \pgf@yb\pgf@y + \pgfpointtransformednonlinear{\pgfpointorigin}% + \advance\pgf@xa by-\pgf@x + \advance\pgf@xb by-\pgf@x + \advance\pgf@ya by-\pgf@y + \advance\pgf@yb by-\pgf@y + \pgfsettransformentries{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@yb}{\pgf@x}{\pgf@y}% + \let\pgf@nlt@list\pgfutil@empty% + \let\pgf@nlt@moveto\pgf@lt@moveto% + \let\pgf@nlt@lineto\pgf@lt@lineto% + \let\pgf@nlt@curveto\pgf@lt@curveto% + \let\pgf@nlt@closepath\pgf@lt@closepath% + \fi% +} + + + +% Adds a non-linear transformation to the current list of +% transformations. +% +% #1 = code +% +% Description: +% +% When the code #1 is called, \pgf@x and \pgf@y will be set to some +% values, let us call this the point p. The nonlinear transformation +% will now map this point to a new point f(p). The coordinates of this +% point shoudl be returned in \pgf@x and \pgf@y. Furthermore, consider +% the two "unit tangents" (going in $x$-direction and in +% $y$-direction) at point p. The nonlinear transformaiton will map +% these to new tangents, t_x and t_y. The (not necessarily normalized) +% vectors t_x and t_y should be returned in pgf@xa and -ya and pgf@xb +% and pgf@yb. The macro should not do any global assignments except to +% \pgf@x and \pgf@y, but may do arbitrary local assignments. +% +% The effect of installing a new transformation is the following: As +% long as there is at least one nonlinear transformation installed, +% whenever the path construction commands add a curve or line to the +% softpath, the line or curve will be "bend" by applying all of the +% nonlinear transformation installed. In particular, straight lines +% will be replaced by curves. +% +% Note that the normal linear transformation are always applied before +% any nonlinear transformations are applied. + +\def\pgftransformnonlinear#1{% + \expandafter\def\expandafter\pgf@nlt@list\expandafter{\pgf@nlt@list#1}% + \let\pgf@nlt@moveto\pgf@nlt@moveto@nlt + \let\pgf@nlt@lineto\pgf@nlt@lineto@nlt + \let\pgf@nlt@curveto\pgf@nlt@curveto@nlt + \let\pgf@nlt@closepath\pgf@nlt@closepath@nlt +} + +\def\pgf@nlt@moveto@nlt#1#2{% + {% + \pgfutil@tempdima#1% + \pgfutil@tempdimb#2% + \pgf@x\pgfutil@tempdima% + \pgf@y\pgfutil@tempdimb% + \xdef\pgf@nlt@last@moveto@orig{{\the\pgf@x}{\the\pgf@y}}% + \pgf@nlt@list% + \xdef\pgf@nlt@last@moveto@trans{{\the\pgf@x}{\the\pgf@y}}% + \xdef\pgf@nlt@last@moveto@xaxis{{\the\pgf@xa}{\the\pgf@ya}}% + \xdef\pgf@nlt@last@moveto@yaxis{{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \pgfsyssoftpath@moveto{\the\pgf@x}{\the\pgf@y}% + \global\let\pgf@nlt@last@coord@orig\pgf@nlt@last@moveto@orig% + \global\let\pgf@nlt@last@coord@trans\pgf@nlt@last@moveto@trans% + \global\let\pgf@nlt@last@coord@xaxis\pgf@nlt@last@moveto@xaxis% + \global\let\pgf@nlt@last@coord@yaxis\pgf@nlt@last@moveto@yaxis% + }% +} + + +\def\pgf@nlt@lineto@nlt#1#2{% + {% + \edef\pgf@temp{\pgf@xc\the#1\pgf@yc\the#2}% + \pgf@temp% + \expandafter\pgfqpoint\pgf@nlt@last@coord@orig% + \expandafter\pgf@nlt@set@temps\pgf@nlt@last@coord@trans% + % Test, whether the points are quite near: + \pgf@xa\pgf@x\advance\pgf@xa by-\pgf@xc% + \pgf@ya\pgf@y\advance\pgf@ya by-\pgf@yc% + \pgfutil@tempswafalse% + \ifdim\pgf@xa<0.1pt\relax\ifdim\pgf@xa>-0.1pt\relax\ifdim\pgf@ya<0.1pt\relax\ifdim\pgf@ya>-0.1pt\relax\pgfutil@tempswatrue\fi\fi\fi\fi% + \ifpgfutil@tempswa% + \pgf@x\pgf@xc\pgf@y\pgf@yc% + \xdef\pgf@nlt@last@coord@orig{{\the\pgf@x}{\the\pgf@y}}% + \pgf@process{\pgf@nlt@list}% + \xdef\pgf@nlt@last@coord@trans{{\the\pgf@x}{\the\pgf@y}}% + \xdef\pgf@nlt@last@coord@xaxis{{\the\pgf@xa}{\the\pgf@ya}}% + \xdef\pgf@nlt@last@coord@yaxis{{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}% + \else% + % Compute support points + \pgf@xb=.333333\pgf@x% + \advance\pgf@xb by.666666\pgf@xc% + \pgf@yb=.333333\pgf@y% + \advance\pgf@yb by.666666\pgf@yc% + \pgf@xa=.333333\pgf@xc% + \advance\pgf@xa by.666666\pgf@x% + \pgf@ya=.333333\pgf@yc% + \advance\pgf@ya by.666666\pgf@y% + \pgf@nlt@inner@curve% + \fi% + }% +} + +\def\pgf@nlt@set@temps#1#2{% + \pgfutil@tempdima#1\pgfutil@tempdimb#2% +} + +\def\pgf@nlt@curveto@nlt#1#2#3#4#5#6{% + {% + \edef\pgf@temp{\pgf@xa\the#1\pgf@ya\the#2\pgf@xb\the#3\pgf@yb\the#4\pgf@xc\the#5\pgf@yc\the#6}% + \pgf@temp% + \pgf@nlt@inner@curve% + }% +} + +\newdimen\pgftransformnonlinearflatness +\pgftransformnonlinearflatness=5pt +\def\pgfsettransformnonlinearflatness#1{\pgfmathsetlength\pgftransformnonlinearflatness{#1}} + + + +% Compute a curve from \pgf@nlt@last@coord@orig to \pgf@xc/\pgf@yc via the +% controls \pgf@xa/\pgf@ya and \pgf@xb/\pgf@yb. +\def\pgf@nlt@inner@curve{% + \expandafter\pgfqpoint\pgf@nlt@last@coord@orig% + % Save delta of supports: + \pgfutil@tempdima\pgf@xa\advance\pgfutil@tempdima by-\pgf@xb + \pgfutil@tempdimb\pgf@ya\advance\pgfutil@tempdimb by-\pgf@yb + \begingroup + % Replace supports by relative supports + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \advance\pgf@xb by-\pgf@xc% + \advance\pgf@yb by-\pgf@yc% + % + % Now, test whether the flatness is satisfied: + % + \pgfutil@tempswafalse + \ifdim\pgfutil@tempdima>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgfutil@tempdima<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgfutil@tempdimb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgfutil@tempdimb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xa>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xa<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@ya>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@ya<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@yb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@yb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifpgfutil@tempswa% + \endgroup% Undo the adjustmenst... + {% + \edef\pgf@orig@xya{\pgf@xa\the\pgf@xa\pgf@ya\the\pgf@ya} + \edef\pgf@orig@xyb{\pgf@xb\the\pgf@xb\pgf@yb\the\pgf@yb} + \edef\pgf@orig@xyc{\pgf@xc\the\pgf@xc\pgf@yc\the\pgf@yc} + \pgfpointcurveattime{.5}% + {\expandafter\pgfqpoint\pgf@nlt@last@coord@orig}% + {\pgf@x\pgf@xa\pgf@y\pgf@ya}% + {\pgf@x\pgf@xb\pgf@y\pgf@yb}% + {\pgf@x\pgf@xc\pgf@y\pgf@yc}% + % First new curve: + % Start is at last@coord@orig, + % first support is at last@coord@orig*t + s*(original xa/ya) + % second support is at xb/yb + % target is at x/y + {% + % Target: + \pgf@xc\pgf@x\pgf@yc\pgf@y + % First support: + \expandafter\pgfqpoint\pgf@nlt@last@coord@orig% + \pgf@orig@xya% + \pgf@xa\pgf@time@s\pgf@xa\advance\pgf@xa by\pgf@time@t\pgf@x% + \pgf@ya\pgf@time@s\pgf@ya\advance\pgf@ya by\pgf@time@t\pgf@y% + \pgf@nlt@inner@curve% + }% + % Second new curve: + % Start is at (new) last@coord@orig + % first support is at xa/ya + % second support is at t*(original xb/yb) + s*(original xc/yc) + % target is at original xc/yc + {% + \pgf@orig@xyb% + \pgf@orig@xyc% + \pgf@xb\pgf@time@t\pgf@xb\advance\pgf@xb by\pgf@time@s\pgf@xc% + \pgf@yb\pgf@time@t\pgf@yb\advance\pgf@yb by\pgf@time@s\pgf@yc% + \pgf@nlt@inner@curve% + }% + }% + \else% + \endgroup% Snap back... + \pgf@nlt@do@inner@curve% + \fi% +} + +\def\pgf@nlt@do@inner@curve{% + \pgf@process{\pgf@x\pgf@xa\pgf@y\pgf@ya\pgf@nlt@list}% + \pgf@xa\pgf@x\pgf@ya\pgf@y% + \pgf@process{\pgf@x\pgf@xb\pgf@y\pgf@yb\pgf@nlt@list}% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \xdef\pgf@nlt@last@coord@orig{{\the\pgf@xc}{\the\pgf@yc}}% + \pgf@process{\pgf@x\pgf@xc\pgf@y\pgf@yc\pgf@nlt@list}% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \xdef\pgf@nlt@last@coord@trans{{\the\pgf@xc}{\the\pgf@yc}}% + \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% + \pgf@protocolsizes{\pgf@xc}{\pgf@yc}% + \pgfsyssoftpath@curveto{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}{\the\pgf@xc}{\the\pgf@yc}% +} + + +\def\pgf@nlt@closepath@nlt{% + {% + \expandafter\pgfqpoint\pgf@nlt@last@moveto@orig% + \expandafter\pgf@nlt@set@temps\pgf@nlt@last@coord@orig% + \advance\pgfutil@tempdima by-\pgf@x% + \advance\pgfutil@tempdimb by-\pgf@y% + \pgfutil@tempswatrue% + \ifdim\pgfutil@tempdima<0.01pt\relax\ifdim\pgfutil@tempdima>-0.01pt\relax\ifdim\pgfutil@tempdimb<0.01pt\relax\ifdim\pgfutil@tempdimb>-0.01pt\relax\pgfutil@tempswafalse\fi\fi\fi\fi% + \ifpgfutil@tempswa% + \pgf@nlt@lineto@nlt{\pgf@x}{\pgf@y}% + \fi% + \pgfsyssoftpath@closepath% + }% +} + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex index e80d3ac06bb..eba114885ea 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex @@ -1,4 +1,5 @@ % Copyright 2006 by Till Tantau +% Copyright 2011 by Saso Zivanovic % % This file may be distributed and/or modified % @@ -6,12 +7,12 @@ % 2. under the GNU Public License. % % See the file doc/generic/pgf/licenses/LICENSE for more details. - -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleoo.code.tex,v 1.8 2010/02/22 22:49:21 tantau Exp $ +% +% Based on pgfmoduleoo.code.tex v1.8 by Till Tantau. This version adds inheritance. -% Support of object-oriented programming in TeX. +% Support of object-oriented programming in TeX, with inheritance. % The oo support works as follows: @@ -52,30 +53,215 @@ % % Description: % -% This command declares a class for futurue use. Inside #2, the macro +% This command declares a class for future use. Inside #2, the macro % \method can be used to declare a method. The \method macro takes a % method name, parameters (methods are normal TeX macros, after all) % and body. -\long\def\pgfooclass#1#2{% - \def\pgfoo@classname{#1}% +% base classes are put in parenthesis before the new class name, but +% are optional. +\def\pgfooclass{% + \pgfutil@ifnextchar ({% + \pgfooclass@ + }{% + \pgfooclass@() + }% +} +\long\def\pgfooclass@(#1)#2#3{% + \def\pgfoo@classname{#2}% + \expandafter\ifx\csname pgfooY\pgfoo@classname.@pgfooinit\endcsname\relax\else + \pgferror{class #2 is already defined}% + \fi + \pgfoo@ciii{#2}{#1}% + \expandafter\let\csname pgfooY#2@pgfoo@mro\endcsname\pgfoo@mro \let\pgfoo@origmethod=\method% \let\pgfoo@origattribute=\attribute% \let\method=\pgfoo@declaremethod% \let\attribute=\pgfoo@declareattribute% - \let\pgfoo@attribute@collection=\pgfutil@empty% - \let\pgfoo@attribute@collection@gc=\pgfutil@empty% - #2% - % Attribute initializer: - \expandafter\let\csname pgfooY\pgfoo@classname.@pgfooinit\endcsname\pgfoo@attribute@collection% - \expandafter\let\csname pgfooY\pgfoo@classname.@pgfoogc\endcsname\pgfoo@attribute@collection@gc% - % Always persent methods: + \let\pgfoo@attributes=\pgfutil@empty% + \let\pgfoo@methods=\pgfutil@empty% + #3% + % inherit + \def\pgfoo@temp@baseclasses{#1}% + \pgfoo@inherit@methods + \pgfoo@inherit@attributes + % Always present (and never inherited) methods: \expandafter\let\csname pgfooY\pgfoo@classname.get handle\endcsname\pgfoo@obj% \expandafter\let\csname pgfooY\pgfoo@classname.get id\endcsname\pgfoo@id% + % for compatibility with previous versions of pgfoo, define method + % with the same name as the class as a synonym for init + \expandafter\let\expandafter\pgfoo@init\csname pgfooY\pgfoo@classname.init\endcsname + \expandafter\let\csname pgfooY\pgfoo@classname.\pgfoo@classname\endcsname\pgfoo@init + % Cleanup \let\method=\pgfoo@origmethod% \let\attribute=\pgfoo@origattribute% } +\def\pgfoo@emptyinit(){} +\def\pgfoo@escapeif#1#2\fi{\fi#1}% a little helper + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Compute MRO using C3 algorithm +% The sequences are enclosed in brackets; elements of sequences and +% the big list are terminated by a comma and a dot, respectively. (Why +% comma *and* a dot: TeX's parset---brackets don't form groups! Soooo, +% why not braces? Because I don't know how do delete excess "{},"s...) + +% #1 = current class, #2 = list of base classes +\def\pgfoo@ciii#1#2{% + % \pgfoo@seq will hold a list of sequences. + % (i) the first sequence has just one element: the current class + \def\pgfoo@seq{[#1,].}% + % (ii) every subclass has a sequence (in the order as they were + % given): the class' sequence is its mro. + \pgfutil@for\pgfoo@baseclass:={#2}\do{% + \edef\pgfoo@baseclass@mro{\csname pgfooY\pgfoo@baseclass @pgfoo@mro\endcsname}% + \expandafter\ifx\expandafter\relax\pgfoo@baseclass@mro\relax\else + \edef\pgfoo@seq{\pgfoo@seq[\pgfoo@baseclass@mro,].}% + \fi + }% + % The final sequence is a sequence of base classes, in the order as + % they were given. + \ifx\relax#2\relax\else + \edef\pgfoo@seq{\pgfoo@seq[#2,].}% + \fi + \edef\pgfoo@temp{()(\pgfoo@seq)}% + \expandafter\pgfoo@ciii@merge\pgfoo@temp +} + +% #1 = MRO so far +% #2 = remaining sequences +% no empty sequences [] should arrive here: they should be removed +% before calling this macro +\def\pgfoo@ciii@merge(#1)(#2){% + \ifx\relax#2\relax + \pgfoo@ciii@done(#1)% + \else\pgfoo@escapeif{% split #2 + \pgfoo@ciii@merge@A(#1)(#2)% + }\fi% +} +% a splitter: to be only called from \pgfoo@ciii@merge +\def\pgfoo@ciii@merge@A(#1)(#2.#3){% + \ifx\relax#3\relax % if #3 is empty, we can take the shortcut + \pgfoo@ciii@mergeA@done(#1)(#2)% + \else\pgfoo@escapeif{% + \pgfoo@ciii@merge@checkHead(#1)()(#2)()(#3)% + }\fi +} + +\def\pgfoo@ciii@mergeA@done(#1)([#2]){% + \pgfoo@ciii@done(#1#2)% +} + +% #1 = MRO so far +% #2 = sequences with bad heads (dot after each sequence) +% [#3,#4] = the sequence whose head we're testing right +% now---obviously, it should not be empty! (#3 has no comma, +% #4 has a comma after each class name) +% #5 = #3 does not occur in the tail of these sequences (dot after +% each sequence) +% #6 = the remaining sequences (dot after each sequence) +\def\pgfoo@ciii@merge@checkHead(#1)(#2)([#3,#4])(#5)(#6){% + \pgfutil@in@{[#3,}{#2}% + \ifpgfutil@in@\pgfoo@escapeif{% #3 is already blacklisted + \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead@P{(#1)(#2[#3,#4].)(#5#6)}% + }\else\pgfoo@escapeif{% + \ifx\relax#6\relax\pgfoo@escapeif{% no more sequences to test the head against! + % so, #3 is a good head, and we can recurse + \pgfoo@ciii@goodHeadFound(#1)(#3)(#2[#4].#5)% + }\else\pgfoo@escapeif{% split #6 and get to work + \pgfoo@ciii@merge@checkHead@A(#1)(#2)([#3,#4])(#5)(#6)% + }\fi + }\fi +} +% splitter: to be only called from \pgfoo@ciii@merge@checkHead +% we will check if #3 occurs in the tail of #6 +\def\pgfoo@ciii@merge@checkHead@A(#1)(#2)([#3,#4])(#5)(#6.#7){% + \pgfoo@ciii@merge@checkHead@B(#1)(#2)([#3,#4])(#5)(#6)(#7)% +} +% splitter: to be only called from \pgfoo@ciii@merge@checkHead@A +% &worker: we will check if #3 occurs in #7. If it does, #3 is a bad head. +\def\pgfoo@ciii@merge@checkHead@B(#1)(#2)([#3,#4])(#5)([#6,#7])(#8){% +% \def\pgfoo@ciii@tempA{#3}\def\pgfoo@ciii@tempB{#5}% +% \ifx\pgfoo@ciii@tempA\pgfoo@ciii@tempB +% \pgferror{An attempt to derive from the same class twice}% +% \else\pgfoo@escapeif{% + \pgfutil@in@{,#3,}{,#7}% + \ifpgfutil@in@\pgfoo@escapeif{% bad head! get next head and restart + % but: need to clean up first! + \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead@P{(#1)(#2[#3,#4].)(#5[#6,#7].#8)}% + }\else\pgfoo@escapeif{% so far, so good + \ifx\relax#8\relax\pgfoo@escapeif{% if #8 is empty, we won: + % #3 is a good head! we will move it to MRO + % but clean-up first! + \pgfoo@ciii@goodHeadFound(#1)(#3)(#2[#4].#5[#6,#7].)% + }\else\pgfoo@escapeif{% proceed to the first seq in #8 + \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead{(#1)(#2)([#3,#4])(#5[#6,#7].)(#8)}% + }\fi + }\fi +% }\fi +} + +% #1 = MRO +% #2 = good head +% #3 = the remaining sequences (in need of removing the good head from +% them, and then also some general cleanup) +\def\pgfoo@ciii@goodHeadFound(#1)(#2)(#3){% + \pgfutil@in@{,#2,}{#3}% + \ifpgfutil@in@\pgfoo@escapeif{% + \def\pgfoo@ciii@removeGoodHead(##1)(##2)(##3,#2,##4){% + \pgfoo@ciii@goodHeadFound(##1)(##2)(##3,##4)}% + \pgfoo@ciii@removeGoodHead(#1)(#2)(#3)% + }\else\pgfoo@escapeif{% + \pgfutil@in@{[#2,}{#3}% + \ifpgfutil@in@\pgfoo@escapeif{% + \def\pgfoo@ciii@removeGoodHead(##1)(##2)(##3[#2,##4){% + \pgfoo@ciii@goodHeadFound(##1)(##2)(##3[##4)}% + \pgfoo@ciii@removeGoodHead(#1)(#2)(#3)% + }\else\pgfoo@escapeif{% + \pgfoo@ciii@clean\pgfoo@ciii@merge{(#1#2,)(#3)}% + }\fi + }\fi +} + +% mediates between the bad head exit of \pgfoo@ciii@merge@checkHead@B +% and \pgfoo@ciii@merge@checkHead; we need the mediator because #3 +% below might have been affected by cleaning. +\def\pgfoo@ciii@merge@checkHead@P(#1)(#2)(#3){% + \if\relax#3\relax % no more good head candidates! + \pgferror{Bad MRO: There is no good (monotonic etc.) + Method Resolution Order for your class hierarchy}% + \else\pgfoo@escapeif{% + \pgfoo@ciii@merge@checkHead@Q(#1)(#2)(#3)% + }\fi +} +% splitter for \pgfoo@ciii@merge@checkHead@P +% #3 = the sequence containing the newest good head candidate +\def\pgfoo@ciii@merge@checkHead@Q(#1)(#2)(#3.#4){% + \pgfoo@ciii@merge@checkHead(#1)(#2)(#3)()(#4)% +} + +% cyclically removes all occurrences of "[]," and "[]." (i.e., empty +% sequences) in #2. When done, calls #1 with whatever remains. +\def\pgfoo@ciii@clean#1#2{% clean commas + \pgfutil@in@{[].}{#2}% clean dots + \ifpgfutil@in@\pgfoo@escapeif{% + \pgfoo@ciii@clean@dot#1#2\pgfoo@ciii@clean@END + }\else\pgfoo@escapeif{% + #1#2% + }\fi +} +\def\pgfoo@ciii@clean@dot#1#2[].#3\pgfoo@ciii@clean@END{% + \pgfoo@ciii@clean#1{#2#3}% +} + +\def\pgfoo@ciii@done(#1,){% + \def\pgfoo@mro{#1}% +} + +% end of C3 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Declare a method @@ -111,10 +297,71 @@ % } % } +% define the method macro and append the method to the method collection \def\pgfoo@declaremethod#1(#2)#3{% - \expandafter\long\expandafter\def\csname pgfooY\pgfoo@classname.#1\endcsname(#2){#3}% + \def\pgfoo@method{#1}% + \ifx\pgfoo@classname\pgfoo@method + \def\pgfoo@method{init}% + \fi + \expandafter\long\expandafter\def\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname(#2){#3}% + \edef\pgfoo@methods{\pgfoo@methods,\pgfoo@method}% +} + +\def\pgfoo@inherit@methods{% + % for non-derived classes: + \expandafter\ifx\expandafter\relax\pgfoo@temp@baseclasses\relax + % if init is not defined, define an empty one + \expandafter\ifx\csname pgfooY\pgfoo@classname.init\endcsname\relax + \expandafter\let\csname pgfooY\pgfoo@classname.init\endcsname\pgfoo@emptyinit% + \edef\pgfoo@methods{,init\pgfoo@methods}% + \fi + \fi + \if\relax\pgfoo@methods\relax\else + % gobble the initial comma + \edef\pgfoo@methods{\expandafter\pgfutil@gobble\pgfoo@methods}% + \fi + % remember the list of collected methods + \expandafter\let\csname pgfooY\pgfoo@classname @pgfoo@methods\endcsname\pgfoo@methods + % get MRO + \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname + % loop throough base classes in MRO + \pgfutil@for\pgfoo@baseclass:=\pgfoo@mro\do{% + \ifx\pgfoo@baseclass\pgfoo@classname % skip self + \else\pgfoo@escapeif{% + % get methods defined in this base class + \expandafter\let\expandafter\pgfoo@methods\csname pgfooY\pgfoo@baseclass @pgfoo@methods\endcsname + \pgfutil@for\pgfoo@method:=\pgfoo@methods\do{% for each method + % check if it is already defined in our class + \expandafter\ifx\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname\relax + % if not, link the method name from our class to base class + \edef\pgfoo@temp{\noexpand\let + \expandafter\noexpand\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname + \expandafter\noexpand\csname pgfooY\pgfoo@baseclass.\pgfoo@method\endcsname}% + \pgfoo@temp + \fi + }% + }\fi + }% } +\def\pgfoosuper(#1,#2).#3({% + #2.get id(\pgfoo@temp@id)% + \edef\pgfoo@classname{\csname pgfooX\pgfoo@temp@id @class\endcsname}% + \def\pgfoo@super@A##1,#1,##2.##3({% + \pgfoo@super@B##2.##3(% + }% + \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname + \expandafter\pgfoo@super@A\expandafter,\pgfoo@mro,.#3(% +} +\def\pgfoo@super@B#1,#2.#3({% + \expandafter\ifx\csname pgfooY#1.#3\endcsname\relax + \pgfoo@escapeif{\pgfoo@super@B#2.#3(}% + \else + \pgfoo@escapeif{\expandafter\pgfoo@caller\pgfoo@temp@id.#1.#3(}% + \fi +} + + % Declare an attribute % @@ -136,21 +383,78 @@ \ifpgfutil@in@% \pgfoo@declareunpack#1;% \else% - \expandafter\def\expandafter\pgfoo@attribute@collection\expandafter{\pgfoo@attribute@collection\pgfoolet{#1}\pgfutil@empty}% - \expandafter\def\expandafter\pgfoo@attribute@collection@gc\expandafter{\pgfoo@attribute@collection@gc\pgfoolet{#1}\relax}% + \pgfoo@declareattribute@\let{#1}\pgfutil@empty \fi% \fi% } -\def\pgfoo@declareunpack#1=#2;{% - \expandafter\def\expandafter\pgfoo@attribute@collection\expandafter{\pgfoo@attribute@collection\pgfooset{#1}{#2}}% - \expandafter\def\expandafter\pgfoo@attribute@collection@gc\expandafter{\pgfoo@attribute@collection@gc\pgfoolet{#1}\relax}% +\def\pgfoo@declareunpack#1=#2;{\pgfoo@declareattribute@\def{#1}{{#2}}} +\def\pgfoo@declareunpackspace#1 =#2;{\pgfoo@declareattribute@\def{#1}{{#2}}} + +% put the initial value in the class's namespace +% put the attr name in a list +\def\pgfoo@declareattribute@#1#2#3{% + \expandafter#1\csname pgfooY\pgfoo@classname @#2\endcsname#3% + \expandafter\def\expandafter\pgfoo@attributes\expandafter{\pgfoo@attributes,#2}% } -\def\pgfoo@declareunpackspace#1 =#2;{% - \expandafter\def\expandafter\pgfoo@attribute@collection\expandafter{\pgfoo@attribute@collection\pgfooset{#1}{#2}}% - \expandafter\def\expandafter\pgfoo@attribute@collection@gc\expandafter{\pgfoo@attribute@collection@gc\pgfoolet{#1}\relax}% + +% for each base class: +% for each attribute declared in that class: +% add the attr on a list if it's not there yet +% convert the list of (attr,class which it comes from) into an +% efficient sequence of triples \op{attrname}\pointer-to-initial-value +% (\op is then set differently in init and garbage collection) +\def\pgfoo@inherit@attributes{% + % store the list of attributes declared in this class for use in + % derived classes + \if\relax\pgfoo@attributes\relax\else + \edef\pgfoo@attributes{\expandafter\pgfutil@gobble\pgfoo@attributes}% gobble comma + \fi + \expandafter\let\csname pgfooY\pgfoo@classname.@pgfoo@attributes\endcsname\pgfoo@attributes% + % get MRO + \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname + \def\pgfoo@allattributes{}% here we will store the attrs declared in base classes + \pgfutil@for\pgfoo@baseclass:=\pgfoo@mro\do{% for each base class in MRO order + % the attributes declared in this base class + \expandafter\let\expandafter\pgfoo@attributes\csname pgfooY\pgfoo@baseclass.@pgfoo@attributes\endcsname + \pgfutil@for\pgfoo@attribute:=\pgfoo@attributes\do{% for each attribute + % check if we have already found it in some previous base class + \edef\pgfoo@temp{{,\pgfoo@attribute=}{\pgfoo@allattributes,}} + \expandafter\pgfutil@in@\pgfoo@temp + \ifpgfutil@in@\else % don't overwrite + % append to the list + \edef\pgfoo@allattributes{\pgfoo@allattributes,\pgfoo@attribute=\pgfoo@baseclass}% + \fi + }% + }% + \if\relax\pgfoo@allattributes\relax\else + \edef\pgfoo@allattributes{\expandafter\pgfutil@gobble\pgfoo@allattributes}% gobble comma + \fi + % this macro will hold a list of attributes from all base classes + % we run this macro at init and gc + \def\pgfoo@process@attributes{} + \pgfutil@for\pgfoo@attributeclass:=\pgfoo@allattributes\do{% for each (attribute, class) pair + % append to the attribute processor + \expandafter\pgfoo@inherit@attributes@appendattribute\pgfoo@attributeclass.% + }% + \expandafter\let\csname pgfooY\pgfoo@classname .@pgfoo@process@attributes\endcsname\pgfoo@process@attributes } +% #1=attr, #2=class which the attr comes from +\def\pgfoo@inherit@attributes@appendattribute#1=#2.{% + \def\pgfoo@tempA{\pgfoo@attribute@op{#1}}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfoo@tempB\expandafter\expandafter\expandafter{\expandafter\pgfoo@tempA\csname pgfooY#2@#1\endcsname}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfoo@process@attributes\expandafter\expandafter\expandafter{\expandafter\pgfoo@process@attributes\pgfoo@tempB}% + % above is just this: + % \def\pgfoo@process@attributes{\pgfoo@process@attributes\pgfoo@attribute@op{#1}% + % \csname pgfooY#2@#1\endcsname} + % with \pgfoo@process@attributes and \csname expanded exactly once: +} + +% \pgfoo@attribute@op for garbace collection +\def\pgfoo@gc@attribute#1#2{\pgfoolet{#1}\relax} + + \newcount\pgfoo@objectcount \newcount\pgfoothis@count @@ -250,6 +554,21 @@ +% Help macro for scanning arguments +\newtoks\pgfoo@toks + +\def\pgfoo@collect@args{% + \pgfutil@ifnextchar\bgroup\pgfoo@collect@args@group\pgfoo@collect@args@nogroup% +} +\def\pgfoo@collect@args@nogroup#1){% + \pgfoo@toks{#1}% + \pgfoo@continue% +} +\def\pgfoo@collect@args@group#1{% + \pgfutil@ifnextchar){\pgfoo@toks{{#1}}\expandafter\pgfoo@continue\pgfutil@gobble}{\pgfoo@collect@args@nogroup{#1}}% +} + + % Instantiate an object % % Possible syntax: @@ -276,32 +595,73 @@ }% }% } -\def\pgfoo@new#1=new #2(#3){% +\def\pgfoo@new#1=new #2({% \expandafter\ifx\csname pgfooY#2.get id\endcsname\relax% - \PackageError{pgfoo}{Unknown class '#2'}{}% + \pgferror{Unknown class '#2'}% \else% - \advance\pgfoo@objectcount by 1\relax% - \edef\pgfoolastobj{\noexpand\pgfoo@caller{\the\pgfoo@objectcount}}% - \expandafter\gdef\csname pgfooX\the\pgfoo@objectcount @class\endcsname{#2}% - \let#1\pgfoolastobj% + \pgfoo@new@create#1{#2}% {% \pgfoothis@count\pgfoo@objectcount% - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfooinit\endcsname% + \let\pgfoo@attribute@op\pgfoolet + \csname pgfooY#2.@pgfoo@process@attributes\endcsname% }% - \pgfoolastobj.#2(#3)% - \aftergroup\pgfoogc% cleanup after group + \let\pgfoo@continue=\pgf@oo@new@cont% + \expandafter\pgfoo@collect@args% \fi% } -\def\pgfoo@new@attribute#1=new #2(#3){% - \pgfoo@new\pgf@oo@temp=new #2(#3)% - \pgfoolet{#1}\pgf@oo@temp% + +\def\pgf@oo@new@cont{% + \expandafter\pgfoolastobj\expandafter.\expandafter i\expandafter n\expandafter i\expandafter t\expandafter(\the\pgfoo@toks)% + \aftergroup\pgfoogc% cleanup after group } +\def\pgfoo@new@attribute#1=new #2({% + \expandafter\ifx\csname pgfooY#2.get id\endcsname\relax% + \pgferror{Unknown class '#2'}% + \else% + \pgfoo@new@create\pgfoo@temp{#2}% + {% + \pgfoothis@count\pgfoo@objectcount% + \let\pgfoo@attribute@op\pgfoolet% + \csname pgfooY#2.@pgfoo@process@attributes\endcsname% + }% + \pgfoolet{#1}\pgfoo@temp% + \let\pgfoo@continue=\pgf@oo@new@cont% + \expandafter\pgfoo@collect@args% + \fi% +} -\def\pgfoo@caller#1.#2(#3){% +\def\pgf@oo@new@cont{% + \expandafter\pgfoolastobj\expandafter.\expandafter i\expandafter n\expandafter i\expandafter t\expandafter(\the\pgfoo@toks)% + \aftergroup\pgfoogc% cleanup after group +} + +\def\pgfoo@new@create#1#2{% + \advance\pgfoo@objectcount by 1\relax% + \edef\pgfoolastobj{\noexpand\pgfoo@caller{\the\pgfoo@objectcount}}% + \expandafter\gdef\csname pgfooX\the\pgfoo@objectcount @class\endcsname{#2}% + \let#1\pgfoolastobj% +} + +\def\pgfoo@caller#1.#2({% + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY\csname pgfooX#1@class\endcsname.#2\endcsname% + \ifx\pgfoo@caller@temp\relax% + % assume that #2 is of form "superclass.method" + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY#2\endcsname% + \ifx\pgfoo@caller@temp\relax% + \pgferror{Object #1 has no method '#2'}% + \fi% + \fi% \def\pgf@marshal{% \pgfoothis@count=#1\relax% - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#2\endcsname(#3)% + }% + \let\pgfoo@continue\pgfoo@caller@cont% + \pgfoo@collect@args% +} +\def\pgfoo@caller@cont{% + \edef\pgf@marshal{% + \pgf@marshal% + \noexpand\pgfoo@caller@temp(\the\pgfoo@toks)% }% \expandafter\pgf@marshal\expandafter\pgfoothis@count\the\pgfoothis@count\relax% } @@ -309,11 +669,18 @@ % The special "this" object -\def\pgfoothis.#1(#2){% - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#1\endcsname(#2)% +\def\pgfoothis.#1({% + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#1\endcsname% + \ifx\pgfoo@caller@temp\relax% + % assume that #1 is of form "superclass.method" + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY#1\endcsname% + \fi% + \let\pgfoo@continue\pgfoothis@cont% + \pgfoo@collect@args% +} +\def\pgfoothis@cont{% + \expandafter\pgfoo@caller@temp\expandafter(\the\pgfoo@toks)% } - - @@ -390,7 +757,8 @@ \else% % Cleanup this object: % The following is the fast version of \pgfooobj{\the\pgfoo@objectcount}.@pgfoogc: - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfoogc\endcsname% + \let\pgfoo@attribute@op\pgfoo@gc@attribute + \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfoo@process@attributes\endcsname% \expandafter\global\expandafter\let\csname pgfooX\the\pgfoothis@count @class\endcsname\relax% \fi% \pgfoo@next% @@ -398,6 +766,28 @@ +% +% +% Object class +% defines method "copy" +% +% + +\pgfooclass{object}{% + \method copy(#1) {% + % create a new object + \edef\pgfoo@temp@classname{\csname pgfooX\the\pgfoothis@count @class\endcsname}% + \expandafter\pgfoo@new@create\expandafter#1\expandafter{\pgfoo@temp@classname}% + \def\pgfoo@copy@attributes##1##2{% + \pgfooget{##1}\pgfoo@attrvalue + \expandafter\let\csname pgfooX\the\pgfoo@objectcount @##1\endcsname\pgfoo@attrvalue + }% + \let\pgfoo@attribute@op\pgfoo@copy@attributes + \csname pgfooY\pgfoo@temp@classname .@pgfoo@process@attributes\endcsname + \aftergroup\pgfoogc% cleanup after group + } +} + % % diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex index ed13b25324c..0a08a5e9d4e 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleparser.code.tex,v 1.1 2009/01/12 12:56:09 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleparser.code.tex,v 1.2 2013/07/15 12:05:34 tantau Exp $ % % This file defines commands for defining a letter-by-letter parser @@ -43,9 +43,9 @@ \expandafter\let\expandafter\pgf@parser@action% \csname pgf@parser@a@\pgf@parser @all@\meaning\pgf@parser@symbol\endcsname% \ifx\pgf@parser@action\relax% - \PackageError{pgfparse}{Unexpected character + \pgferror{Unexpected character '\meaning\pgf@parser@symbol' in parser '\pgf@parser' in state - '\pgf@parser@state'}{}% + '\pgf@parser@state'}% \fi% \fi% \pgf@parser@action% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex index ea55ca8517b..8620a91e4de 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleplot.code.tex,v 1.8 2010/10/22 17:34:17 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleplot.code.tex,v 1.12 2013/07/31 16:22:24 tantau Exp $ % PGF's plotting interface works as follows: @@ -16,26 +16,35 @@ % need to provide the coordinates (obviously) of the points that % should be plotted. The coordinates are given via a long stream of % commands. These commands are \pgfplotstreamstart, which is -% given exactly once at the beginning, \pgfplotstreampoint, of which there -% are numerous in the middle, \pgfplotstreamspecial, of which there may be -% numerous in the middle, and \pgfplotstreamend, which must be given -% at the end. Between these commands arbitrary other commands may be -% given. Here is an example: +% given exactly once at the beginning, the commands +% \pgfplotstreampoint, \pgfplotstreampointoutlier, +% \pgfplotstreampointundefined, \pgfplotstreamnewdataset, of which +% there are numerous in the middle, the special \pgfplotstreamspecial, +% of which there may be numerous in the middle, and \pgfplotstreamend, +% which must be given at the end. Between these commands arbitrary +% other commands may be given. Here is an example: % % ... % \pgfplotstreamstart % \pgfplotstreampoint{\pgfpointxy{0}{0}} % \pgfplotstreampoint{\pgfpointxy{1}{1}} +% \pgfplotstreamnewdataset % \pgfplotstreampoint{\pgfpointxy{2}{4}} % \relax -% \pgfplotstreampoint{\pgfpointxy{3}{9}} +% \pgfplotstreampointoutlier{\pgfpointxy{3}{9}} % \pgfplotstreamspecial{some handler-dependent special stuff} % \pgfplotstreamend % % By themselves, the \pgfplotstreamxxxx commands do not do anything by % default. Rather, to ``use'' such a stream, you must first install a % stream handler. For example, the ``lineto'' handler will simply -% translate every \pgfplotstreampoint into a \pgfpathlineto. +% basically every \pgfplotstreampoint into a \pgfpathlineto. +% +% One special things is the handling of "jumps" in a stream. For +% instance, when a lineto handler encounters an "outlier" or a new +% data set, the current line should end and a new subpath should start +% (unless configured otherwise). For this, the special jump handler is +% important. % % Example: % @@ -55,9 +64,111 @@ % are set by the handlers: \def\pgfplotstreamstart{\pgf@plotstreamstart} \def\pgfplotstreampoint#1{\gdef\pgfplotlastpoint{#1}\pgf@plotstreampoint{#1}} +\def\pgfplotstreampointoutlier#1{\pgfplot@outliers{}{\pgf@plotstreamjump}{\pgfplotstreampoint{#1}}}% +\def\pgfplotstreampointundefined{\pgfplot@outliers{}{\pgf@plotstreamjump}{}}% +\def\pgfplotstreamnewdataset{\pgfplot@outliers{}{\pgf@plotstreamjump}{}}% \def\pgfplotstreamspecial{\pgf@plotstreamspecial} \def\pgfplotstreamend{\pgf@plotstreamend} +\def\pgfplot@ignorer#1#2#3{#1} +\def\pgfplot@jumper#1#2#3{#2} +\def\pgfplot@plotter#1#2#3{#3} + +\let\pgfplot@outliers\pgfplot@jumper +\let\pgfplot@undefined\pgfplot@jumper +\let\pgfplot@newdata\pgfplot@jumper + +\pgfset{ + handle outlier points in plots/.is choice, + handle outlier points in plots/ignore/.code=\let\pgfplot@outliers\pgfplot@ignorer, + handle outlier points in plots/jump/.code=\let\pgfplot@outliers\pgfplot@jumper, + handle outlier points in plots/plot/.code=\let\pgfplot@outliers\pgfplot@plotter, + handle undefined points in plots/.is choice, + handle undefined points in plots/ignore/.code=\let\pgfplot@undefined\pgfplot@ignorer, + handle undefined points in plots/jump/.code=\let\pgfplot@undefined\pgfplot@jumper, + handle new data sets in plots/.is choice, + handle new data sets in plots/ignore/.code=\let\pgfplot@newdata\pgfplot@ignorer, + handle new data sets in plots/jump/.code=\let\pgfplot@newdata\pgfplot@jumper, +} + + +% Declares a new plot handler +% +% #1 = macro that should install the stream handler subsequently +% #2 = parameter list of said macro. +% #3 = keys as described below +% +% Description: +% +% When you declare a new plot handler, you provide, through keys, +% different "actions" that should be taken when the different stream +% commands are used: +% +% start = some code to be executed when \pgfplotstreamstart is called +% for this plothandler +% end = same for the end of the stream +% point = code to be executed for a point of the stream +% jump = code to be executed for a "jump" in the stream +% special = code to be executed for \pgfplotstreamspecial +% start macro = here and for the following keys, the to-be-executed +% code is stored in the given macro +% end macro = see above +% jump macro = see above +% point macro = see above +% special macro = see above +% +% Example: +% +% \pgfdeclareplothandler{\ultrasimplehandler}{}{ +% point=\pgfpathlineto{##1} +% } + +\def\pgfdeclareplothandler#1#2#3{% + \def#1#2{% + \pgfkeys{% + /pgf/plots/@handler options/.cd, + start=\relax, + end macro=\relax, + point macro=\pgfutil@gobble, + jump macro=\relax, + special macro=\pgfutil@gobble,% + #3% + }% + }% +} + +\pgfkeys{% + /pgf/plots/@handler options/.cd, + start/.code=% + \gdef\pgf@plotstreamstart{% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreamend\pgf@plotstreamend@init% + \global\let\pgf@plotstreampoint\pgf@plotstreampoint@init% + \global\let\pgf@plotstreamjump\pgf@plotstreamjump@init% + \global\let\pgf@plotstreamspecial\pgf@plotstreamspecial@init% + #1% + },% + start macro/.code=% + \gdef\pgf@plotstreamstart{% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreamend\pgf@plotstreamend@init% + \global\let\pgf@plotstreampoint\pgf@plotstreampoint@init% + \global\let\pgf@plotstreamjump\pgf@plotstreamjump@init% + \global\let\pgf@plotstreamspecial\pgf@plotstreamspecial@init% + #1% + },% + end/.code=\gdef\pgf@plotstreamend@init{#1}, + end macro/.code=\global\let\pgf@plotstreamend@init#1, + point/.code=\gdef\pgf@plotstreampoint@init##1{#1}, + point macro/.code=\global\let\pgf@plotstreampoint@init#1, + jump/.code=\gdef\pgf@plotstreamjump@init{#1}, + jump macro/.code=\global\let\pgf@plotstreamjump@init#1, + special/.code=\gdef\pgf@plotstreamspecial@init##1{#1}, + special macro/.code=\global\let\pgf@plotstreamspecial@init#1, +} + +\newif\ifpgf@plot@started + @@ -88,6 +199,7 @@ + % % Handlers % @@ -103,12 +215,9 @@ % \pgfplothandlerlineto % \pgfplotxyfile{mytable} -\def\pgfplothandlerlineto{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@line@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% +\pgfdeclareplothandler{\pgfplothandlerlineto}{}{ + point macro=\pgf@plot@line@handler, + jump=\global\let\pgf@plotstreampoint\pgf@plot@line@handler@move% } \def\pgf@plot@line@handler#1{% @@ -116,29 +225,48 @@ \global\let\pgf@plotstreampoint=\pgfpathlineto% } +\def\pgf@plot@line@handler@move#1{% + \pgfpathmoveto{#1}% + \global\let\pgf@plotstreampoint=\pgfpathlineto% +} + % This handler turns creates a series of lineto commands, with the -% last command being a closepath, resulting in a closed path. +% last command being a closepath, resulting in a closed path. If a +% jump is encountered, the current subpath is closed and a new subpath +% is started. % % Example: % % \pgfplothandlerpolygon % \pgfplotxyfile{mytable} -\def\pgfplothandlerpolygon{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@line@handler@close% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfpathclose% - }% -} +\pgfdeclareplothandler{\pgfplothandlerpolygon}{}{% + point macro=\pgf@plot@line@handler@close, + jump macro=\pgf@plot@next@close@and@moveto, + end macro=\pgf@plot@polygon@stop +}% \def\pgf@plot@line@handler@close#1{% \pgfpathmoveto{#1}% + \global\pgf@plot@startedtrue% \global\let\pgf@plotstreampoint=\pgfpathlineto% } +\def\pgf@plot@polygon@stop{% + \ifpgf@plot@started% + \pgfpathclose% + \fi% + \global\pgf@plot@startedfalse% +} + +\def\pgf@plot@next@close@and@moveto{% + \ifpgf@plot@started% + \pgfpathclose% + \fi% + \global\let\pgf@plotstreampoint\pgf@plot@line@handler@close% +} % More handlers are defined in pgflibraryplothandlers @@ -154,14 +282,7 @@ % \pgfplothandlerdiscard % \pgfplotxyfile{mytable} -\def\pgfplothandlerdiscard{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgfutil@gobble% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% -} - +\pgfdeclareplothandler{\pgfplothandlerdiscard}{}{} @@ -178,14 +299,12 @@ % \pgftransformxshift{1cm} % \myplot -\def\pgfplothandlerrecord#1{% - \def\pgf@plot@recordto{#1}% - \gdef#1{\pgfplotstreamstart}% - \def\pgf@plotstreamstart{% - \gdef\pgf@plotstreampoint####1{\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreampoint{####1}}}% - \gdef\pgf@plotstreamspecial####1{\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamspecial{####1}}}% - \gdef\pgf@plotstreamend{\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamend}}% - }% +\pgfdeclareplothandler{\pgfplothandlerrecord}{#1}{% + start=\gdef#1{\pgfplotstreamstart}, + point=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreampoint{##1}}, + jump=\expandafter\gdef\expandafter#1\expandafter{#1\pgf@plotstreamjump}, + special=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamspecial{##1}}, + end=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamend}, } @@ -212,9 +331,10 @@ \pgfplotstreamstart% \openin\r@pgf@reada=#1 \ifeof\r@pgf@reada - \PackageWarning{pgf}{Plot data file `#1' not found.} + \pgfwarning{Plot data file `#1' not found.} \else \catcode`\#=14 + \catcode`\^^M=5 \pgf@readxyfile% \fi \pgfplotstreamend% @@ -228,7 +348,9 @@ \let\par=\pgf@savedpar% \edef\pgf@temp{\pgf@temp}% \ifx\pgf@temp\pgfutil@empty% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else\ifx\pgf@temp\pgf@partext% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else% \expandafter\pgf@parsexyline\pgf@temp\pgf@stop% \fi\fi% @@ -236,9 +358,18 @@ } \def\pgf@parsexyline#1 #2 #3\pgf@stop{% - \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% + \edef\pgf@xyline@flag@val{#3}% + \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% + \pgfplotstreampointundefined% + \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out% + \pgfplotstreampointoutlier{\pgfpointxy{#1}{#2}}% + \else% + \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% + \fi\fi% } +\edef\pgf@xyline@flag@out{o\space}% +\edef\pgf@xyline@flag@undef{u\space}% @@ -261,9 +392,10 @@ \pgfplotstreamstart% \openin\r@pgf@reada=#1 \ifeof\r@pgf@reada - \PackageWarning{pgf}{Plot data file `#1' not found.} + \pgfwarning{Plot data file `#1' not found.} \else \catcode`\#=14 + \catcode`\^^M=5 \pgf@readxyzfile% \fi \pgfplotstreamend% @@ -273,7 +405,9 @@ \def\pgf@readxyzfile{% \pgfutil@read\r@pgf@reada to \pgf@temp% \ifx\pgf@temp\pgfutil@empty% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else\ifx\pgf@temp\pgf@partext% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else% \expandafter\pgf@parsexyzline\pgf@temp\pgf@stop% \fi\fi% @@ -281,7 +415,14 @@ } \def\pgf@parsexyzline#1 #2 #3 #4\pgf@stop{% - \pgfplotstreampoint{\pgfpointxyz{#1}{#2}{#3}}% + \edef\pgf@xyline@flag@val{#4}% + \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% + \pgfplotstreampointundefined% + \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out% + \pgfplotstreampointoutlier{\pgfpointxyz{#1}{#2}{#3}}% + \else% + \pgfplotstreampoint{\pgfpointxyz{#1}{#2}{#3}}% + \fi\fi% } @@ -314,6 +455,9 @@ \let\pgf@plotwrite=\w@pgf@writea \newif\ifpgf@resample@plot +\pgfkeys{% + /pgf/plot/gnuplot call/.initial={gnuplot}} + \def\pgfplotgnuplot{\pgfutil@ifnextchar[{\pgf@plotgnuplot}{\pgf@plotgnuplot[\jobname]}}%} \def\pgf@plotgnuplot[#1]#2{% \pgf@resample@plottrue% @@ -344,25 +488,27 @@ \immediate\pgfutil@write\pgf@plotwrite{\pgf@gnuplot@head}% \immediate\pgfutil@write\pgf@plotwrite{#2}% \immediate\closeout\pgf@plotwrite% - \immediate\pgfutil@write18{gnuplot \pgf@plotgnuplotfile}% + \immediate\pgfutil@write18{% + \pgfkeysvalueof{/pgf/plot/gnuplot call} \pgf@plotgnuplotfile}% \fi% - % temporarily redefine \pgf@parsexyline - \let\pgf@savedparsexyline=\pgf@parsexyline% - \let\pgf@parsexyline=\pgf@parsegnuplotxyline% +% \let\pgf@savedparsexyline=\pgf@parsexyline% +% \let\pgf@parsexyline=\pgf@parsegnuplotxyline% \pgfplotxyfile{\pgf@plottablefile}% - \let\pgf@parsexyline=\pgf@savedparsexyline% -} - -\def\pgf@parsegnuplotxyline#1 #2 #3\pgf@stop{% - \edef\pgf@xyline@flag@val{#3}% - \edef\pgf@xyline@flag@undef{u\space}% - \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% - \else% - \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% - \fi% +% \let\pgf@parsexyline=\pgf@savedparsexyline% } - +% \def\pgf@parsegnuplotxyline#1 #2 #3\pgf@stop{% +% \edef\pgf@xyline@flag@val{#3}% +% \edef\pgf@xyline@flag@out{o\space}% +% \edef\pgf@xyline@flag@undef{u\space}% +% \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% +% \pgfplotstreampointundefined% +% \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out% +% \pgfplotstreampointoutlier{\pgfpointxy{#1}{#2}}% +% \else% +% \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% +% \fi\fi% +% } % This producer handler plots a function using pgf's mathematical engine. % diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex index da75b3e2e43..7e4e65d4c38 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleshapes.code.tex,v 1.13 2010/09/09 13:52:57 cjorssen Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleshapes.code.tex,v 1.34 2013/10/31 15:44:19 tantau Exp $ @@ -38,12 +38,12 @@ \def\pgfmultipartnode#1#2#3#4{% \pgfutil@ifundefined{pgf@sh@s@#1}% - {\PackageError{pgf}{Unknown shape ``#1''}{}}% + {\pgferror{Unknown shape ``#1''}}% {% {% \let\pgf@sh@savedmacros=\pgfutil@empty% MW \let\pgf@sh@savedpoints=\pgfutil@empty% - \def\shape@name{#1}% CJ + \def\pgf@sm@shape@name{#1}% CJ % TT added prefix! \csname pgf@sh@s@#1\endcsname% \pgf@sh@savedpoints% \pgf@sh@savedmacros% MW @@ -57,15 +57,8 @@ }% % Save the saved points and the transformation matrix \edef\pgf@node@name{#3}% - \ifx\pgf@positionnodelater@macro\relax% - \else% - % Rename node - \edef\pgf@node@name{not yet positioned@\pgf@node@name}% - % Interrupt bounding box! - \pgfinterruptboundingbox% - % Put everything in our box: - \setbox\pgfpositionnodelaterbox=\hbox\bgroup% - % + \ifpgflatenodepositioning + \pgf@shapes@late@pos@begin% \fi% \ifx\pgf@node@name\pgfutil@empty% \else% @@ -74,20 +67,29 @@ \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedpoints}% \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@ma@\pgf@node@name\endcsname}% MW \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedmacros}% MW - \pgfgettransform\pgf@temp + \pgfgettransform\pgf@temp% \expandafter\xdef\csname pgf@sh@nt@\pgf@node@name\endcsname{\pgf@temp}% \expandafter\xdef\csname pgf@sh@pi@\pgf@node@name\endcsname{\pgfpictureid}% \fi% \pgfutil@ifundefined{pgf@sh@bbg@#1}{} {{\pgfscope\csname pgf@sh@bbg@#1\endcsname\endpgfscope}}% - \pgfutil@ifundefined{pgf@sh@bg@#1}{}% - {\csname pgf@sh@bg@#1\endcsname#4}% + \pgfutil@ifundefined{pgf@sh@bg@#1}{% + \global\let\pgfpositionnodelaterpath\pgfutil@empty% + }% + {\csname pgf@sh@bg@#1\endcsname% + \ifpgflatenodepositioning% + \pgfsyssoftpath@getcurrentpath\pgfpositionnodelaterpath% + \pgfprocessround{\pgfpositionnodelaterpath}{\pgfpositionnodelaterpath}% + \global\let\pgfpositionnodelaterpath\pgfpositionnodelaterpath% + \fi% + #4}% \pgfutil@ifundefined{pgf@sh@fbg@#1}{} {{\pgfscope\csname pgf@sh@fbg@#1\endcsname\endpgfscope}}% {% \expandafter\pgfutil@for\expandafter\pgf@shape@com\expandafter:\expandafter=\csname pgf@sh@boxes@#1\endcsname\do{% {% \pgftransformshift{\pgf@sh@reanchor{#1}{\pgf@shape@com}}% + \pgfapproximatenonlineartransformation% \expandafter\pgfqboxsynced\expandafter{\csname pgfnodepart\pgf@shape@com box\endcsname}% }% }% @@ -98,23 +100,44 @@ {\csname pgf@sh@fg@#1\endcsname#4}% \pgfutil@ifundefined{pgf@sh@ffg@#1}{}% {{\pgfscope\csname pgf@sh@ffg@#1\endcsname\endpgfscope}}% - \ifx\pgf@positionnodelater@macro\relax% - \expandafter\pgf@nodecallback\expandafter{\pgf@node@name}% + \ifpgflatenodepositioning% + \pgf@shapes@late@pos@end% \else% - \egroup% Close box - \edef\pgfpositionnodelaterminx{\the\pgf@picminx}% - \edef\pgfpositionnodelaterminy{\the\pgf@picminy}% - \edef\pgfpositionnodelatermaxx{\the\pgf@picmaxx}% - \edef\pgfpositionnodelatermaxy{\the\pgf@picmaxy}% - \let\pgfpositionnodelatername=\pgf@node@name% - \pgf@positionnodelater@macro% - \endpgfinterruptboundingbox% + \expandafter\pgf@nodecallback\expandafter{\pgf@node@name}% \fi% }% }% } - +\def\pgf@shapes@late@pos@begin{% + % Rename node + \edef\pgf@node@name{not yet positionedPGFINTERNAL\pgf@node@name}% + % Interrupt bounding box! + \pgfinterruptboundingbox% + % Put everything in our box: + \pgf@relevantforpicturesizetrue% + \setbox\pgfpositionnodelaterbox=\hbox% + \bgroup% +} + +\def\pgf@shapes@late@pos@end{% + \egroup% Close box + \ifdim\pgf@picminx>\pgf@picmaxx\relax% happens for empty nodes + \def\pgfpositionnodelaterminx{0.0pt}% + \let\pgfpositionnodelaterminy\pgfpositionnodelaterminx% + \let\pgfpositionnodelatermaxx\pgfpositionnodelaterminx% + \let\pgfpositionnodelatermaxy\pgfpositionnodelaterminx% + \else% + \edef\pgfpositionnodelaterminx{\the\pgf@picminx}% + \edef\pgfpositionnodelaterminy{\the\pgf@picminy}% + \edef\pgfpositionnodelatermaxx{\the\pgf@picmaxx}% + \edef\pgfpositionnodelatermaxy{\the\pgf@picmaxy}% + \fi% + \let\pgfpositionnodelatername=\pgf@node@name% + \pgf@positionnodelater@macro% + \endpgfinterruptboundingbox% +} + \def\pgf@shift@node#1#2{% % This internal command shifts the recorded coordinates for node #1 % by the vector #2. It is used to @@ -199,7 +222,7 @@ % \pgfpositionnodelatername % The name of the just-created-node. This name will be the % originally "desired" name of the box plus the prefix "not yet -% positioned box@". +% positioned boxPGFINTERNAL". % % \pgfpositionnodelaterminx % \pgfpositionnodelatermaxx @@ -218,11 +241,21 @@ % When \pgfpositionnodenow is called, the macros mentioned above % should have the exact same values they had when #1 is called. -\def\pgfpositionnodelater#1{\let\pgf@positionnodelater@macro=#1\relax} +\def\pgfpositionnodelater#1{% + \let\pgf@positionnodelater@macro=#1% + \ifx\pgf@positionnodelater@macro\relax% + \pgflatenodepositioningfalse% + \else% + \pgflatenodepositioningtrue% + \fi% +} +\newif\ifpgflatenodepositioning \pgfpositionnodelater{\relax} \def\pgfpositionnodelaterbox{0} + + % Position a node that has been scheduled for later insertion % % #1 = position in the picture, where the original anchor should go, @@ -232,7 +265,7 @@ % % This command works in concert with \pgfpositionnodelater, see the % description there. When \pgfpositionnodenow is called, the macros -% \pgfpositionnodelaterbox and so one should be set to the values they +% \pgfpositionnodelaterbox and so on should be set to the values they % had when the macro given to \pgfpositionnodelater was called. Then, % the box described by these macros will be inserted into the picture % at the position given #1. More precisely, the original node will @@ -241,13 +274,13 @@ % into the actual picture. \def\pgfpositionnodenow#1{% + \pgfinterruptpath% {% \pgfpointtransformed{#1}% \edef\pgf@temp@shift{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} \pgftransformreset% \pgftransformshift{\pgf@temp@shift}% - \setbox\pgfpositionnodelaterbox=\hbox{\pgfsys@beginpicture\box\pgfpositionnodelaterbox\pgfsys@endpicture}% - \pgfqboxsynced{\pgfpositionnodelaterbox}% + \pgfsys@pictureboxsynced\pgfpositionnodelaterbox% \pgf@shift@node{\pgfpositionnodelatername}{\pgf@temp@shift}% % Bounding box update... \pgfpointtransformed{\pgfqpoint{\pgfpositionnodelaterminx}{\pgfpositionnodelaterminy}}% @@ -257,15 +290,65 @@ % Naming and callbacks \expandafter\pgfpositionnodenow@rename\pgfpositionnodelatername\relax% }% + % Late setup% + {% + \csname pgf@lns@\pgfpositionnodelatername\endcsname% + \expandafter\global\expandafter\let\csname pgf@lns@\pgfpositionnodelatername\endcsname\relax% + }% + \endpgfinterruptpath% } -\def\pgfpositionnodenow@rename not yet positioned@#1\relax{% - \pgfnoderename{#1}{not yet positioned@#1} +\def\pgfpositionnodenow@rename not yet positionedPGFINTERNAL#1\relax{% + \pgfnoderename{#1}{not yet positionedPGFINTERNAL#1} \pgf@nodecallback{#1}% } +% "Fake" a node +% +% #1 = node name +% +% Description: +% +% This command will setup things so that it "looks like" a node named +% #1 has been created, but, in reality, no node is created. The idea +% is that a node created in this way can be referenced by systems +% using the late positioning, which will only create the node later +% on. +% +\def\pgffakenode#1{% + \edef\pgf@temp{\ifpgflatenodepositioning not yet positionedPGFINTERNAL\fi#1}% + \expandafter\gdef\csname pgf@sh@ns@\pgf@temp\endcsname{coordinate}% + \expandafter\gdef\csname pgf@sh@np@\pgf@temp\endcsname{\def\centerpoint{\pgfpointorigin}}% + \expandafter\gdef\csname pgf@sh@nt@\pgf@temp\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% + \expandafter\global\expandafter\let\csname pgf@sh@ma@\pgf@temp\endcsname\pgfutil@empty% + \expandafter\xdef\csname pgf@sh@pi@\pgf@temp\endcsname{\pgfpictureid}% +} + + + +% Specify code that should be executed after a node has been created +% +% #1 = node name +% #2 = later code +% +% Description: +% +% This macro allows you to provide some code #2 that will be executed +% right after a node has been positioned using \pgfpositionnodenow. If +% the node has already been positioned (if the late positioning is not +% switched on), nothing happens. + +\def\pgfnodepostsetupcode#1#2{% + \ifpgflatenodepositioning% + \expandafter\ifx\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname\relax% + \expandafter\gdef\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname{#2}% + \else% + \expandafter\pgfutil@g@addto@macro\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname{#2}% + \fi% + \fi% +} @@ -334,19 +417,23 @@ \edef\pgf@temp{#1}% \ifx\pgf@temp\pgfutil@empty% do nothing \else% - \pgf@process{\pgfpointtransformed{#2}}% - \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{coordinate}% - \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% - \noexpand\def\noexpand\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - } - \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% - \expandafter\global\expandafter\let\csname pgf@sh@ma@#1\endcsname\pgfutil@empty% - \expandafter\gdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}% + \ifpgflatenodepositioning% + {\pgftransformshift{#2}\pgfnode{coordinate}{center}{}{#1}{}}% + \else% + \pgf@process{\pgfpointtransformed{#2}}% + \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{coordinate}% + \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% + \noexpand\def\noexpand\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + } + \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% + \expandafter\global\expandafter\let\csname pgf@sh@ma@#1\endcsname\pgfutil@empty% + \expandafter\xdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}% + \fi% \fi% } \def\pgf@sh@redeferredanchor#1#2{% CJ - \expandafter\gdef\csname pgf@anchor@\shape@name @#1\endcsname{#2}}% CJ + \expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @#1\endcsname{#2}}% CJ @@ -393,7 +480,7 @@ {% \pgfutil@ifundefined{pgf@anchor@generic@#2}{% \pgfmathsetcounter{pgf@counta}{#2}% - \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\c@pgf@counta}{1pt}}% + \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\the\c@pgf@counta}{1pt}}% }{% \csname pgf@anchor@generic@#2\endcsname{#1}% }% @@ -414,7 +501,7 @@ % can be used to query the referenced node's name. % This macro is not defined during node creation. \def\pgfdeclaregenericanchor#1#2{% - \expandafter\def\csname pgf@anchor@generic@#1\endcsname##1{#2}% + \expandafter\def\csname pgf@anchor@generic@#1\endcsname##1{#2}% }% @@ -435,7 +522,10 @@ \def\pgfpointanchor#1#2{% % Ok, check whether #1 is known! \pgfutil@ifundefined{pgf@sh@ns@#1} - {\PackageError{pgf}{No shape named #1 is known}{}% + {\pgfutil@ifundefined{pgf@sh@ns@not yet positionedPGFINTERNAL#1}{% + \pgferror{No shape named #1 is known}}{ + % else, fail silently + }% \pgfpointorigin}% {% \pgf@process{% @@ -500,7 +590,7 @@ \def\pgfpointshapeborder#1#2{% % Ok, check whether #1 is known! \pgfutil@ifundefined{pgf@sh@ns@#1} - {\PackageError{pgf}{No shape named #1 is known}{}% + {\pgferror{No shape named #1 is known}% \pgfpointorigin}% {% \pgf@process{% @@ -536,6 +626,25 @@ } +% Retrieve the list of node parts of a shape +% +% #1 = a macro +% #2 = a shape name +% +% Description: +% +% Stores the list of node parts of a shape #2 in the macro #1. +% +% Example: +% +% \pgfgetnodeparts\mylist{circle split} +% +% This will set \mylist\ to "text,lower" + +\def\pgfgetnodeparts#1#2{% + \expandafter\let\expandafter#1\csname pgf@sh@boxes@#2\endcsname% +} + % Declares a shape type % @@ -605,7 +714,7 @@ \long\def\pgfdeclareshape#1#2{% { - \def\shape@name{#1} + \def\pgf@sm@shape@name{#1} \let\savedanchor=\pgf@sh@savedanchor \let\saveddimen=\pgf@sh@saveddimen \let\savedmacro=\pgf@sh@savedmacro% MW @@ -632,48 +741,48 @@ \anchorborder{\csname pgf@anchor@#1@center\endcsname}% \anchor{text}{\pgfpointorigin}% \nodeparts{text}% - \expandafter\global\expandafter\let\csname pgf@sh@s@\shape@name\endcsname=\pgfutil@empty% + \expandafter\global\expandafter\let\csname pgf@sh@s@\pgf@sm@shape@name\endcsname=\pgfutil@empty% #2 } } \def\pgf@sh@savedanchor#1#2{% - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resavedanchor{#1}{#2}}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resavedanchor{#1}{#2}}} \def\pgf@sh@saveddimen#1#2{% - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resaveddimen{#1}{#2}}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resaveddimen{#1}{#2}}} \def\pgf@sh@savedmacro#1#2{% MW - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resavedmacro{#1}{#2}}}% MW -\def\pgf@sh@anchor#1#2{\expandafter\gdef\csname pgf@anchor@\shape@name @#1\endcsname{#2}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resavedmacro{#1}{#2}}}% MW +\def\pgf@sh@anchor#1#2{\expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @#1\endcsname{#2}} \def\pgf@sh@deferredanchor#1#2{% CJ \expandafter\pgfutil@g@addto@macro - \csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@redeferredanchor{#1}{#2}}}% CJ -\def\pgf@sh@anchorborder#1{\expandafter\gdef\csname pgf@anchor@\shape@name @border\endcsname##1{\pgf@process{##1}#1}} -\long\def\pgf@sh@behindbgpath#1{\expandafter\gdef\csname pgf@sh@bbg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@bgpath#1{\expandafter\gdef\csname pgf@sh@bg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@beforebgpath#1{\expandafter\gdef\csname pgf@sh@fbg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@behindfgpath#1{\expandafter\gdef\csname pgf@sh@bfg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@fgpath#1{\expandafter\gdef\csname pgf@sh@fg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@beforefgpath#1{\expandafter\gdef\csname pgf@sg@ffg@\shape@name\endcsname{#1}} -\def\pgf@sh@boxes#1{\expandafter\gdef\csname pgf@sh@boxes@\shape@name\endcsname{#1}} + \csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@redeferredanchor{#1}{#2}}}% CJ +\def\pgf@sh@anchorborder#1{\expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @border\endcsname##1{\pgf@process{##1}#1}} +\long\def\pgf@sh@behindbgpath#1{\expandafter\gdef\csname pgf@sh@bbg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@bgpath#1{\expandafter\gdef\csname pgf@sh@bg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@beforebgpath#1{\expandafter\gdef\csname pgf@sh@fbg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@behindfgpath#1{\expandafter\gdef\csname pgf@sh@bfg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@fgpath#1{\expandafter\gdef\csname pgf@sh@fg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@beforefgpath#1{\expandafter\gdef\csname pgf@sh@ffg@\pgf@sm@shape@name\endcsname{#1}} +\def\pgf@sh@boxes#1{\expandafter\gdef\csname pgf@sh@boxes@\pgf@sm@shape@name\endcsname{#1}} \def\pgf@sh@inheritsavedanchors[from=#1]{% - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\csname pgf@sh@s@#1\endcsname}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\csname pgf@sh@s@#1\endcsname}} \def\pgf@sh@inheritanchor[from=#1]#2{% \edef\pgf@marshal{\global\let\expandafter\noexpand\csname - pgf@anchor@\shape@name @#2\endcsname=\expandafter\noexpand\csname + pgf@anchor@\pgf@sm@shape@name @#2\endcsname=\expandafter\noexpand\csname pgf@anchor@#1@#2\endcsname}% \pgf@marshal% } \def\pgf@sh@inheritanchorborder[from=#1]{% \edef\pgf@marshal{\global\let\expandafter\noexpand\csname - pgf@anchor@\shape@name @border\endcsname=\expandafter\noexpand\csname + pgf@anchor@\pgf@sm@shape@name @border\endcsname=\expandafter\noexpand\csname pgf@anchor@#1@border\endcsname}% \pgf@marshal% } \def\pgf@sh@inheritor#1#2{% \edef\pgf@marshal{\global\let\expandafter\noexpand\csname - pgf@sh@#1@\shape@name\endcsname=\expandafter\noexpand\csname + pgf@sh@#1@\pgf@sm@shape@name\endcsname=\expandafter\noexpand\csname pgf@sh@#1@#2\endcsname}% \pgf@marshal% } @@ -932,6 +1041,15 @@ } +% Special current path start coordinate: +\expandafter\def\csname pgf@sh@ns@current subpath start\endcsname{coordinate} +\expandafter\def\csname pgf@sh@np@current subpath start\endcsname{% + \def\centerpoint{\expandafter\pgfqpoint\pgfsyssoftpath@lastmoveto}% +} +\expandafter\def\csname pgf@sh@nt@current subpath start\endcsname{{1}{0}{0}{1}{0pt}{0pt}} +\expandafter\def\csname pgf@sh@pi@current subpath start\endcsname{\pgfpictureid} + + % Special current bounding box rectangle: \expandafter\def\csname pgf@sh@ns@current bounding box\endcsname{rectangle} @@ -956,8 +1074,8 @@ % Special current page bounding box rectangle: \expandafter\def\csname pgf@sh@ns@current page\endcsname{rectangle} \expandafter\def\csname pgf@sh@np@current page\endcsname{% - \def\southwest{\pgfqpoint{0pt}{0pt}}% - \def\northeast{\pgfqpoint{\paperwidth}{\paperheight}}% + \def\southwest{\pgfpointorigin}% + \def\northeast{\pgfpoint{\pgfsys@thepagewidth}{\pgfsys@thepageheight}}% } \expandafter\def\csname pgf@sh@nt@current page\endcsname{{1}{0}{0}{1}{0pt}{0pt}} \expandafter\def\csname pgf@sh@pi@current page\endcsname{pgfpageorigin} @@ -978,7 +1096,20 @@ \expandafter\gdef\csname pgf@lbb@miny@#1\endcsname{16000pt}% \pgf@size@hookedtrue% \expandafter\def\expandafter\pgf@path@size@hook\expandafter{\pgf@path@size@hook\pgf@lbb@do{#1}} - }% + }, + /pgf/freeze local bounding box/.code={% + {% + \csname pgf@sh@np@#1\endcsname% + \southwest% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \northeast% + \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% + \noexpand\def\noexpand\southwest{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \noexpand\def\noexpand\northeast{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + }% + }% + } } \def\pgf@lbb@do#1{% \ifdim\pgf@size@hook@x<\csname pgf@lbb@minx@#1\endcsname\expandafter\xdef\csname pgf@lbb@minx@#1\endcsname{\the\pgf@size@hook@x}\fi% @@ -1121,7 +1252,7 @@ % % Background path % - \backgroundpath{ + \backgroundpath{% \pgfutil@tempdima=\radius% \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}% \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex index 0d3ad5dfdeb..5f6479a1d7b 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex @@ -7,10 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulesnakes.code.tex,v 1.2 2008/01/17 20:09:17 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulesnakes.code.tex,v 1.3 2013/07/15 12:05:34 tantau Exp $ -\PackageWarning{pgf}{Snakes have been superseded by decorations. Use -the module decorations instead of snakes} +\pgfwarning{Snakes have been superseded by decorations. Use the module decorations instead of snakes} \usepgfmodule{decorations} @@ -251,7 +250,7 @@ the module decorations instead of snakes} % \pgfpathsnakealongvector{zig zag}{100pt}{\pgfpolar{30}{1pt}} \def\pgfpathsnakealongvector#1#2#3{% - \pgfutil@ifundefined{pgf@snake@@#1@initial}{\PackageError{pgf}{Undefined snake ``#1''}{}} + \pgfutil@ifundefined{pgf@snake@@#1@initial}{\pgferror{Undefined snake ``#1''}} { \begingroup% keep things local \pgftransformreset% |