summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgf/modules
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-10-29 00:31:31 +0000
committerKarl Berry <karl@freefriends.org>2010-10-29 00:31:31 +0000
commit6bc1f5497cfb2f56d65c80a4c36ea3bad6dc046c (patch)
treef7751da75030fb1e06653eeb44e579fcee09c65f /Master/texmf-dist/tex/generic/pgf/modules
parented0c7c756e441b2d2ba3633da233fc24361ac0d3 (diff)
pgf 2.10 (28oct10)
git-svn-id: svn://tug.org/texlive/trunk@20236 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/modules')
-rw-r--r--Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex3035
-rw-r--r--Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex334
-rw-r--r--Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex8
-rw-r--r--Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex451
-rw-r--r--Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex111
-rw-r--r--Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex85
-rw-r--r--Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex236
-rw-r--r--Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesorting.code.tex69
8 files changed, 4247 insertions, 82 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex
new file mode 100644
index 00000000000..1c78bb221e6
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex
@@ -0,0 +1,3035 @@
+% Copyright 2006 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduledatavisualization.code.tex,v 1.37 2010/08/24 21:28:58 tantau Exp $
+
+\usepgfmodule{oo,shapes}
+\usepgflibrary{fpu}
+
+
+% This module defines the basic framework for data visualization.
+
+% In order to visualize data, you first need data. The format for this
+% data is not specified, indeed, different formats are possible. A
+% data point is created each time the command \pgfdatapoint is
+% used. The "parameters" of the data point are just the current values
+% of the keys or macros in the current scope.
+%
+% A set of data points created using the \pgfdata command.
+% When a data point is created, a number of signals are emitted, see
+% the description of \pgfdatapoint. To actually visualize something,
+% objects should be created that listen to these signals and that
+% handle them.
+%
+% The following class manages a data visualization
+
+\pgfooclass{data visualization}
+{
+ % Class data visualization
+ %
+ % This class is used to "manage" a data visualization. It provides
+ % methods for hooking into the data visualization process and its
+ % constructor initializes the signals that are issued during a data
+ % visualization.
+ %
+ % When a data visualization object is created, a whole bunch of
+ % signal objects. You should then create objects that connect to
+ % these signals. They will be emitted when datapoints come
+ % available.
+ %
+ % It is permissible to have several data visualization objects
+ % active at the same time.
+ %
+ % To use a data visualization object, you should (possibly
+ % repeatedly) call the method add data() or the macro \pgfdata. You should also
+ % create transformation, mapping and visualization objects. Then,
+ % you should, first, call the method survey, which will "survey" the
+ % data, allowing the mapping and bounding objects to compute the
+ % correct ranges. You may then create further objects based on this
+ % data. Then, you should call the "visualize" method, which will
+ % invoke the visualization signals for the data points.
+
+
+ % These attribute store code that should be executed at certain
+ % points. The order is the following:
+ %
+ % 1. "before survey" code
+ % 2. "begin survey" phase signal
+ % 3. "at start survey" code
+ % 4. data points are processed
+ % 5. "at end survey" code
+ % 6. "end survey" phase signal
+ % 7. "after survey" code
+ %
+ % The first seven points will be repeated until the method "do
+ % another survey" is no longer called during a survey.
+ %
+ % 8. "before visualization" code
+ % 9. "begin visualization" phase signal
+ % 10. "at start visualization" code
+ % 11. data points are processed once more
+ % 12. "at end visualization" code
+ % 13. "end visualization" phase signal
+ % 14. "after visualization" code
+ \attribute before survey;
+ \attribute at start survey;
+ \attribute at end survey;
+ \attribute after survey;
+ \attribute before visualization;
+ \attribute at start visualization;
+ \attribute at end visualization;
+ \attribute after visualization;
+
+ %
+ % Survey counts and handling
+ %
+
+ \attribute survey count=1;
+ % Each time a survey is done before the visualization is done, this
+ % count is incremented. Normally, there is only one survey, but
+ % objects may request another survey or even more surveys to be
+ % done, giving them a chance to setup further internal values. By
+ % accessing this count (via the get survey count method), you can
+ % find out which survey is currently being done.
+
+ \attribute number of surveys=1;
+ % By increasing this count, you can request additional surveys to be
+ % done.
+
+
+ % Stores the to-be-visualized data
+ \attribute data;
+
+
+ % Stores the signal objects
+ \attribute prepare datapoint signal;
+ \attribute map datapoint signal;
+ \attribute transform datapoint signal;
+ \attribute visualize datapoint signal;
+ \attribute finish datapoint signal;
+ \attribute survey datapoint signal;
+ \attribute phase signal;
+ \attribute path signal;
+ \attribute direction signal;
+ \attribute style signal;
+
+
+ % Constructor
+ %
+ % Inits the signals
+ \method data visualization() {
+ \pgfoonew{prepare datapoint signal}=new signal()%
+ \pgfoonew{map datapoint signal}=new signal()%
+ \pgfoonew{transform datapoint signal}=new signal()%
+ \pgfoonew{visualize datapoint signal}=new signal()%
+ \pgfoonew{finish datapoint signal}=new signal()%
+ \pgfoonew{survey datapoint signal}=new signal()%
+ \pgfoonew{phase signal}=new signal()%
+ \pgfoonew{path signal}=new signal()%
+ \pgfoonew{direction signal}=new signal()%
+ \pgfoonew{style signal}=new signal()%
+ %
+ % Store this object in a key
+ %
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeyslet{/pgf/data visualization/obj}\pgf@dv@me
+ }
+
+ % The phase signal will emit the following constants:
+ \def\pgfdvbeforesurvey{1}
+ \def\pgfdvbeginsurvey{2}
+ \def\pgfdvendsurvey{3}
+ \def\pgfdvaftersurvey{4}
+ \def\pgfdvbeforevisualization{5}
+ \def\pgfdvbeginvisualization{6}
+ \def\pgfdvendvisualization{7}
+ \def\pgfdvaftervisualization{8}
+
+ % The path signale will meit the following constants:
+ \def\pgfdvpathmovetotoken{5}
+ \def\pgfdvpathlinetotoken{6}
+ \def\pgfdvdirectionfromtoken{7}
+ \def\pgfdvdirectiontotoken{8}
+
+ % Method
+ %
+ % Connect the object #1's slot "#2" to the signal named "#3"
+ \method connect(#1,#2,#3) {
+ \pgfoovalueof{#3}.connect(#1,#2)
+ }
+
+ % Method
+ %
+ % 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}
+ }
+
+
+ % Setters
+ \method before survey(#1) {
+ \pgfooappend{before survey}{#1}
+ }
+ \method at start survey(#1) {
+ \pgfooappend{at start survey}{#1}
+ }
+ \method before visualization(#1) {
+ \pgfooappend{before visualization}{#1}
+ }
+ \method at start visualization(#1) {
+ \pgfooappend{at start visualization}{#1}
+ }
+
+ % Method
+ \method at end survey(#1) {
+ \pgfooprefix{at end survey}{#1}
+ }
+ \method after survey(#1) {
+ \pgfooprefix{after survey}{#1}
+ }
+ \method at end visualization(#1) {
+ \pgfooprefix{at end visualization}{#1}
+ }
+ \method after visualization(#1) {
+ \pgfooprefix{after visualization}{#1}
+ }
+
+
+ % Method
+ %
+ % Copy the signals to macros. This is just for efficiency (ha!)
+ \method prepare signal macros() {
+ \pgfooget{prepare datapoint signal}\pgf@signalpreparedatapoint
+ \pgfooget{map datapoint signal}\pgf@signalmapdatapoint
+ \pgfooget{transform datapoint signal}\pgf@signaltransformdatapoint
+ \pgfooget{visualize datapoint signal}\pgf@signalvisualizedatapoint
+ \pgfooget{finish datapoint signal}\pgf@signalfinishdatapoint
+ \pgfooget{survey datapoint signal}\pgf@signalsurveydatapoint
+ \pgfooget{phase signal}\pgf@signalphase
+ \pgfooget{path signal}\pgf@signalpath
+ \pgfooget{direction signal}\pgf@signaldirection
+ \pgfooget{style signal}\pgf@signalstyle
+ }
+
+
+ % Survey method
+ %
+ % Call this method to "survey" the data. This should be done before
+ % the "visualize" method is called.
+ \method survey() {
+ % Survey phase.
+ \let\pgfdatapoint=\pgfdatapoint@surveyphase%
+ \pgfoothis.prepare signal macros()
+ \pgfooset{survey count}{1}
+ \pgfutil@loop
+ \pgf@signalphase.emit(\pgfdvbeforesurvey)
+ \pgfoovalueof{before survey}%
+ \pgf@signalphase.emit(\pgfdvbeginsurvey)
+ \pgfoovalueof{at start survey}
+ \pgfoovalueof{data}%
+ \pgfoovalueof{at end survey}
+ \pgf@signalphase.emit(\pgfdvendsurvey)%
+ \pgfoovalueof{after survey}
+ \pgf@signalphase.emit(\pgfdvaftersurvey)
+ \c@pgf@counta=\pgfoovalueof{survey count}\relax
+ \c@pgf@countb=\pgfoovalueof{number of surveys}\relax
+ \ifnum\c@pgf@counta<\c@pgf@countb
+ \advance\c@pgf@counta by1\relax
+ \pgfooeset{survey count}{\the\c@pgf@counta}
+ \pgfutil@repeat
+ }
+
+ % Getter
+ \method get survey count(#1) {
+ \pgfooget{survey count}{#1}
+ }
+
+ % Request another survey to be done
+ \method do an additional survey() {
+ \c@pgf@counta=\pgfoovalueof{number of surveys}\relax
+ \advance\c@pgf@counta by1\relax
+ \pgfooeset{number of surveys}{\the\c@pgf@counta}
+ }
+
+ % Visualize method
+ %
+ % This method will cause the actual visualization.
+ \method visualize() {
+ % Visualization phase.
+ \let\pgfdatapoint=\pgfdatapoint@visualizationphase%
+ \pgfoothis.prepare signal macros()
+ \pgf@signalphase.emit(\pgfdvbeforevisualization)%
+ \pgfoovalueof{before visualization}
+ \pgf@signalphase.emit(\pgfdvbeginvisualization)%
+ \pgfoovalueof{at start visualization}
+ \pgfoovalueof{data}%
+ \pgfoovalueof{at end visualization}
+ \pgf@signalphase.emit(\pgfdvendvisualization)%
+ \pgfoovalueof{after visualization}
+ \pgf@signalphase.emit(\pgfdvaftervisualization)%
+ }
+}
+
+
+%
+% The data point keys
+%
+% Unlike other keys, the subkeys of /data point/ can simply be set
+% directly. If the key has not been initialized, it will automatically
+% be.
+\pgfkeys{/data point/.unknown/.code={%
+ \pgfkeyssetvalue{/data point/\pgfkeyscurrentname}{#1}
+ }}
+
+
+
+
+% Create and handle a data point
+%
+% Description:
+%
+% This command is called by the survey and the visualize methods
+% whenever a complete data point has been produced. Depending on the
+% current circumstances, different signals will be emitted.
+%
+% The data that is represented by the data point is not given as a
+% parameter. Rather, it is stored in macros and keys, that is, the
+% data point is conceptually given by the settings of all the keys and
+% macros in the local scope.
+%
+% There are two phases to data processing: In the survey phase data
+% points are produced and handled in order to find out things like
+% their number or the minimum and maximum values of attributes, so
+% that axes and picture sizes can be prepared correctly. In the
+% visualization phase, data point are actually shown.
+%
+% During the survey phase, for each data point the signal
+% "surveydatapoint" is emitted.
+%
+% During the visualization phase, more signals are emitted. A prepare
+% signal is emitted first, giving all objects a
+% chance to "prepare" for the data point. Note that it is permissible
+% for an object to manipulate the data point here (and also
+% in later on).
+%
+% Next, the command \pgfdvmapdatapointtocanvas is called. Mainly,
+% the effect of this command is to setup the keys /data point/canvas x
+% and /data point/canvas y, see the description of this command for
+% more details.
+%
+% The next step consists of signaling "visualize data point". Objects
+% listening to this will cause some form of visualization of the
+% data point to occur.
+%
+% Before the visualization is started, it is checked whether the key
+% /data point/name is set (to a non-empty value). If so,
+% a coordinate is created with the given canvas x and y values and
+% this key's value as name.
+%
+% Finally, finish data point allows objects to do any final processing
+% of the data point.
+
+\def\pgfdatapoint@surveyphase{%
+ \pgf@signalpreparedatapoint.emit()%
+ \pgf@signalmapdatapoint.emit()%
+ \pgf@signalsurveydatapoint.emit()%
+}
+
+\def\pgfdatapoint@visualizationphase{%
+ \pgf@signalpreparedatapoint.emit()%
+ \pgfdvmapdatapointtocanvas%
+ \pgfkeysifdefined{/data point/name}
+ {%
+ \pgfcoordinate{\pgfkeysvalueof{/data point/name}}{\pgfpointdvdatapoint}%
+ }{}%
+ \pgf@signalvisualizedatapoint.emit()%
+ \pgf@signalfinishdatapoint.emit()%
+}
+
+
+
+% Compute a position of a data point
+%
+% Description:
+%
+% This command uses a special signal to compute the position where a
+% data point should be visualized on the canvas. In detail, the
+% following happens:
+%
+% A local scope is created and the
+% transformation matrix is reset. Then, two signals are emitted: First,
+% "map data points" and then "transform data point". The first
+% lets listening objects "map" the object by setting up
+% attributes of the data point. The second asks objects
+% listening to this signal to transform the current transformation
+% matrix. After the signals, we compute where
+% the origin lies inside this transformed coordinate system. Then the
+% two keys /data point/canvas x and /data point/canvas y are set to
+% the values of this position. The local scope ends (but the settings
+% of the keys persist by a bit of magic), thus restoring the
+% transformation matrix to its original value.
+
+\def\pgfdvmapdatapointtocanvas{%
+ {%
+ \pgfpointdvlocaldatapoint
+ % Smuggle outside group
+ \expandafter%
+ }%
+ \edef\pgf@marshal{%
+ \noexpand\pgfkeyssetvalue{/data point/canvas x}{\the\pgf@x}
+ \noexpand\pgfkeyssetvalue{/data point/canvas y}{\the\pgf@y}
+ }%
+ \pgf@marshal%
+}
+
+% Help functions for locating a canvas data point
+%
+% Description:
+%
+% The first function returns the data point computed by a
+% canvasposition... call.
+
+\def\pgfpointdvdatapoint{%
+ \pgfqpoint{\pgfkeysvalueof{/data point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}%
+}
+
+\def\pgfpointdvlocaldatapoint{%
+ {%
+ % only returns the data point in \pgf@x and \pgf@y, does not set
+ % canvas x and canvas y
+ \pgf@signalmapdatapoint.emit()%
+ \pgftransformreset%
+ \pgf@signaltransformdatapoint.emit()%
+ \pgfpointtransformed{\pgfpointorigin}%
+ }%
+}
+
+
+
+%
+% Special path constructions commands
+%
+%
+% The following commands are used to construct paths based on
+% datapoints.
+%
+% Normally, all these methods need to do is to compute the current
+% canvas position of the current data point and then do a moveto,
+% lineto or some other operation to this position.
+%
+% However, when the coordinate system is weird, like with polar
+% coordinates or spherical or log-polar coordinate or whatever, a
+% straight line "along an attribute" is no longer a straight line.
+% In this case, two actions can be taken:
+%
+% 1. The problem can be ignored, resulting in a wrong line.
+% 2. Some clever algorithm kicks in an replaces the straight line by
+% the correct replacement.
+%
+% As always, when a computer tries to be clever, things can go
+% wrong... Nevertheless, some support for the second method is
+% given. This works as follows: Objects can register to the data
+% visualization path signal. This signal is emitted every time the
+% lineto or moveto commands are executed. If an object reacts to such
+% a command and handles it, it should set
+% \pgfdvhandledtrue.
+
+\newif\ifpgfdvhandled
+
+\def\pgfdv@generic#1#2#3{%
+ {%
+ \pgfdvhandledfalse%
+ \pgf@signalmapdatapoint.emit()%
+ #1.emit(#2)%
+ \ifpgfdvhandled%
+ \else%
+ \pgf@process{%
+ \pgftransformreset%
+ \pgf@signaltransformdatapoint.emit()%
+ \pgfpointtransformed{\pgfpointorigin}%
+ }%
+ #3{}%
+ \fi%
+ }%
+}
+
+
+% Handle a moveto
+%
+% This command has no parameters since the target of the moveto is
+% given by the canvas position of the current local data point.
+\def\pgfpathdvmoveto{%
+ \pgfdv@generic{\pgf@signalpath}{\pgfdvpathmovetotoken}{\pgfpathmoveto}
+}
+
+
+% Handle a lineto
+%
+% This command has no parameters since the target of the moveto is
+% given by the canvas position of the current local data point.
+\def\pgfpathdvlineto{%
+ \pgfdv@generic{\pgf@signalpath}{\pgfdvpathlinetotoken}{\pgfpathlineto}
+}
+
+
+
+% Compute a normalized vector pointing from some point to another.
+%
+% #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
+% 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
+% then sets up the second point and emits the corresponding
+% ...totoken.
+%
+
+\def\pgfpointdvdirection#1#2{%
+ {
+ {
+ #1
+ \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectionfromtoken}{\xdef\pgf@dv@from{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}
+ }
+ {
+ #2
+ \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{
+ \edef\pgf@dv@dir@xa{\the\pgf@x}
+ \edef\pgf@dv@dir@ya{\the\pgf@y}
+ \pgf@process{
+ \pgfpointnormalised{%
+ \pgfpointdiff{\pgf@dv@from}{\pgfqpoint{\pgf@dv@dir@xa}{\pgf@dv@dir@ya}}
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+
+
+%
+%
+% Data parsing and formatting
+%
+%
+
+
+
+% Run the rendering pipeline on a dataset.
+%
+% #1 = options with path /pgf/data/
+% #2 = optionally data given inline in curly braces.
+%
+% Description:
+%
+% This command is used to define a data set. For a single data
+% visualization, multiple data sets can be defined, they will
+% 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:
+%
+% /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.
+%
+% If source is empty, the data is stored in the argument that
+% follows. Otherwise, the file whose name is stored in source is read.
+% This data is stored in an internal variable, which is local to the
+% current group.
+%
+% After the group, the key "/pgf/data/continue code" will be
+% executed.
+%
+% When the data is actually used later on (during a survey or a
+% visualization), independently of what source is used, a format
+% handler is started for each data set. This works as follows: first,
+% the handler's startup code is executed. Then for each line of the
+% data file/the data given inline, the line handler function is
+% called. Finally, the data format end handler is called.
+%
+% The format handler's job is to call \pgfdatapoint each time a
+% complete data point has been produced.
+%
+% Example:
+%
+% \pgfoonew \dv=new data visualization()
+% \pgfoonew \obj=new attribute mapper(...)
+% ...
+%
+% \pgfkeys{/pgf/data/.cd,
+% column 1=dax/low,
+% column 2=dax/high,
+% column 3=dax/entry,
+% column 4=dax/exit}
+%
+% \pgfdata[format=space separated columns]
+% {
+% % today
+% 2000 2300 2100 2200
+% 2000 2350 2200 2500
+% 2200 2300 2250 2260
+% 1800 2260 2260 1900
+% 2000 2300 2100 2200
+% }
+%
+% \pgfdata[format=comma separated columns]
+% {
+% % yesterday
+% 2000, 2350, 2200, 2250
+% 2200, 2300, 2250, 2260
+% }
+%
+% \pgfdata[source=data,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]{%
+ % 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'}{}%
+ \else%
+ \pgfkeysgetvalue{/pgf/data/source}\pgf@dv@source%
+ \ifx\pgf@dv@source\pgfutil@empty%
+ \let\pgf@next\pgf@dataset@grab@inline%
+ \else%
+ \let\pgf@next\pgf@dataset@grab@external%
+ \fi%
+ \pgf@next%
+}
+\def\pgf@dataset@grab@inline{%
+ \pgfutil@ifnextchar\bgroup{%
+ \begingroup%
+ \catcode`\^^M=\active%
+ \pgf@dv@format@catcodes%
+ \pgf@dataset@grab@@inline}%
+ {\PackageError{pgf}{Opening brace expected}{}}%
+}
+\def\pgf@dataset@grab@external{%
+ \fi%
+ \endgroup%
+ \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@external}}})%
+ \pgf@dv@cont@code%
+}
+
+{\catcode`\^^M=\active%
+ \gdef\pgf@dataset@grab@@inline#1{%
+ \endgroup%
+ \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@inline#1^^M\pgf@@eol}}})%
+ \fi%
+ \endgroup%
+ \pgf@dv@cont@code%
+ }%
+}%
+\def\pgf@@eol{\pgf@eol}
+
+\def\pgf@do@data#1#2{%
+ \begingroup%
+ \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}%
+ \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format%
+ \expandafter\let\expandafter\pgf@dv@format@line\csname pgfdv@format@\pgf@dv@format @line\endcsname%
+ \expandafter\let\expandafter\pgf@dv@format@emptyline\csname pgfdv@format@\pgf@dv@format @empty\endcsname%
+ \csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@startup\endcsname%
+ #2%
+ \csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@end\endcsname%
+ \endgroup%
+}
+
+
+%
+% Read external file
+%
+
+\def\pgf@dataset@do@external{%
+ \csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@catcodes\endcsname%
+ \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/source} %
+ \ifeof\r@pgf@reada\relax
+ \PackageError{pgf}{Data source '\pgfkeysvalueof{/pgf/data/source}' not found}{}%
+ \else
+ \pgf@dataset@readline%
+ \fi
+ \immediate\closein\r@pgf@reada%
+}
+
+\def\pgf@partext{\par}%
+\def\pgf@dataset@readline{%
+ \immediate\read\r@pgf@reada to \pgf@temp%
+ \ifx\pgf@temp\pgf@partext%
+ \pgf@dv@format@emptyline%
+ \else%
+ \ifx\pgf@temp\pgfutil@empty%
+ \pgf@dv@format@emptyline%
+ \else%
+ \expandafter\pgf@dv@format@line\pgf@temp\pgfeol%
+ \fi%
+ \fi%
+ \ifeof\r@pgf@reada\else\expandafter\pgf@dataset@readline\fi%
+}
+
+
+%
+% Read inline data
+%
+
+\def\pgf@dataset@do@inline{%
+ \pgf@dv@handle@line%
+}
+
+{\catcode`\^^M=\active%
+\gdef\pgf@dv@handle@line{%
+ \pgfutil@ifnextchar^^M{\pgf@dv@format@emptyline\expandafter\pgf@dv@handle@line\pgfutil@gobble}%
+ {\pgfutil@ifnextchar\pgf@@eol{\pgfutil@gobble}{\pgf@dv@handle@nonemptyline}}%
+}%
+\gdef\pgf@dv@handle@nonemptyline#1^^M{%
+ \pgf@dv@format@line#1\pgfeol%
+ \pgf@dv@handle@line%
+}%
+}
+
+\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=
+}
+
+
+
+
+
+
+% Define a data format
+%
+% #1 = format name
+% #2 = catcode code
+% #3 = startup code
+% #4 = line arguments
+% #5 = line code
+% #6 = empty line code
+% #7 = end code
+%
+% Description:
+%
+% This command defines a new data format for data visualization. When
+% 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
+% 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
+% command #5 is executed, where the line will be matched against the
+% argument pattern given in #4. For empty lines, #6 will be executed
+% instead. At the end of the source, #7 will be executed.
+
+\def\pgfdeclaredataformat#1#2#3#4#5#6#7{%
+ \expandafter\def\csname pgfdv@format@#1@catcodes\endcsname{#2}%
+ \expandafter\def\csname pgfdv@format@#1@startup\endcsname{#3}%
+ \expandafter\def\csname pgfdv@format@#1@line\endcsname#4\pgfeol{#5}%
+ \expandafter\def\csname pgfdv@format@#1@empty\endcsname{#6}%
+ \expandafter\def\csname pgfdv@format@#1@end\endcsname{#7}%
+}
+
+
+
+%
+% Predefined standard formats
+%
+
+% TeX code format
+%
+% Description:
+%
+% The lines of the data set are assumed to contain executable TeX
+% code that will call \pgfdatapoint.
+%
+% Example:
+%
+% \pgfdatavisualizationrender[format=TeX code]
+% \dataset{
+% \pgfkeyssetvalue{/data point/x}{5}
+% \pgfkeyssetvalue{/data point/y}{5}
+% \pgfdatapoint
+% \pgfkeyssetvalue{/data point/x}{6}
+% \pgfkeyssetvalue{/data point/y}{6}
+% \pgfdatapoint
+% }
+
+\pgfdeclaredataformat{TeX code}{}{}{#1}{#1 }{}{}
+
+
+
+% Key-value lines format
+%
+% Description:
+%
+% The lines of the data set are passed to \pgfkeys with the path set
+% to /data point.
+%
+% Example:
+%
+% \data[format=key value pairs] {
+% x=5, y=6, hi=9
+% x=7, y=6, lo=10
+% }
+
+\pgfdeclaredataformat{key value pairs}{}{}{#1}{{\pgfkeys{/data point/.cd,#1}\pgfdatapoint}}{}{}
+
+
+
+
+
+% Table format
+%
+% Description:
+%
+% A table consists of a head line, which contains the attribute names
+% of the values that will be found in the following lines. Each line
+% (except for the headline) contains one data point.
+%
+% Inside each line the data points are separated by a separator like a
+% comma or a space or a colon. The separator can be configured using
+% the key /pgf/data/separator (leave the separator empty or set it to
+% \space for a space as separator). The default separator is a comma.
+%
+% Some tables will miss the headline. In this case, using the
+% /pgf/data/headline key you can provide a headline yourself.
+%
+% Example:
+%
+% \data[format=table] {
+% x y
+% 10 5
+% 11 6
+% 6 7
+% }
+%
+% \data[format=table,separator={,}] {
+% x, y
+% 10, 5
+% 11, 6
+% 6, 7
+% }
+%
+% \data[format=table,headline=x y] {
+% 10 5
+% 11 6
+% 6 7
+% }
+
+\pgfdeclaredataformat{table}
+{} % no catcodes
+{
+ \pgfkeysgetvalue{/pgf/data/headline}\pgf@dv@headline
+ \pgfkeysgetvalue{/pgf/data/separator}\pgf@dv@separator
+ \ifx\pgf@dv@separator\pgfutil@empty
+ \let\pgf@dv@separator\space
+ \fi
+ \ifx\pgf@dv@separator\pgf@dv@spacetext
+ \let\pgf@dv@separator\space
+ \fi
+ \expandafter\def\expandafter\pgf@dv@till@separator%
+ \expandafter##\expandafter1\pgf@dv@separator{\pgf@dv@table@handle{##1}}
+ \expandafter\def\expandafter\pgf@dv@till@separator@head%
+ \expandafter##\expandafter1\pgf@dv@separator{\pgf@dv@head@handle{##1}}
+ \ifx\pgf@dv@headline\pgfutil@empty
+ % Ok, read headline from file
+ \pgfdv@firstlinetrue
+ \else
+ % Headline already set
+ \pgfdv@firstlinefalse
+ \expandafter\pgf@dv@parse@headline\expandafter{\pgf@dv@headline}
+ \fi
+}
+{#1} % special line pattern, so read everything
+{
+ \ifpgfdv@firstline
+ \pgfdv@firstlinefalse
+ \pgf@dv@parse@headline{#1}
+ \else
+ {
+ \c@pgf@counta=0\relax% keep track of attribute number
+ \def\pgf@marshal{\pgf@dv@parse@table#1}
+ \expandafter\expandafter\expandafter\pgf@marshal%
+ \expandafter\pgf@dv@separator\expandafter\pgfeol\pgf@dv@separator
+ \pgfdatapoint
+ }
+ \fi
+}
+{} % ignore empty lines
+{} % no special end code
+
+\newif\ifpgfdv@firstline
+
+\pgfkeys{
+ /pgf/data/separator/.initial={,},
+ /pgf/data/headline/.initial=
+}
+\def\pgf@dv@spacetext{\space}
+
+\def\pgf@dv@parse@table{%
+ \pgfutil@ifnextchar"% Special, but ignored right now...
+ {\PackageError{pgf}{csv with quotes not yet implemented}{}}
+ {\pgf@dv@till@separator}
+}
+\def\pgf@dv@table@handle#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfeoltext%
+ % Bingo! Stop
+ \let\pgf@next=\relax%
+ \else%
+ \advance\c@pgf@counta by1\relax%
+ \pgfkeysgetvalue{/pgf/data/table/attribute \the\c@pgf@counta}\pgf@dv@target
+ \ifx\pgf@dv@target\relax%
+ \edef\pgf@dv@target{attribute \the\c@pgf@counta}
+ \pgfkeyslet{/pgf/data/table/attribute \the\c@pgf@counta}\pgf@dv@target
+ \fi
+ \pgfkeyssetvalue{/data point/\pgf@dv@target}{#1}
+ \let\pgf@next=\pgf@dv@parse@table%
+ \fi%
+ \pgf@next%
+}
+
+
+
+\def\pgf@dv@parse@headline#1{
+ \c@pgf@counta=0\relax% keep track of attribute number
+ \def\pgf@marshal{\pgf@dv@doparse@headline#1}
+ \expandafter\expandafter\expandafter\pgf@marshal%
+ \expandafter\pgf@dv@separator\expandafter\pgfeol\pgf@dv@separator
+}
+
+\def\pgf@dv@doparse@headline{%
+ \pgfutil@ifnextchar"% Special, but ignored right now...
+ {\PackageError{pgf}{csv with quotes not yet implemented}{}}
+ {\pgf@dv@till@separator@head}
+}
+\def\pgf@dv@head@handle#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfeoltext%
+ % Bingo! Stop
+ \let\pgf@next=\relax%
+ \else%
+ \advance\c@pgf@counta by1\relax%
+ \pgfkeyssetvalue{/pgf/data/table/attribute \the\c@pgf@counta}{#1}
+ \let\pgf@next=\pgf@dv@doparse@headline%
+ \fi%
+ \pgf@next%
+}
+
+\def\pgfeoltext{\pgfeol}
+
+
+%
+%
+% Micro math kernel for dv
+%
+%
+
+% The idea behind the following methods is to "abstract away" which
+% math engine is used. In the future, something fancy build on luatex
+% might be used, so it would we should not rely directly on the
+% fpu library code.
+%
+% The system works as follows: First, you "enter" a number into the
+% engine. When you do so, it is converted into some internal
+% representation that cannot be accessed any more and is called a
+% "math variable" henceforth. All commands of the
+% math system only work on math variables.
+%
+% In order to "exit" a value stored in a math variable from the
+% engine, some other macros can be used.
+%
+% Operations like addition or multiplication take two math variables
+% and store the result in another math variable.
+
+
+
+% Store a value in a math variable of the math engine
+%
+% #1 = a math variable (a macro name) that is to store the value
+% #2 = an expression describing a number
+%
+%
+% Description:
+%
+% The #2 should be an expression that evaluates to a number. However,
+% due to the way the pgf math engine(s) work, currently, there are
+% several restrictions/the syntax is not as simple as one might
+% hope. Fortunately, the syntax is hopefully compatible with
+% easier-to-use future systems.
+%
+% The syntax is as follows: #2 may be
+%
+% 1. a simple high-precision number. This number is currently directly
+% passed to \pgfmathfloatparsenumber, so typical permissible values
+% are "100" or "10000000000000" or "nan" or "-5.673543345345e9000"
+%
+% 2. a mathematical expression, which *must* be surrounded by
+% parantheses. From a "mathematical" point of view these
+% parantheses are superfluous, but the they are used to help pgf
+% distinguish expressions from high-precision numbers. (If, in the
+% future, expressions may contain high precision numbers, the
+% parantheses will simply be ignored.)
+%
+% The expression is evaluated using \pgfmathparse, which means that
+% TeX-precision is used. This means, for instance, that numbers
+% larger than about 16500 will create error messages.
+%
+% The advantage is that you may say write things like "(5+6)" or
+% "(pi/2)".
+%
+% 3. In case #2 starts with an exclamation mark (indicating an
+% "escape"), everything following the mark is simply evaluated by
+% TeX. The effect of evaluating #2 should be that the math
+% variable "\pgfdvmathvalue" is set to some value. This value will
+% then be transferred to #1.
+%
+% 4. In case #2 is the result of calling \pgfdvmathexitbyserializing, the
+% "serialized" value is restored. The idea is that the serialized
+% will turn its internal representation of a number into something
+% that can be stored as a text somewhere.
+%
+% Currently, "@" at the beginning of #2 is used to indicate that
+% what follows is a serialized version of a math variable.
+%
+% In order to determine which of the above cases is to be used for a
+% variable, the first symbol #2 is checked, *after* the first symbol
+% of #2 has been expanded once (using \expandafter once).
+%
+% Example:
+%
+% \pgfdvmathenter{\mymacro}{20000000000000}
+% \pgfdvmathenter{\mymacro}{(5+pi)}
+% \pgfdvmathenter{\mymacro}{!\pgfdvmathadd{\pgfdvmathvalue}{\a}{\b}}
+%
+% \pgfdvmathenter{\foo}{5}
+% \pgfdvmathexitbyserializing{\somevalue}{\foo}
+% \pgfdvmathenter{\mymacro}{\somevalue}
+
+\def\pgfdvmathenter#1#2{%
+ \expandafter\pgfdvmathenter@check\expandafter#1#2\pgfdvmath@end%
+}
+\def\pgfdvmathenter@check#1{%
+ \pgfutil@ifnextchar @{\pgfdvmath@internal#1}{%
+ \pgfutil@ifnextchar ({\pgfdvmath@expression#1}{%)
+ \pgfutil@ifnextchar !{\pgfdvmath@execute#1}{\pgfdvmath@normal#1}}}%
+}
+
+\def\pgfdvmath@internal#1@#2\pgfdvmath@end{%
+ \def#1{#2}%
+}
+\def\pgfdvmath@expression#1(#2)#3\pgfdvmath@end{%
+ \pgfmathparse{#2}%
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+ \let#1=\pgfmathresult%
+}
+\def\pgfdvmath@execute#1!#2\pgfdvmath@end{%
+ #2%
+ \let#1=\pgfdvmathvalue%
+}
+\def\pgfdvmath@normal#1#2\pgfdvmath@end{%
+ \pgfmathfloatparsenumber{#2}%
+ \let#1=\pgfmathresult%
+}
+
+
+
+% Print a math variable in the math engine using \pgfmathprintnumber
+%
+% #1 = math variable
+%
+% Description:
+%
+% See the description of \pgfmathprintnumber
+%
+% Example:
+%
+% \pgfdvmathenter{\mymacro}{20000000000000}
+% \pgfdvmathexitbyprinting{\mymacro}
+
+\def\pgfdvmathexitbyprinting#1{%
+ \pgfmathprintnumber{#1}%
+}
+
+
+
+% Exit a math variable as a number in a scientific and portable number
+% format in a macro
+%
+% #1 = macro in which to store the value
+% #2 = math variable
+%
+% Description:
+%
+% You can exit a number using this operation. You can then directly
+% reenter the number using \pgfdvmathenter
+%
+% Example:
+%
+% \pgfdvmathenter{\mynumber}{20000000000000}
+% \pgfdvmathexitbyscientificformat{\mymacro}{\mynumber}
+
+\def\pgfdvmathexitbyscientificformat#1#2{%
+ \edef#1{\pgfmathfloatvalueof#2}%
+}
+
+
+
+% Exit a math variable as a "serialized" (= string-based)
+% version.
+%
+% #1 = macro in which to store the value
+% #2 = math variable
+%
+% Description:
+%
+% The serialized version can be reentered using
+% \pgfmathenter and is similar to \pgfdvmathexitbyscientificformat,
+% but exiting and entering are (a bit) faster.
+%
+% Example:
+%
+% \pgfdvmathenter{\mynumber}{20000000000000}
+% \pgfdvmathexitbyserializing{\mymacro}{\mynumber}
+
+\def\pgfdvmathexitbyserializing#1#2{%
+ \edef#1{@#2}%
+}
+
+
+
+
+
+% Operations on two numbers
+%
+% #1 = macro that should store the result of applying the
+% corresponding operation to the following:
+% #2 = entered number
+% #3 = entered number
+%
+% Description:
+%
+% Sets #1 to the result of applying an operation to #2 and #3
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{2000}
+% \pgfdvmathenter{\b}{5+6}
+% \pgfdvmathadd{\c}{\a}{\b}
+
+\def\pgfdvmathadd#1#2#3{%
+ \pgfmathfloatadd{#2}{#3}%
+ \let#1=\pgfmathresult%
+}
+\def\pgfdvmathsub#1#2#3{%
+ \pgfmathfloatsubtract{#2}{#3}%
+ \let#1=\pgfmathresult%
+}
+\def\pgfdvmathmul#1#2#3{%
+ \pgfmathfloatmultiply{#2}{#3}%
+ \let#1=\pgfmathresult%
+}
+\def\pgfdvmathdiv#1#2#3{%
+ \pgfmathfloatdivide{#2}{#3}%
+ \let#1=\pgfmathresult%
+}
+
+
+
+
+% Log, ln and exponent functions
+%
+% #1 = a math variable
+% #2 = a math variable
+%
+% Description
+%
+% \pgfdvmathln will compute #1 = ln(#2)
+% \pgfdvmathlog will compute #1 = log_{10}(#2)
+% \pgfdvmathexp will compute #1 = exp(#2)
+% \pgfdvmathpowten will compute #1 = 10^{#2}
+
+\def\pgfdvmathln#1#2{%
+ \pgfmathfloatln{#2}%
+ \let#1=\pgfmathresult%
+}
+
+\def\pgfdvmathlog#1#2{%
+ \pgfmathfloatln{#2}%
+ \pgfmathfloatmultiply{\pgfmathresult}{\pgfdvmathalwaysloge}%
+ \let#1=\pgfmathresult%
+}
+
+\def\pgfdvmathexp#1#2{%
+ \pgfmathfloatexp{#2}%
+ \let#1=\pgfmathresult%
+}
+
+\def\pgfdvmathpowten#1#2{%
+ \pgfmathfloattofixed{#2}%
+ \let\pgf@dv@temp=\pgfmathresult%
+ \pgfmathround{\pgf@dv@temp}%
+ \let\pgf@dv@temp@round=\pgfmathresult%
+ \pgf@x=\pgf@dv@temp@round pt%
+ \pgf@x=-\pgf@x%
+ \advance\pgf@x by\pgf@dv@temp pt\relax%
+ \ifdim\pgf@x>0.0002pt%
+ \pgfmathfloatmultiply{#2}{\pgfdvmathalwayslnten}%
+ \pgfmathfloatexp{\pgfmathresult}%
+ \else
+ \ifdim\pgf@x<-0.0002pt%
+ \pgfmathfloatmultiply{#2}{\pgfdvmathalwayslnten}%
+ \pgfmathfloatexp{\pgfmathresult}%
+ \else
+ \pgf@x=\pgf@dv@temp@round sp%
+ \c@pgf@counta=\pgf@x%
+ \pgfmathfloatcreate{1}{1.0}{\the\c@pgf@counta}%
+ \fi
+ \fi
+ \let#1=\pgfmathresult%
+}
+
+
+% Floor functions
+%
+% #1 = a math variable
+% #2 = a math variable
+%
+% Description
+%
+% Sets #1 to the largest integer less or equal to #2
+
+\def\pgfdvmathfloor#1#2{%
+ \pgfmathifisint{#2}{%
+ \let#1=#2%
+ }{%
+ \pgfmathfloatgetflags#2\c@pgf@counta%
+ \ifcase\c@pgf@counta
+ \let#1=\pgfdvmathalwayszero%
+ \or
+ \pgfmathfloatfloor{#2}%
+ \let#1=\pgfmathresult%
+ \or
+ \pgfmathfloatsubtract{\pgfdvmathalwaysone}{#2}%
+ \pgfmathfloatfloor{\pgfmathresult}%
+ \pgfmathfloatsubtract{\pgfdvmathalwayszero}{\pgfmathresult}%
+ \let#1=\pgfmathresult%
+ \or\let#1=#2%
+ \or\let#1=#2%
+ \or\let#1=#2%
+ \fi%
+ }%
+}
+
+
+% Advanced unary operations
+%
+% #1 = macro that should store the result of applying the
+% operation to an entered number
+% #2 = the operation (as a string like "ln")
+% #3 = entered number
+%
+% Description:
+%
+% Sets #1 to the result of applying #2 to #3
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{2000}
+% \pgfdvmathunaryop{\b}{ln}{\a}
+
+\def\pgfdvmathunaryop#1#2#3{%
+ \csname pgfmathfloat#2\endcsname{#3}%
+ \let#1=\pgfmathresult%
+}
+
+
+% Advanced binary operations
+%
+% #1 = macro that should store the result of applying the
+% operation to two entered number
+% #2 = the operation (as a string like "veclen")
+% #3 = first argument (an entered number)
+% #4 = second argument (an entered number)
+%
+% Description:
+%
+% Sets #1 to the result of applying #2 to #3
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{3}
+% \pgfdvmathenter{\b}{4}
+% \pgfdvmathbinop{\c}{veclen}{\a}{\b}
+
+\def\pgfdvmathbinop#1#2#3#4{%
+ \csname pgfmathfloat#2\endcsname{#3}{#4}%
+ \let#1=\pgfmathresult%
+}
+
+
+
+% Comparing values
+%
+% #1 = first math variable
+% #2 = second math variable
+% #3 = code to-be-executed if #1 < #2
+% #4 = code to-be-executed if #1 >= #2
+%
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{3}
+% \pgfdvmathenter{\b}{4}
+% \pgfdvmathifless{\a}{\b}{yes}{should not happen}
+
+\def\pgfdvmathifless#1#2#3#4{%
+ \pgfmathfloatlessthan{#1}{#2}%
+ \ifpgfmathfloatcomparison#3\else#4\fi%
+}
+
+
+
+
+%
+%
+% Standard objects for data visualization
+%
+%
+
+
+%
+% Transformers
+%
+
+\pgfooclass{linear transformer}
+{
+ % Class linear transformer
+ %
+ % This class is a transformer class. It reacts to the transform
+ % datapoint signal. When this signal is raised, it will shift the
+ % coordinate system as follows: If the current value of /data
+ % point/this.attribute is 0, then the system is shifted to the
+ % current value of this.origin. If the current value is 1, the
+ % system is shifted to this.origin + this.unit vector. For other
+ % values of /data point/this.attribuate, the shift is interpolated
+ % between these two values.
+
+
+ \attribute attribute;
+ % The attribute (/data point/this.attribute) by which
+ % the unit vector is multiplied. If it is empty (which is
+ % different from 0), no transformation is done at all.
+
+ \attribute origin = \pgfpointorigin;
+ % The shift in case the /data point/this.attribute is 0.
+
+ \attribute unit vector;
+ % The coordinate system is additionally shifted by this amount
+ % times the current value of /data point/this.attribute.
+
+
+ % Constructor
+ %
+ % #1 = attribute that is being transformed. Example: x
+ % #2 = a vector corresponding to one unit of #1.
+ % Example: \pgfpoint{1cm}{0cm}
+ \method linear transformer(#1,#2) {
+ \pgfooset{attribute}{#1}
+ \pgf@process{#2}
+ \edef\pgf@temp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \pgfoolet{unit vector}\pgf@temp%
+ }
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,transform,transform datapoint signal)
+ }
+
+ % Setter
+ \method set origin(#1) {
+ \pgf@process{#1}
+ \edef\pgf@temp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \pgfoolet{origin}\pgf@temp%
+ }
+
+ % Slot
+ %
+ % This slot should be connected to the transform datapoint
+ % signal. When this signal is emitted, the coordinate system will be
+ % shifted according to the current value of the attribute.
+ \method transform() {
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}\pgf@dv@val%
+ \ifx\pgf@dv@val\pgfutil@empty%
+ \else%
+ \ifx\pgf@dv@val\relax%
+ \else%
+ \pgfdvmathenter{\pgf@dv@math@var}{\pgf@dv@val}%
+ \pgfdvmathexitbyscientificformat{\pgf@dv@val}{\pgf@dv@math@var}%
+ \pgftransformshift{\pgfoovalueof{origin}}%
+ \pgfmathfloatgetexponent\pgf@dv@math@var\c@pgf@counta%
+ \ifnum\c@pgf@counta<-3\relax%
+ \else%
+ \pgftransformshift{\pgfpointscale{\pgf@dv@val}{\pgfoovalueof{unit vector}}}%
+ \fi%
+ \fi%
+ \fi%
+ }
+
+}
+
+
+%
+% Numerical mapping of attributes to other attributes
+%
+
+\pgfooclass{interval mapper}
+{
+ % Class interval mapper
+ %
+ % This interval mapper reacts to the map datapoint signal. Its purpose is to
+ % map one attribute to another attribute. For the first attribute,
+ % an intervals is specified.
+ %
+ % In addition to the in interval [a,b] there is also an outinterval
+ % [c,d]. Values in the range [a,b] are linearly mapped to the
+ % range [c,d] and the result is stored in the second attribute.
+ %
+ % For instance, if the first range is [10,20] and the second range
+ % is [0,100], then 10 is mapped to 0, 11 is mapped to 10, 20 is
+ % mapped to 100 and 30 is mapped to 200.
+ %
+ % It is permissible to specify an additional non-linear
+ % transformation function f. In this case, for an input value x the
+ % position of f(x) inside the interval [f(a),f(b)] is determined and
+ % this position is linearly mapped to [c,d].
+ %
+ % For example, if f(x) = log_10 (x) and the first range [a,b] =
+ % [10,1000] and the second range is [1,2], then 10 is mapped to 1,
+ % 100 is mapped to 1.5 (since f(100) = 3 lies in the middle
+ % between f(10) = 2 and f(1000) = 4) and 100000 is mapped to 3.
+
+
+ \attribute in;
+ % The name of the input attribute. If the value of this attribute
+ % is empty or undefined, no mapping is done.
+ %
+ % The in attribute may have a subkey called .../const. If this key
+ % has a value different from \relax, it will always be used instead
+ % of the in attribute itself. This can be useful to temporarily
+ % set a constant value to a key inside a mapping chain.
+
+% \attribute clip;
+% % The code for clipping the interval. Will set \pgf@dvcliptrue, if a
+% % clip is necessary.
+
+ \attribute out;
+ % The name of the output attribute.
+
+ \attribute trans;
+ % Stores (more or less) the transformation function.
+
+ \attribute out min;
+ % Start of the second range (the value of c).
+
+ \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).
+
+
+ % Constructor
+ %
+ % #1 = input attribute. Example: velocity.
+ % #2 = output attribute. Example: x
+ % #3 = optional transformation function. The input value for this
+ % function is stored in entered number \pgfvalue.
+ % The output of the function should be stored in the
+ % same entered number.
+ %
+ % The intervals are set using setter methods later on.
+ %
+ \method interval mapper(#1,#2,#3) {
+ \pgfooset{in}{#1}
+ \pgfooset{out}{#2}
+ \def\pgf@temp{#3}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \pgfooset{trans}{%
+ #3%
+ }%
+ \fi%
+ }
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,map,map datapoint signal)
+ }
+
+% % Method
+% \method set clip interval(#1,#2) {
+% \def\pgfdvmin{#1}%
+% \def\pgfdvmax{#2}%
+% \ifx\pgfdvmin\pgfutil@empty%
+% \else%
+% \pgfdvmathenter{\pgf@dv@temp}{\pgfdvmin}%
+% \pgfdvmathexitbyserializing{\pgfdvmin}{\pgf@dv@temp}%
+% \fi
+% \ifx\pgfdvmax\pgfutil@empty%
+% \else%
+% \pgfdvmathenter{\pgf@dv@temp}{\pgfdvmax}%
+% \pgfdvmathexitbyserializing{\pgfdvmax}{\pgf@dv@temp}%
+% \fi
+% \pgfooeset{clip}{%
+% \noexpand\pgf@dvclipfalse%
+% \ifx\pgfdvmin\pgfutil@empty%
+% \else%
+% \noexpand\pgfdvmathenter{\noexpand\pgf@dv@temp}{\pgfdvmin}%
+% \noexpand\pgfdvmathifless{\noexpand\pgfvalue}{\noexpand\pgf@dv@temp}{\noexpand\pgf@dvcliptrue}{}%
+% \fi%
+% \ifx\pgfdvmax\pgfutil@empty%
+% \else%
+% \noexpand\pgfdvmathenter{\noexpand\pgf@dv@temp}{\pgfdvmax}%
+% \noexpand\pgfdvmathifless{\noexpand\pgf@dv@temp}{\noexpand\pgfvalue}{\noexpand\pgf@dvcliptrue}{}%
+% \fi%
+% }
+% }
+
+ % Method
+ %
+ % #1 = in interval minimum
+ % #2 = in interval maximum
+ % #3 = out interval minimum
+ % #4 = out interval maximum
+ %
+ % This method will (re)compute the correct mappings for the interval
+ % mapper.
+ \method set interval values(#1,#2,#3,#4) {
+ {%
+ \pgfdvmathenter{\pgf@in@interval@min}{#1}
+ \pgfdvmathenter{\pgf@in@interval@max}{#2}
+ \pgfdvmathenter{\pgf@out@interval@min}{#3}
+ \pgfdvmathenter{\pgf@out@interval@max}{#4}
+ % Let's start with the output, it's easier...
+ \pgfoolet{out min}{\pgf@out@interval@min}
+ \pgfdvmathsub{\pgf@out@diff}{\pgf@out@interval@max}{\pgf@out@interval@min}
+ \let\pgfvalue=\pgf@in@interval@min
+ \pgfoovalueof{trans}
+ \let\pgf@in@interval@min@transformed=\pgfvalue
+ \pgfoolet{trans in min}{\pgf@in@interval@min@transformed}%
+ \let\pgfvalue=\pgf@in@interval@max
+ \pgfoovalueof{trans}
+ \let\pgf@in@interval@max@transformed=\pgfvalue
+ \pgfdvmathsub{\pgf@diff@in@transformed}{\pgf@in@interval@max@transformed}{\pgf@in@interval@min@transformed}
+ %
+ % Precompute the scaling
+ %
+ \pgfdvmathdiv{\pgf@scale}{\pgf@out@diff}{\pgf@diff@in@transformed}%
+ \pgfoolet{scale}{\pgf@scale}%
+ }%
+ }
+
+ % Slot
+ \method map() {
+ \pgfooget{scale}\pgf@temp
+ \ifx\pgf@temp\pgfutil@empty%
+ % not yet setup
+ \else%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/const}\pgf@dv@external@value%
+ \ifx\pgf@dv@external@value\relax%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}}\pgf@dv@external@value%
+ \fi%
+ \ifx\pgf@dv@external@value\pgfutil@empty%
+ \else%
+ \ifx\pgf@dv@external@value\relax%
+ \else%
+% % Clip?
+ \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}%
+% \pgfoovalueof{clip}%
+% \ifpgf@dvclip%
+% \pgfkeyslet{/data point/\pgfoovalueof{out}}\pgfutil@empty%
+% \else%
+ \pgf@dv@mapper@trans{}
+% \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
+ \fi%
+ }
+
+ \def\pgf@dv@mapper@trans#1{
+ \pgfooget{trans in min}{\pgf@dv@trans@in@min}%
+ \pgfooget{scale}{\pgf@dv@scale}%
+ \pgfooget{out min}{\pgf@dv@out@min}%
+ \pgfoovalueof{trans}%
+ \pgfdvmathsub{\pgfvalue}{\pgfvalue}{\pgf@dv@trans@in@min}%
+ \pgfdvmathmul{\pgfvalue}{\pgfvalue}{\pgf@dv@scale}%
+ \pgfdvmathadd{\pgfvalue}{\pgfvalue}{\pgf@dv@out@min}%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{out}#1/offset}\pgf@dv@external@offset%
+ \ifx\pgf@dv@external@offset\relax\else%
+ \ifx\pgf@dv@external@offset\pgfutil@empty\else%
+ \pgfdvmathenter{\pgf@dv@offset}{\pgf@dv@external@offset}%
+ \pgfdvmathadd{\pgfvalue}{\pgfvalue}{\pgf@dv@offset}
+ \fi
+ \fi
+ \pgfdvmathexitbyserializing{\pgf@temp}{\pgfvalue}%
+ \pgfkeyslet{/data point/\pgfoovalueof{out}#1}\pgf@temp%
+ }
+}
+
+
+
+
+
+%\newif\ifpgf@dvclip
+\newif\ifpgf@dvignore
+
+\pgfooclass{scaling mapper}
+{
+ % Class scaling mapper
+ %
+ % A scaling mapper is (mainly) used to scale an attribute in such a way
+ % that it can be rendered easily on a page. The idea is that you
+ % specify some attribute and a desired target interval size (like
+ % [0,5]). The scaling mapper will then survey the data and will setup a
+ % interval mapper in such a way that the minimum value present in the data is
+ % mapped to 0 and the maximum to 5. However, it is also possible to,
+ % say, only have the maximum value mapped to 5 and have 0 be mapped
+ % to 0. Other, more complicated specifications are also possible.
+ %
+ % The scaling mapper internally creates several objects: First, a surveyor
+ % for determining the minimum and maximum values of the attribute
+ % and a interval mapper for then mapping the values to the scaled
+ % values. Additionally, interval objects are needed.
+
+ \attribute in;
+ % The to-be-scaled attribute;
+
+ \attribute out;
+ % The attribute storing the scaled value.
+
+ \attribute in range obj;
+ % This interval keep track of the range of the in attribute
+
+ \attribute scaling spec;
+ % A specification of how the scaling should be performed.
+ %
+ % The format is the following:
+ %
+ % #1 at #2 and #3 at #4
+ %
+ % Here, #2 and #4 must be numbers. #1 and #3 can either be numbers
+ % or #1 can be the text "min" and #3 can be the text "max".
+ %
+ % The effect of such a specification is the following: The value #1
+ % is mapped to #2, the value #3 is mapped to #4 and values between
+ % #1 and #3 (or outside this range) are mapped linearly to a value
+ % between (or outside) #2 and #4. In case #1 is set to "min", the
+ % smallest observed value of the in-attribute is mapped to #3 and
+ % similarly for a value of "max" for #3.
+ %
+ % Additionally, as for a interval mapper, a function f might be specified
+ % that deforms the linear mapping. In case f is specified,
+ % f(#1) is mapped to #2 and f(#3) is mapped to #4.
+
+ \attribute function;
+ % Stores the function
+
+ \attribute interval mapper;
+ % Stores the interval mapper object
+
+ \attribute range surveyor;
+ % Stores the range surveyor object
+
+
+ % Constructor
+ %
+ % #1 = in attribute
+ % #2 = out attribute
+ % #3 = scaling specification
+ % #4 = optional function
+ %
+ \method scaling mapper(#1,#2,#3,#4) {
+ %
+ % Save the parameters in attributes
+ %
+ \pgfooset{in}{#1}
+ \pgfooset{out}{#2}
+ \pgfooset{scaling spec}{#3}
+ \pgfooset{function}{#4}
+ %
+ % Now setup the objects for the before survey phase
+ %
+ %
+ % First, the in range interval
+ \pgfoonew \pgf@dv@in@range@obj=new interval(,)
+ \pgfoolet{in range obj}\pgf@dv@in@range@obj
+ % Second, the in range surveyor. We do not need to store this
+ % object, it will "do its work in the background"
+ \pgfoonew \pgf@dv@range@obj=new range surveyor(#1,\pgf@dv@in@range@obj)
+ \pgf@dv@range@obj.default connects()
+ \pgfoolet{range surveyor}\pgf@dv@range@obj
+ %
+ %
+ % The interval mapper:
+ %
+ \pgfoonew{interval mapper}=new interval mapper(#1,#2,#4)
+ \pgfoovalueof{interval mapper}.default connects()
+ }
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }
+
+
+% % Method
+% %
+% % #1 = a min clip -- everything below this value will be clipped
+% % #2 = a max value -- everything above this value will be clipped
+% %
+% % Sets a clipping for the underlying interval mapper.
+% %
+% \method set clip interval(#1,#2) {
+% \pgfoovalueof{interval mapper}.set clip interval({#1},{#2})%
+% }
+
+ % Getter
+ %
+ % Returns an interval object that stores the range of the in
+ % attribute.
+ \method get in range interval() {
+ \pgfooget{in range obj}\pgfdvinrangeinterval
+ }
+
+
+ % Getter
+ %
+ % Returns the out attribute.
+ %
+ \method get out() {
+ \pgfooget{out}\pgfdvout
+ }
+
+ % Getter
+ %
+ % Returns the function attribute.
+ %
+ \method get function(#1) {
+ \pgfooget{function}#1
+ }
+
+ % Method
+ %
+ % #1 = a included in value
+ %
+ % This method only affects the survey. The value #1 is recorded as
+ % if it were encountered for the in attribute at some point.
+ %
+ \method include in value(#1) {
+ \pgfoovalueof{range surveyor}.include attribute value({#1})
+ }
+
+
+ % Method
+ %
+ % #1 = value for the attribute
+ %
+ % Sets the attribute to the (evaluated) given value (evaluation
+ % using \pgfmathparse). When the value is evaluated, the values of
+ % \pgfdvmin and \pgfdvmax will be set to the minimum and maximum
+ % values of the in interval. (See \pgfdvmathenter with the "!"-notation).
+ %
+ % In case #1 is set to the special value "min", it evaluates to
+ % \pgfdvmin, when set to "max" it evaluates to \pgfdvmax.
+ %
+ \method set in to(#1) {
+ \edef\pgf@temp{#1}
+ \ifx\pgf@temp\pgf@min@text
+ \pgf@dv@lib@set@mm%
+ \let\pgf@dv@value\pgfdvmin
+ \else
+ \ifx\pgf@temp\pgf@max@text
+ \pgf@dv@lib@set@mm%
+ \let\pgf@dv@value\pgfdvmax
+ \else
+ \pgfdvmathenter{\pgf@dv@value}{\pgf@temp}
+ \fi
+ \fi
+ \pgfdvmathexitbyserializing{\pgf@dv@serial}{\pgf@dv@value}
+ \pgfkeyslet{/data point/\pgfoovalueof{in}}\pgf@dv@serial
+ }
+ \def\pgf@dv@lib@set@mm{
+ \pgfooget{in range obj}\pgfdvinrangeinterval
+ \pgfdvinrangeinterval.get min and max()%
+ }
+
+
+ % Slot
+ \method phase(#1) {
+ \ifx#1\pgfdvendsurvey
+ % Ok, we setup the interval mapper.
+ %
+ % We start by computing the interval borders:
+ \pgfoovalueof{in range obj}.get min and max()
+ \ifx\pgfdvmin\pgfutil@empty% undefined, since no data points
+ \else%
+ \pgfooget{scaling spec}\pgf@temp
+ \expandafter\pgf@lib@dv@parse@scaling\pgf@temp\pgf@stop%
+ \pgfoovalueof{interval mapper}.set interval values(%
+ \pgf@lib@dv@min,\pgf@lib@dv@max,%
+ \pgf@lib@dv@min@at,\pgf@lib@dv@max@at)
+ \fi
+ \fi
+ }
+
+
+ % Internal helper
+ \def\pgf@lib@dv@parse@scaling#1 at#2and #3 at#4\pgf@stop{%
+ \def\pgf@lib@dv@min{#1}%
+ \pgfdvmathenter{\pgf@lib@dv@min@at@mv}{#2}
+ \def\pgf@lib@dv@max{#3}%
+ \pgfdvmathenter{\pgf@lib@dv@max@at@mv}{#4}
+ \ifx\pgf@lib@dv@min\pgf@min@text%
+ \let\pgf@lib@dv@min@mv\pgfdvmin
+ \else
+ \pgfdvmathenter{\pgf@lib@dv@min@mv}{\pgf@lib@dv@min}
+ \fi
+ \ifx\pgf@lib@dv@max\pgf@max@text%
+ \let\pgf@lib@dv@max@mv\pgfdvmax
+ \else
+ \pgfdvmathenter{\pgf@lib@dv@max@mv}{\pgf@lib@dv@max}
+ \fi
+ \pgfdvmathexitbyserializing{\pgf@lib@dv@min}{\pgf@lib@dv@min@mv}
+ \pgfdvmathexitbyserializing{\pgf@lib@dv@min@at}{\pgf@lib@dv@min@at@mv}
+ \pgfdvmathexitbyserializing{\pgf@lib@dv@max}{\pgf@lib@dv@max@mv}
+ \pgfdvmathexitbyserializing{\pgf@lib@dv@max@at}{\pgf@lib@dv@max@at@mv}
+ }
+ \def\pgf@min@text{min}
+ \def\pgf@max@text{max}
+}
+
+
+
+
+
+%
+% Surveyors
+%
+
+\pgfooclass{range surveyor}
+{
+ % Class range surveyor
+ %
+ % A range surveyor is used only in the survey phase. Its job is to
+ % determine the minimum and maximum values of an attribute that are
+ % "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.
+
+ \attribute attribute;
+ % The to-be-surveyed attribute
+
+ \attribute interval obj;
+ % The interval object that protocols the minimum and maximum
+ % values.
+
+
+ % Constructor
+ %
+ % #1 = the attribute
+ % #2 = handle to the interval object
+ %
+ \method range surveyor(#1,#2) {
+ \pgfooset{attribute}{#1}
+ \pgfoolet{interval obj}#2
+ }
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,survey,survey datapoint signal)
+ }
+
+ % Method
+ %
+ % #1 = a value
+ %
+ % Adjust the interval as if during the survey this value were
+ % encountered
+ \method include attribute value(#1) {
+ \def\pgf@dv@val{#1}
+ \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)
+ }
+
+ % Slot
+ %
+ % This slot should be connected to the survey datapoint signal. For
+ % each datapoint, this method will call the adjust method of the
+ % 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)
+ }
+
+ \def\pgf@dv@range@surv{%
+ \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%
+ \fi%
+ \fi
+ }
+}
+
+
+
+%
+% Visualizers
+%
+
+\usepgflibrary{plothandlers}
+
+
+
+\pgfooclass{plot handler visualizer}
+{
+ % Class plot handler visualizer
+ %
+ % This visualizer uses one or more plot handlers to visualize data points.
+ % As the data points are processed, the canvas positions of the data
+ % points are recorded. At the end of a group of data points, the
+ % recorded stream of canvas position is visualized (rendered)
+ % using plot handlers. For instance, when the lineto plot handler
+ % is used, the data points are connected by straight lines, when the
+ % curveto plot handler is used, they are connected by smooth curves
+ % and so on.
+ %
+ % Since plot lines are not drawn immediately, but only at the end,
+ % when everything has been collected, multiple plot handlers can
+ % coexist peacefully at the same time.
+ %
+ % You can specify a "filter", which will cause only those data
+ % points to be visualized by the visualizer that pass the test. The
+ % filter should set \pgfdvfilterpassedfalse for to-be-filtered 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
+ % before and after the stream of coordinates is created. Typically,
+ % these keys will store commands to use the path created by the plot
+ % handler.
+
+ \attribute handlers;
+ % The to-be-used handlers
+
+ \attribute name;
+ % Filter code
+
+ \attribute filter=\pgfdvnamedvisualizerfilter;
+ % Filter code
+
+ \attribute positions;
+ % An internal protocol of the positions on the stream
+
+ \attribute cache;
+ % An internal cache. Positions are first inserted into this
+ % 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.
+
+
+ % Constructor
+ %
+ % #1 = A name
+ % #2 = A comma-separated list of handlers like
+ % "\pgfplothandlerlineto,\pgfplothandlercurveto"
+ %
+ \method plot handler visualizer(#1,#2) {
+ \pgfooset{name}{#1}
+ \pgfooset{handlers}{#2}
+ }
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,protocol,visualize datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }
+
+ % Setter
+ \method set filter(#1) {
+ \pgfooset{filter}{#1}
+ }
+
+ % Slot
+ \method protocol() {
+ \pgfdvfilterpassedtrue
+ \pgfoovalueof{filter}
+ \ifpgfdvfilterpassed%
+ \pgf@dv@line@cache@it
+ \fi%
+ }
+
+ \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}}}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@dv@cache%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@dv@cache\pgf@dv@add}%
+ % Possibly flush cache
+ \global\advance\pgf@lib@dv@cache@count by1\relax%
+ \ifnum\pgf@lib@dv@cache@count=100\relax%
+ \global\pgf@lib@dv@cache@count=0\relax%
+ % Append cache to positions
+ \pgfooget{positions}\pgf@dv@temp
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@dv@temp%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@dv@temp\pgf@dv@cache}%
+ \pgfoolet{positions}\pgf@dv@temp
+ \let\pgf@dv@cache\pgfutil@empty
+ \fi
+ \pgfoolet{cache}\pgf@dv@cache
+ }
+
+ % Slot
+ \method phase(#1) {%
+ \ifx#1\pgfdvendvisualization%
+ \pgfoothis.render()%
+ \fi%
+ }
+
+ % Internal method
+ \method render() {
+ \pgfscope
+ \pgfooget{handlers}\tikz@dv@temp@list
+ \foreach\tikz@dv@temp in\tikz@dv@temp@list{
+ \ifx\tikz@dv@temp\pgfutil@empty
+ \else
+ \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin}
+ \tikz@dv@temp
+ \pgfplotstreamstart
+ \pgfoovalueof{positions}
+ \pgfoovalueof{cache}
+ \pgfplotstreamend
+ \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end}
+ \fi
+ }
+ \endpgfscope
+ \pgfoolet{positions}\pgfutil@empty
+ \pgfoolet{cache}\pgfutil@empty
+ }
+
+ \def\pgf@dv@ph#1#2{\pgfplotstreampoint{\pgfqpoint{#1}{#2}}}
+}
+
+\newcount\pgf@lib@dv@cache@count
+
+
+% A possible filter for unnamed visualizers
+%
+% #1 = Text to be compared with key /data point/visualizer
+%
+% Description:
+%
+% In a data visualization with multiple visualizers, data points
+% typically "belong" only to a single visualizer. It is, thus,
+% necessary to filter data points accoring to the current
+% visualizer. This current visualizer is assumed to be stored in /data
+% 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.
+
+\def\pgfdvvisualizerfilter#1{%
+ \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@dv@visualizer%
+ \else
+ \pgfdvfilterpassedfalse
+ \fi%
+}
+
+
+
+% A filter for named visualizer
+%
+% Description:
+%
+% 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.
+
+\def\pgfdvnamedvisualizerfilter{%
+ \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer%
+ \pgfooget{name}\pgf@temp%
+ \ifx\pgf@temp\pgf@dv@visualizer%
+ \else
+ \pgfdvfilterpassedfalse
+ \fi%
+}
+
+
+
+\pgfooclass{rectangle visualizer}
+{
+ % 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
+
+ \attribute use path attribute;
+ % The attribute that stores the to-be-taken action
+
+
+ % Constructor
+ %
+ % #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
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,visualize,visualize datapoint signal)
+ }
+
+ % 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
+ \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
+ \ifx\pgf@dv@amax\relax\else\ifx\pgf@dv@amax\pgfutil@empty\else
+ \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}}
+ \fi\fi
+ \fi\fi
+ \fi\fi
+ \fi\fi
+ }
+ }
+}
+
+\newcount\pgf@lib@dv@cache@count
+
+
+
+%
+% Label positioning classes
+%
+
+\pgfooclass{label visualizer}
+{
+ % Class label visualizer
+ %
+ % The job of this class is to visualize a label of a curve or some
+ % other object.
+ %
+ % The idea is as follows: This class monitors a certain
+ % attribute. When this attribute reaches a certain value for the
+ % first time, the following happens: A normalized vector of the line
+ % connecting the current canvas position to the canvas position of
+ % the previous data point is computed and stored in pgf@x/pgf@y. The
+ % coordinate system is shifted so that the current data point is at
+ % the origin. Then, some drawing code is executed.
+
+ \attribute attribute;
+ % The monitored attribute
+
+ \attribute filter;
+ % Filter code, see plot handler visualizer doc.
+
+ \attribute threshold;
+ % When the attribute exceeds this threshold, the drawing code is
+ % executed
+
+ \attribute before canvas position=;
+ % Stores canvas position of the data point before the interesting one
+
+ \attribute canvas position=;
+ % Stores canvas position of the data point
+
+ \attribute code;
+ % To-be-executed code when the label should be drawn
+
+
+ % Constructor
+ %
+ % #1 = attribute
+ % #2 = a macro, storing the threshold
+ % #3 = code
+ % #4 = filter code
+ %
+ \method label visualizer(#1,#2,#3,#4) {
+ \pgfooset{attribute}{#1}
+ \ifx#2\pgfutil@empty
+ \else
+ \pgfdvmathenter{\pgf@temp}{#2}
+ \fi
+ \pgfoolet{threshold}\pgf@temp
+ \pgfooset{code}{#3}
+ \pgfooset{filter}{#4}
+ }
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,test,visualize datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }
+
+ % Slot
+ \method test() {
+ \pgfdvfilterpassedtrue
+ \pgfoovalueof{filter}
+ \ifpgfdvfilterpassed%
+ \pgfooget{attribute}\pgf@dv@attribute
+ \ifx\pgf@dv@attribute\pgfutil@empty%
+ % nothing to do (anymore)
+ \else%
+ \pgf@dv@label@vis@record
+ \fi%
+ \fi%
+ }
+
+ \def\pgf@dv@label@vis@record{
+ % Record current position
+ \edef\pgf@dv@pos{%
+ \noexpand\pgfqpoint%
+ {\pgfkeysvalueof{/data point/canvas x}}%
+ {\pgfkeysvalueof{/data point/canvas y}}}%
+ \pgfooget{canvas position}\pgf@dv@temp%
+ \pgfoolet{before canvas position}\pgf@dv@temp%
+ \pgfoolet{canvas position}\pgf@dv@pos%
+ % Now check threshold
+ \pgfooget{threshold}\pgf@dv@thres%
+ \ifx\pgf@dv@thres\pgfutil@empty%
+ \else%
+ % Hmm, have to check, whether the value is, indeed, correct
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}\pgf@dv@val
+ \ifx\pgf@dv@val\relax%
+ \else\ifx\pgf@dv@val\pgfutil@empty%
+ \else%
+ \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}%
+ \pgfooget{threshold}{\pgf@dv@thres}
+ % Now, protocol value
+ \pgfdvmathifless{\pgf@dv@value}{\pgf@dv@thres}{}{%
+ \pgfoolet{attribute}\pgfutil@empty% Stop!
+ }%
+ \fi\fi%
+ \fi%
+ }
+
+ % Slot
+ \method phase(#1) {%
+ \ifx#1\pgfdvendvisualization%
+ \scope
+ \pgfcoordinate{label visualizer coordinate}{\pgfoovalueof{canvas position}}
+ \pgfcoordinate{label visualizer coordinate'}{\pgfoovalueof{before canvas position}}
+ \pgfoovalueof{code}
+ \endscope
+ \fi%
+ }
+
+}
+
+
+
+%
+% Style sheets
+%
+\pgfooclass{style attribute}
+{
+ % Class style attribute
+ %
+ % Instances of this class are used to select a style based on the
+ % current value of an attribute.
+ %
+ % Instances of this class monitor an attribute. Whenever the "style"
+ % signal is raised, the object investigates the current value of the
+ % attribute. It then looks up /pgf/data visualization/style
+ % sheets/<name of style sheet>/<value of the attribute> and executes
+ % this key, provided it is defined. If it not defined, the key
+ % /pgf/data visualization/style sheets/<name of style sheet>/default
+ % style is executed with the value as a parameter.
+
+ \attribute attribute;
+ % The name of the attribute
+
+ \attribute style sheet name;
+ % The styling function
+
+ % Constructor
+ %
+ % #1 = attribute (including, if present, /data point/)
+ % #2 = style sheet name
+ %
+ \method style attribute(#1,#2) {
+ \pgfooset{attribute}{#1}
+ \pgfooset{style sheet name}{#2}
+ }
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,invoke style,style signal)
+ }
+
+ % Slots
+ \method invoke style() {
+ \pgfooget{attribute}\pgf@dv@temp
+ \pgfkeysgetvalue{\pgf@dv@temp}\pgf@dv@temp@val
+ \ifx\pgf@dv@temp@val\pgfutil@empty%do nothing
+ \else\ifx\pgf@dv@temp@val\relax%do nothing
+ \else%
+ \pgfkeysifdefined{\pgf@dv@temp/\pgf@dv@temp@val}{\pgfkeysgetvalue{\pgf@dv@temp/\pgf@dv@temp@val}\pgf@dv@temp@val}{}% redirect
+ \edef\pgf@temp{/pgf/data visualization/style sheets/\pgfoovalueof{style sheet name}}
+ \pgfkeysifassignable{\pgf@temp/\pgf@dv@temp@val}{%
+ \pgfkeysalso{\pgf@temp/\pgf@dv@temp@val}}{%
+ \pgfkeysalso{\pgf@temp/default style/.expand once=\pgf@dv@temp@val}
+ }
+ \fi\fi%
+ }
+}
+
+
+% Declares a new style sheet
+%
+% #1 = name of style sheet
+% #2 = settings
+%
+% Description:
+%
+% This is a shortcut for doing a /.cd to /pgf/data visualization/style sheets/#1
+
+\def\pgfdvdeclarestylesheet#1#2{
+ \pgfkeys{/pgf/data visualization/style sheets/#1/.cd,#2}
+}
+
+
+
+
+
+
+
+
+
+%
+% Legend container class
+%
+
+\pgfooclass{legend}
+{
+ % Class legend
+ %
+ % This class is used to collect entries into a legend. The idea is
+ % that, say, for each line of a picture you would like to have an
+ % entry in a legend. Then you prepare these entries and send
+ % them to a legend container object. It will collect the entries
+ % and, at the end, arrange them in rows and columns by
+ % separating them using \pgfdvnextcell and \pgfdvendrow.
+ %
+ % By surrounding the resulting arrangement by a call to \pgfmatrix or
+ % a call to \halign you can then create a legend.
+ %
+ % To specify how the entries should be arranged, a size
+ % specification and two directions are needed.
+ %
+ % For the size specification you specify either the ideal number of
+ % columns and the maximum number of rows or you specify the ideal
+ % number of rows and the maximum number of columns. In the first
+ % case, the class first tries to create as many columns as specified
+ % by the "ideal" parameter. If there are less entries than this
+ % parameter, you obviously get less columns, namely as many as there
+ % are entries, each column containing only one entry. If there are
+ % more entries that the ideal number of columns, you get multiple
+ % columns, each containing as many entries to make sure that the
+ % ideal number is met. However, if a column would get more than the
+ % specified maximum number of elements per column, you get more
+ % columns that the ideal number -- to ensure that no column contains
+ % more than the desired number. The case is symmetric, but with the
+ % roles of columns and rows exchanged.
+ %
+ % Here is an example: You specify that you want 2 columns, ideally,
+ % each having a maximum of 4 entries. Here is what you would get:
+ %
+ % Number of entries & Number of resulting columns ... & ... and rows
+ % 1 & 1 & 1
+ % 2 & 2 & 1
+ % 3 & 2 & 2
+ % 4 & 2 & 2
+ % 5 & 2 & 3
+ % 6 & 2 & 3
+ % 7 & 2 & 4
+ % 8 & 2 & 4
+ % 9 & 3 & 4
+ % 10 & 3 & 4
+ % 11 & 3 & 4
+ % 12 & 3 & 4
+ % 13 & 4 & 4
+ %
+ %
+ % Once the number of columns and rows has been computed, the next
+ % step is to "fill" the table. For this, eight strategies may be
+ % specified: right then down, right then up, left then down, left
+ % then up, up then right, up then left, down then right, down then
+ % left. A strategy like "right then up" means the following: Each
+ % new entry should placed right of the previous entry in the
+ % arrangement. However, once the maximum number of elements in a row
+ % has been reached, the a new row should be started that is placed
+ % above ("up") then just-assembled row.
+ %
+ %
+ %
+ %
+ % Example:
+ %
+ % You create an object \legend and then call
+ %
+ % \pgfoofnew \legend=new legend(columns,2,3,down then right)
+ % \legend.add entry(first)
+ % \legend.add entry(second)
+ % \legend.add entry(third)
+ % \legend.add entry(fourth)
+ % \legend.add entry(fifth)
+ % \legend.add entry(sixth)
+ % \legend.add entry(seventh)
+ % \legend.get arrangment(\arrangement)
+ %
+ % Then \arrangment will expand to
+ %
+ % first \pgfdvnextcell fourth \pgfdvnextcell seventh \pgfdvendrow
+ % second \pgfdvnextcell fifth \pgfdvnextcell third \pgfdvendrow
+ % third \pgfdvendrow sixth \pgfdvnextcell \pgfdvendrow
+ %
+ % By saying \let\pgfdvendrow=\\ and \let\pgfdvnextcell=&, you
+ % can use \arrangment inside a table.
+
+
+ \attribute entries;
+ % Collectes the entries
+
+ \attribute columns or rows;
+ % Specifies whether columns or rows are specified
+
+ \attribute ideal;
+ % The ideal number of columns/rows
+
+ \attribute max;
+ % The maximum number of entries per column/row
+
+ \attribute strategy;
+ % Specifies how the matrix should be filled
+
+ \attribute number of entries=0;
+ % Counts the number of entries that have been stored
+
+
+ % Constructor
+ %
+ % #1 = "columns" or "rows" -> specifies whether the ideal number and
+ % the max entries number refer to columns or the row
+ % #2 = the ideal number of #1's
+ % #3 = the maximum number of entries in a #1
+ % #4 = one of the eight strategies
+ %
+ \method legend(#1,#2,#3,#4) {
+ \pgfooset{columns or rows}{#1}
+ \pgfooset{ideal}{#2}
+ \pgfooset{max}{#3}
+ \pgfooset{strategy}{#4}
+ }
+
+ % Method
+ \method add entry(#1) {
+ \pgfooappend{entries}{{#1}}
+ \c@pgf@counta=\pgfoovalueof{number of entries}\relax%
+ \advance\c@pgf@counta by1\relax%
+ \pgfooeset{number of entries}{\the\c@pgf@counta}
+ }
+
+ % Method
+ \method get arrangement(#1) {
+ {
+ %
+ % Step 1: Compute the desired number of rows or columns
+ %
+ %
+ % Compute the ideal number of entries per row/column (called
+ % "target" in the following) and entries per colum/row (called
+ % "per target" in the following)
+ %
+ % if (number of entries > ideal)
+ \ifnum\pgfoovalueof{number of entries}>\pgfoovalueof{ideal}\relax%
+ % {
+ % if (ideal * max > number of entries)
+ \c@pgf@counta=\pgfoovalueof{ideal}\relax%
+ \multiply\c@pgf@counta by\pgfoovalueof{max}\relax%
+ \ifnum\c@pgf@counta>\pgfoovalueof{number of entries}\relax
+ % {
+ % target = ideal;
+ % per target = ceil (number of entries / ideal);
+ \c@pgf@counta=\pgfoovalueof{ideal}\relax%
+ \c@pgf@countb=\pgfoovalueof{number of entries}\relax
+ \advance\c@pgf@countb by-1\relax
+ \divide\c@pgf@countb by\c@pgf@counta\relax%
+ \advance\c@pgf@countb by1\relax%
+ % }
+ % else
+ % {
+ % target = ceil(number of entries / max);
+ % per target = max;
+ \else
+ \c@pgf@countb=\pgfoovalueof{max}\relax%
+ \c@pgf@counta=\pgfoovalueof{number of entries}\relax
+ \advance\c@pgf@counta by-1\relax
+ \divide\c@pgf@counta by\c@pgf@countb\relax%
+ \advance\c@pgf@counta by1\relax%
+ \fi
+ % }
+ % }
+ % else
+ % {
+ % target = number of entries;
+ % per target = 1;
+ % }
+ \else
+ \c@pgf@counta=\pgfoovalueof{number of entries}\relax%
+ \c@pgf@countb=1\relax%
+ \fi%
+ %
+ % Ensure that counta = rows, countb = columns
+ %
+ \pgfooget{columns or rows}\pgf@temp
+ \ifx\pgf@temp\pgf@dv@columnstext%
+ \c@pgf@countc=\c@pgf@counta\relax
+ \c@pgf@counta=\c@pgf@countb\relax
+ \c@pgf@countb=\c@pgf@countc\relax
+ \fi
+ \edef\temp{rows: \the\c@pgf@counta, columns: \the\c@pgf@countb}\temp
+ %
+ % Now arrange the matrix
+ %
+ \csname pgf@dv@legend@init@\pgfoovalueof{strategy}\endcsname
+ \expandafter\let\expandafter\pgf@dv@updater\csname pgf@dv@legend@update@\pgfoovalueof{strategy}\endcsname
+ \pgfooget{entries}\pgf@temp
+ \expandafter\pgf@dv@legend@arrange\pgf@temp\pgf@stop
+ %
+ % Now assemble the matrix
+ %
+ \edef\pgf@dv@row@list{1,...,\the\c@pgf@counta}
+ \edef\pgf@dv@column@list{1,...,\the\c@pgf@countb}
+ \global\let\pgf@dv@matrix\pgfutil@empty
+ \foreach \pgf@dv@row in \pgf@dv@row@list
+ {
+ \global\let\pgf@dv@matrix@row\pgf@dv@first@mark
+ \foreach \pgf@dv@column in \pgf@dv@column@list
+ {
+ \expandafter\let\expandafter\pgf@temp\csname pgf@dv@legend@entry@\pgf@dv@row @\pgf@dv@column\endcsname
+ \ifx\pgf@temp\relax
+ \let\pgf@temp\pgfutil@empty
+ \fi
+ \ifx\pgf@dv@matrix@row\pgf@dv@first@mark
+ \global\let\pgf@dv@matrix@row\pgf@temp
+ \else
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgf@dv@matrix@row\expandafter{\expandafter\pgfdvnextcell\pgf@temp}
+ \fi
+ }
+ \pgfutil@g@addto@macro\pgf@dv@matrix@row{\pgfdvendrow}
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgf@dv@matrix\expandafter{\pgf@dv@matrix@row}
+ }
+ \global\let\pgf@dv@matrix@row\relax
+ }
+ \let#1\pgf@dv@matrix
+ \global\let\pgf@dv@matrix\relax
+ }
+
+ \def\pgf@dv@first@mark{\pgf@dv@first@mark}
+
+ \def\pgf@dv@legend@arrange{%
+ \pgfutil@ifnextchar\pgf@stop{\pgfutil@gobble}{\pgf@dv@legend@handle@entry}
+ }
+
+ \def\pgf@dv@legend@handle@entry#1{
+ \expandafter\def\csname pgf@dv@legend@entry@\the\c@pgf@countc @\the\c@pgf@countd\endcsname{#1}%
+ \pgf@dv@updater%
+ \pgf@dv@legend@arrange%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@init@down then right\endcsname{%
+ \c@pgf@countc=1\relax%
+ \c@pgf@countd=1\relax%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@update@down then right\endcsname{%
+ \advance\c@pgf@countc by1\relax
+ \ifnum\c@pgf@countc>\c@pgf@counta\relax%
+ \c@pgf@countc=1\relax%
+ \advance\c@pgf@countd by1\relax%
+ \fi%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@init@right then down\endcsname{%
+ \c@pgf@countc=1\relax%
+ \c@pgf@countd=1\relax%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@update@right then down\endcsname{%
+ \advance\c@pgf@countd by1\relax
+ \ifnum\c@pgf@countd>\c@pgf@countb\relax%
+ \c@pgf@countd=1\relax%
+ \advance\c@pgf@countc by1\relax%
+ \fi%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@init@up then right\endcsname{%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \c@pgf@countd=1\relax%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@update@up then right\endcsname{%
+ \advance\c@pgf@countc by-1\relax
+ \ifnum\c@pgf@countc=0\relax%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \advance\c@pgf@countd by1\relax%
+ \fi%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@init@right then up\endcsname{%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \c@pgf@countd=1\relax%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@update@right then up\endcsname{%
+ \advance\c@pgf@countd by1\relax
+ \ifnum\c@pgf@countd>\c@pgf@countb\relax%
+ \c@pgf@countd=1\relax%
+ \advance\c@pgf@countc by-1\relax%
+ \fi%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@init@left then up\endcsname{%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@update@left then up\endcsname{%
+ \advance\c@pgf@countd by-1\relax
+ \ifnum\c@pgf@countd=0\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ \advance\c@pgf@countc by-1\relax%
+ \fi%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@init@up then left\endcsname{%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@update@up then left\endcsname{%
+ \advance\c@pgf@countc by-1\relax
+ \ifnum\c@pgf@countc=0\relax%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \advance\c@pgf@countd by-1\relax%
+ \fi%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@init@left then down\endcsname{%
+ \c@pgf@countc=1\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@update@left then down\endcsname{%
+ \advance\c@pgf@countd by-1\relax
+ \ifnum\c@pgf@countd=0\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ \advance\c@pgf@countc by1\relax%
+ \fi%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@init@down then left\endcsname{%
+ \c@pgf@countc=1\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ }
+
+ \expandafter\def\csname pgf@dv@legend@update@down then left\endcsname{%
+ \advance\c@pgf@countc by1\relax
+ \ifnum\c@pgf@countc>\c@pgf@countb\relax%
+ \c@pgf@countc=1\relax%
+ \advance\c@pgf@countd by-1\relax%
+ \fi%
+ }
+
+ \def\pgf@dv@columnstext{columns}
+}
+
+
+
+%
+% Help classes
+%
+
+\pgfooclass{interval}
+{
+ % Class interval
+ %
+ % Instances of this class store intervals. When either the min or
+ % the max value is empty, this corresponds to "not yet set", (not to
+ % "infinity).
+
+ \attribute min;
+ % The minimum value of the interval
+
+ \attribute max;
+ % The maximum value of the interval
+
+ % Constructor
+ %
+ % #1 = initial minimum value
+ % #2 = initial maximum value
+ %
+ \method interval(#1,#2) {
+ \pgfooset{min}{#1}
+ \pgfooset{max}{#2}
+ }
+
+ % Method
+ \method default connects() {
+ }
+
+ % Sets the minimum/maximum to a new value
+ \method set min(#1) {
+ \pgfooset{min}{#1}
+ }
+ \method set max(#1) {
+ \pgfooset{max}{#1}
+ }
+
+ % Getter
+ %
+ % Returns the current values of the minimum and maximum in the
+ % macros \pgfdvmin and \pgfdvmax.
+ \method get min and max() {
+ \pgfooget{min}\pgfdvmin
+ \pgfooget{max}\pgfdvmax
+ }
+
+ % Adjusts the mimum and maximum values
+ %
+ % #1 = some code. When this code is executed, the values of
+ % \pgfdvmin and \pgfdvmax will be set to the current values of
+ % the minimum/maximum. The code may change these values. The
+ % changed values will then be stored.
+ %
+ % This method does nothing that cannot be achieved also by calling
+ % set/get methods, but it is easier to use and faster.
+ \method adjust(#1) {
+ {%
+ \pgfooget{min}\pgfdvmin
+ \pgfooget{max}\pgfdvmax
+ #1%
+ \pgfoolet{min}\pgfdvmin
+ \pgfoolet{max}\pgfdvmax
+ }%
+ }
+}
+
+
+
+\pgfooclass{count}
+{
+ % Class count
+ %
+ % This class can be used to count the number of data points that are
+ % 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
+ % 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
+
+ \attribute val=0;
+ % The current value of the counter
+
+ \attribute step=1;
+ % The stepping by which the counter is incremented for each
+ % datapoint
+
+ \attribute start val=0;
+ % The start value of the counter
+
+ \attribute filter=;
+ % This attribute stores some code that is executed for each
+ % data point. If the data point sets the TeX-if ifpgfdvfilterpassed to
+ % true, then the counter is not incremented.
+
+
+ % Constructor
+ %
+ % #1 = The attribute in which the counter value is stored
+ %
+ \method count(#1) {
+ \pgfooset{attribute}{#1}
+ }
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,apply,prepare datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }
+
+ % Setter
+ \method set value(#1) {
+ \pgfooset{val}{#1}
+ \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute}}{#1}%
+ }
+
+ % Setter
+ \method set start value(#1) {
+ \pgfooset{start val}{#1}
+ }
+
+ % Setter
+ \method set filter(#1) {
+ \pgfooset{filter}{#1}
+ }
+
+ % Setter
+ \method set step(#1) {
+ \pgfooset{step}{#1}
+ }
+
+ % Slot
+ \method apply() {
+ \pgfdvfilterpassedtrue%
+ \pgfoovalueof{filter}%
+ \ifpgfdvfilterpassed%
+ \pgfmathparse{\pgfoovalueof{val}+\pgfoovalueof{step}}%
+ \pgfoolet{val}\pgfmathresult%
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}}\pgfmathresult%
+ \fi%
+ }
+
+ % Slot
+ \method phase(#1) {
+ \ifx#1\pgfdvbeginsurvey
+ \pgfooeset{val}{\pgfoovalueof{start val}}
+ \else \ifx#1\pgfdvbeginvisualization
+ \pgfooeset{val}{\pgfoovalueof{start val}}
+ \fi\fi
+ }
+}
+
+\newif\ifpgfdvfilterpassed
+
+
+
+
+\pgfooclass{accumulator}
+{
+ % Class accumulator
+ %
+ % This class is used to keep track of the sum of the values of some
+ % attribute. When this object is connected to some attribute, the
+ % subkey attribute/sum will always contain the sum of all values in
+ % all previous data points with respect to this
+ % attribute. Furthermore, the subkey attribute/prev key will hold
+ % the previous sum, which is sometimes also useful to have access
+ % to.
+
+ \attribute attribute;
+ % The attribute to-be-accumulated
+
+ \attribute sum;
+ % The initial value of the sum
+
+ % Constructor
+ %
+ % #1 = to-be-accumulated attribute
+ \method accumulator(#1) {
+ \pgfooset{attribute}{#1}
+ \pgfoothis.reset()
+ }
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,apply,prepare datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }
+
+ % Slot
+ \method apply() {%
+ % Save old sum
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/sum}\pgf@temp%
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/prev sum}\pgf@temp%
+ % Add new attribute...
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}{\pgf@temp@b}%
+ \pgfdvmathenter{\pgf@dv@new@val}{\pgf@temp@b}%
+ % ... to sum
+ \pgfooget{sum}\pgf@dv@sum%
+ \pgfdvmathadd{\pgf@dv@sum}{\pgf@dv@new@val}{\pgf@dv@sum}%
+ \pgfoolet{sum}\pgf@dv@sum
+ % Record in attribute
+ \pgfdvmathexitbyscientificformat{\pgf@dv@serial@sum}{\pgf@dv@sum}
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/sum}\pgf@dv@serial@sum
+ }
+
+ % Method
+ %
+ % Use this method to reset the sum at any point.
+ %
+ \method reset() {
+ \pgfdvmathenter{\pgf@dv@temp}{0}
+ \pgfoolet{sum}{\pgf@dv@temp}
+ \pgfdvmathexitbyserializing{\pgf@dv@zero}{\pgf@dv@temp}
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/prev sum}{\pgf@dv@zero}
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/sum}{\pgf@dv@zero}
+ }
+
+ % Slot
+ \method phase(#1) {
+ \ifx#1\pgfdvbeginsurvey
+ \pgfoothis.reset()
+ \else \ifx#1\pgfdvbeginvisualization
+ \pgfoothis.reset()
+ \fi\fi
+ }
+}
+
+
+
+
+
+
+
+%
+%
+% Help keys and, attributes
+%
+%
+
+\pgfkeys{% do not even think of changing the values of the following:
+ /data point/always true/.initial=true,
+ /data point/always false/.initial=false,
+ /data point/always 0/.initial=0,
+ /data point/always 1/.initial=1,
+ /data point/always empty/.initial=,
+ /data point/always pgfusepath stroke/.initial=\pgfusepath{stroke}
+}
+
+\pgfdvmathenter{\pgfdvmathalwaysloge}{0.434294481903252}
+\pgfdvmathenter{\pgfdvmathalwayslnten}{2.302585092994046}
+\pgfdvmathenter{\pgfdvmathalwayszero}{0}
+\pgfdvmathenter{\pgfdvmathalwaysone}{1}
+
+
+\endinput
+
+
+
+
+
+
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 739a28395c2..9834e91f0ec 100644
--- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex
+++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex
@@ -1,4 +1,4 @@
-% Copyright 2008 by Mark Wibrow
+% Copyright 2008 by Mark Wibrow and Till Tantau
%
% This file may be distributed and/or modified
%
@@ -57,10 +57,11 @@
start radius/.initial=2.5pt,
end radius/.initial=2.5pt,
radius/.style={start radius=#1,end radius=#1},
- path has corners/.is if=pgfdecoratepathhascorners
+ path has corners/.is if=pgfdecoratepathhascorners,
+ reverse path/.is if=pgf@decorate@inputsegmentobjects@reverse
}
\newif\ifpgfdecoratepathhascorners
-
+\newif\ifpgf@decorate@inputsegmentobjects@reverse
% Declare a decoration
%
@@ -490,6 +491,7 @@
}
+
% Enviroment \pgfmetadecoration \endpgfmetadecoration
%
% Decorate a path with decoration automatons!
@@ -539,12 +541,12 @@
% \endpgfpicture
%
\def\pgfmetadecoration#1{%
- \begingroup%
- \let\decoration\pgf@metadecoration@decoration%
- \let\beforedecoration\pgf@metadecoration@beforedecoration%
- \let\afterdecoration\pgf@metadecoration@afterdecoration%
- \def\pgf@metadecoration@name{#1}%
- \pgf@decoration@env%
+ \begingroup%
+ \let\decoration\pgf@metadecoration@decoration%
+ \let\beforedecoration\pgf@metadecoration@beforedecoration%
+ \let\afterdecoration\pgf@metadecoration@afterdecoration%
+ \def\pgf@metadecoration@name{#1}%
+ \pgf@decoration@env%
}
\def\endpgfmetadecoration{%
@@ -611,6 +613,21 @@
\bgroup%
}
+\def\pgf@decorate@path@check@moveto#1{%
+ \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@decoration@endenv{%
\egroup%
\pgftransformreset%
@@ -623,6 +640,18 @@
\ifx\pgfdecoratedpath\pgfutil@empty%
\PackageError{PGF}{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}%
+ }%
+ }%
+ {}%
%
% Remove special round tokens and get points.
%
@@ -631,6 +660,16 @@
% Parse the soft path into a series of decorated input segment objects.
%
\pgf@decorate@parsesoftpath{\pgfdecoratedpath}{\pgf@decorate@inputsegmentobjects}%
+ %
+ % Setup further options
+ %
+ \pgfkeys{/pgf/every decoration/.try}%
+ %
+ % Reverse objects if necessary.
+ %
+ \ifpgf@decorate@inputsegmentobjects@reverse%
+ \pgf@decorate@inputsegmentobjects@reverse{\pgf@decorate@inputsegmentobjects}{\pgf@decorate@inputsegmentobjects}%
+ \fi%
%
\let\pgf@decorated@remainingdistance\pgf@decorate@totalpathlength%
%
@@ -647,13 +686,8 @@
\pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject%
\pgf@decorate@processnextinputsegmentobject%
\pgf@decorate@distancetomove0pt\relax%
- %
- % Setup further options
- %
- \pgfkeys{/pgf/every decoration/.try}%
\fi%
-}%
-
+}%
@@ -1194,25 +1228,24 @@
% 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.
%
- \expandafter\pgfutil@in@\expandafter\pgf@decorate@inputsegmentobject@moveto%
- \expandafter{\pgf@decorate@currentinputsegmentobject}%
- \ifpgfutil@in@%
- \pgf@decorate@currentinputsegmentobject%
+ \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%
- \relax%
+ \pgf@decorate@is@closepath@false%
+ \pgf@decorate@currentinputsegmentobject%
\fi%
%
- \pgf@decorate@is@closepath@false%
- \pgf@decorate@currentinputsegmentobject%
- %
% Teensy hack in case a path goes nowhere.
%
\ifdim\pgfdecoratedinputsegmentlength=0pt\relax%
@@ -1221,8 +1254,41 @@
\pgfdecoratedinputsegmentremainingdistance\pgfdecoratedinputsegmentlength\relax%
\pgfdecoratedinputsegmentcompleteddistance0pt\relax%
\def\pgf@decorate@inputsegmenttime{0}%
- \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}%
- \let\pgfdecoratedangle\pgfmathresult%
+ %
+ % 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%
}
@@ -1232,18 +1298,30 @@
\newif\ifpgf@decorate@is@closepath@%
+% Input segment types.
+%
+% These allow comparison with \ifx using
+%
+% \pgfdecorationcurrentinputsegment
+% \pgfdecorationnextinputsegment
+% \pgfdecorationcurrentprevioussegment
+%
+\def\pgfdecorationinputsegmentmoveto{moveto}
+\def\pgfdecorationinputsegmentlineto{lineto}
+\def\pgfdecorationinputsegmentcurveto{curveto}
+\def\pgfdecorationinputsegmentclosepath{closepath}
+\def\pgfdecorationinputsegmentlast{last}
% Input segment object moveto.
%
\def\pgf@decorate@inputsegmentobject@moveto#1{%
- \pgfpathmoveto{#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\pgf@decorate@splitinputsegmentobject\pgf@decorate@splitinputsegmentobject@move%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto%
}
% Input segment object lineto.
@@ -1251,17 +1329,28 @@
\def\pgf@decorate@inputsegmentobject@lineto#1#2#3{%
\def\pgfdecoratedinputsegmentlength{#1}%
\def\pgf@decorate@inputsegment@first{#2}%
+ \def\pgf@decorate@inputsegment@last{#3}%
%
- % OK, lines don't need supports, but this means angle calculations
- % do not have to be done individually for each object.
+ % Supports should be defined like this, so if treated as a curve,
+ % equal time steps will correspond to equal distances.
%
- \def\pgf@decorate@inputsegment@supporta{#3}%
- \def\pgf@decorate@inputsegment@supportb{#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%
+ }%
%
\let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line%
\let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line%
- \let\pgf@decorate@splitinputsegmentobject\pgf@decorate@splitinputsegmentobject@line%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlineto%
}
% Input segment object curveto.
@@ -1275,7 +1364,7 @@
%
\let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@curve%
\let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@curve%
- \let\pgf@decorate@splitinputsegmentobject\pgf@decorate@splitinputsegmentobject@curve%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto%
}
% Input segment object closepath.
@@ -1287,18 +1376,33 @@
%
\def\pgfdecoratedinputsegmentlength{#1}%
\def\pgf@decorate@inputsegment@first{#2}%
- \def\pgf@decorate@inputsegment@supporta{#3}%
- \def\pgf@decorate@inputsegment@supportb{#2}%
- \def\pgf@decorate@inputsegment@last{#3}%
- %
+ \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%
+ }%
+ %
\let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line%
\let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line%
- \let\pgf@decorate@splitinputsegmentobject\pgf@decorate@splitinputsegmentobject@line%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentclosepath%
}
+
% Input segment object endofinputsegments.
%
-\def\pgf@decorate@inputsegmentobject@endofinputsegments{}
+\def\pgf@decorate@inputsegmentobject@endofinputsegments{%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlast%
+}
@@ -1493,7 +1597,7 @@
% \pgfpathlineto{\pgfpoint{12pt}{0pt}}
% \pgfgetpath\softpath
%
-% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath}{}
+% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath}
%
% results in:
%
@@ -1855,6 +1959,150 @@
}
+% Macro to reverse a set of input segment objects.
+%
+% #1 - a macro holding the input segment objects.
+% #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@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@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@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%
+}
+
+\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%
+}
+
+\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}%
+}
+
+\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%
+}
+
+\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%
+}
+
+\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%
+}%
+
+
+
+
+
\let\startpgfdecoration=\pgfdecoration
\let\stoppgfdecoration=\endpgfdecoration
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 c808f60d762..32024c047d6 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.1 2008/01/15 10:27:34 tantau Exp $
+\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulematrix.code.tex,v 1.4 2010/08/24 21:28:58 tantau Exp $
\usepgfmodule{shapes}
@@ -77,7 +77,7 @@
%
% Next, the whole resulting matrix, which is given as #7, is placed
% inside a node whose name is given as #3, whose shape is #1, and
-% whose anchor is #1. This means that the resulting node is shifted
+% whose anchor is #2. This means that the resulting node is shifted
% such that the given anchor lies at the origin. Then, as for a normal
% node, the #4 path usage command is used for the node.
%
@@ -159,6 +159,7 @@
\PackageError{pgf}{You cannot nest pgfmatrix environments, yet}{}
\fi%
\bgroup%
+ \everycr{}%
#6%
\def\pgf@matrix@par@shape{#1}%
\def\pgf@matrix@par@anchor{#2}%
@@ -360,6 +361,9 @@
% Step 4: Collect everything in a cell box
%
\setbox\pgf@matrix@cell=\hbox\bgroup\bgroup%
+ % make sure that cell pictures are not affected if matrizes have
+ % 'overlay' option on:
+ \pgf@relevantforpicturesizetrue
\pgfsys@beginpicture%
\normalbaselines%
% Find out whether the cell is empty:
diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex
new file mode 100644
index 00000000000..e80d3ac06bb
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex
@@ -0,0 +1,451 @@
+% Copyright 2006 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleoo.code.tex,v 1.8 2010/02/22 22:49:21 tantau Exp $
+
+
+
+% Support of object-oriented programming in TeX.
+
+
+% The oo support works as follows:
+%
+% The main supported concepts are classes, objects, methods,
+% attributes and signal/slots. A class defines a set of methods, which are,
+% in the end, just normal TeX macros. Once a class has been created,
+% it can be instantiated by calling the \pgfoonew command, resulting
+% in a new object. Objects are local to their group. Given an object,
+% you can send it a message, resulting in the method code of the
+% object's method to be executed. While an object exists, it has a set
+% of attributes whose values can change over time. Attributes values
+% are not local to TeX groups, rather their life-cycle is the same as
+% the object's (which, however, is local to the group in which the
+% object was declared).
+%
+% The implementation is as follows: There is an ID counter that is
+% increased each time an object is created. This counter is local to
+% the group, which means that when a group ends the counter will
+% revert to the previous value, allowing objects to the reused in
+% subsequent groups.
+%
+% A method is just a normal \TeX macro, but to call it you write
+% \objecthandle.methodname(parameters). The \objecthandle is a macro
+% that is created when you say \pgfoonew. The special object
+% \pgfoothis is the current object.
+%
+% Attributes are stored globally in internal TeX macros whose name is
+% composed of the object number and the attribute name.
+
+
+
+
+% Declares a class
+%
+% #1 = class name
+% #2 = methods
+%
+% Description:
+%
+% This command declares a class for futurue 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}%
+ \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:
+ \expandafter\let\csname pgfooY\pgfoo@classname.get handle\endcsname\pgfoo@obj%
+ \expandafter\let\csname pgfooY\pgfoo@classname.get id\endcsname\pgfoo@id%
+ \let\method=\pgfoo@origmethod%
+ \let\attribute=\pgfoo@origattribute%
+}
+
+
+
+% Declare a method
+%
+% Description:
+%
+% Defines a method. To use/invoke this method for an object \object,
+% you write \object.methodname(parameters). This will cause the method
+% body to be invoked with the argument "(parameters)".
+%
+% To define the method \method should be directly followed by the
+% method name and, then, by (, followed by a parameter pattern,
+% followed by ), followed by the message body. Spaces are allowed only
+% after "\method" and after the closing ).
+%
+% Example:
+%
+% \pgfooclass{MyPlot}{
+%
+% \attribute x=0;
+% \attribute y=0;
+%
+% \method MyPlot() {
+% }
+%
+% \method getX(#1) {
+% \pgfooget{x}{#1}
+% }
+%
+% \method setPoint(#1,#2) {
+% \pgfooset{x}{#1}
+% \pgfooset{y}{#2}
+% }
+% }
+
+\def\pgfoo@declaremethod#1(#2)#3{%
+ \expandafter\long\expandafter\def\csname pgfooY\pgfoo@classname.#1\endcsname(#2){#3}%
+}
+
+
+% Declare an attribute
+%
+% #1 = attribute name
+% #2 = optional default value
+%
+% Description:
+%
+% Declares the attribute #1 for the current class. If the attribute
+% name is followed by =, the text following the equal sign is the
+% default value.
+
+\def\pgfoo@declareattribute#1;{%
+ \pgfutil@in@{ =}{#1}%
+ \ifpgfutil@in@%
+ \pgfoo@declareunpackspace#1;%
+ \else%
+ \pgfutil@in@={#1}%
+ \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}%
+ \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@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}%
+}
+
+
+\newcount\pgfoo@objectcount
+\newcount\pgfoothis@count
+
+% The attribute value method
+%
+% #1 = attr
+%
+% This method inserts the current value of the given attribute for the
+% current object.
+
+\def\pgfoovalueof#1{%
+ \csname pgfooX\the\pgfoothis@count @#1\endcsname%
+}
+
+
+% The attribute get method
+%
+% #1 = attr
+% #2 = macro
+%
+% This method makes the macro equal to the current value of the
+% attribute for the current object.
+
+\def\pgfooget#1#2{%
+ \expandafter\let\expandafter#2\csname pgfooX\the\pgfoothis@count @#1\endcsname%
+}
+
+
+% The attribute set method
+%
+% #1 = attr
+% #2 = value
+%
+% This method sets the given attribute for the current object to the
+% given value.
+
+\long\def\pgfooset#1#2{%
+ \expandafter\gdef\csname pgfooX\the\pgfoothis@count @#1\endcsname{#2}%
+}
+
+
+% The attribute set method (expanded version)
+%
+% #1 = attr
+% #2 = value
+%
+% This method sets the given attribute for the current object to the
+% expanded version of the given value.
+
+\long\def\pgfooeset#1#2{%
+ \expandafter\xdef\csname pgfooX\the\pgfoothis@count @#1\endcsname{#2}%
+}
+
+
+% The attribute let method
+%
+% #1 = attr
+% #2 = value
+%
+% This method sets the given attribute for the current object to the
+% given value using \let.
+
+\def\pgfoolet#1#2{%
+ \expandafter\global\expandafter\let\csname pgfooX\the\pgfoothis@count @#1\endcsname#2%
+}
+
+
+% Add something to an attribute at the end
+%
+% #1 = attr
+% #2 = code
+%
+% This method adds the give code to the attr at the end.
+
+\def\pgfooappend#1#2{%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@oo@temp\expandafter\expandafter\expandafter{\csname pgfooX\the\pgfoothis@count @#1\endcsname#2}%
+ \expandafter\global\expandafter\let\csname pgfooX\the\pgfoothis@count @#1\endcsname\pgf@oo@temp%
+}
+
+
+% Add something to an attribute at the beginning
+%
+% #1 = attr
+% #2 = code
+%
+% This method adds the give code to the attr at the beginning.
+
+\def\pgfooprefix#1#2{%
+ \pgfooget{#1}\pgf@oo@temp%
+ \def\pgf@oo@@temp{#2}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@oo@temp%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@oo@@temp\pgf@oo@temp}%
+ \pgfoolet{#1}\pgf@oo@temp%
+}
+
+
+
+% Instantiate an object
+%
+% Possible syntax:
+%
+% 1) \pgfoonew new <class name>(<constructor parameters)
+% 2) \pgfoonew \<objectname>=new <class name>(<constructor parameters)
+% 3) \pgfoonew{attribute}=new <class name>(<constructor parameters)
+%
+% Description:
+%
+% Creates an object. After the object has been created, the method
+% called <class name> (the constructor) is invoked. If the
+% \<objectname>= part is present, the macro is assigned to the newly
+% created object.
+
+\def\pgfoonew{%
+ \pgfutil@ifnextchar n{%
+ \pgfoo@new\pgfoo@dummy=%
+ }{%
+ \pgfutil@ifnextchar\bgroup{%
+ \pgfoo@new@attribute%
+ }{%
+ \pgfoo@new%
+ }%
+ }%
+}
+\def\pgfoo@new#1=new #2(#3){%
+ \expandafter\ifx\csname pgfooY#2.get id\endcsname\relax%
+ \PackageError{pgfoo}{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%
+ {%
+ \pgfoothis@count\pgfoo@objectcount%
+ \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfooinit\endcsname%
+ }%
+ \pgfoolastobj.#2(#3)%
+ \aftergroup\pgfoogc% cleanup after group
+ \fi%
+}
+\def\pgfoo@new@attribute#1=new #2(#3){%
+ \pgfoo@new\pgf@oo@temp=new #2(#3)%
+ \pgfoolet{#1}\pgf@oo@temp%
+}
+
+
+\def\pgfoo@caller#1.#2(#3){%
+ \def\pgf@marshal{%
+ \pgfoothis@count=#1\relax%
+ \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#2\endcsname(#3)%
+ }%
+ \expandafter\pgf@marshal\expandafter\pgfoothis@count\the\pgfoothis@count\relax%
+}
+\let\pgfoo@orig@caller=\pgfoo@caller
+
+% The special "this" object
+
+\def\pgfoothis.#1(#2){%
+ \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#1\endcsname(#2)%
+}
+
+
+
+
+
+% Get the object id
+%
+% #1 = macro to store the id
+%
+% Description:
+%
+% This special method allows you to access the object id. You can then
+% use \pgfoocall to call a method using this id. This is mainly useful
+% when you wish to store the id for a longer time.
+
+\def\pgfoo@id(#1){%
+ \edef#1{\the\pgfoothis@count}%
+}
+
+% Yields the object with the given id
+%
+% #1 = id
+%
+% Description:
+%
+% Given an object id, \pgfooobj{<id>} will yield the object having
+% this id.
+
+\def\pgfooobj#1{%
+ \pgfoo@caller{#1}%
+}
+
+
+% Get the object
+%
+% #1 = macro to store the object
+%
+% Description:
+%
+% This special method allows you to get a new handle to a given
+% object. If \obj is an object, you could normally just say
+% \let#1=\obj. However, if \obj happens to be \pgfoothis, then you may
+% wish to get a handle to the object itself, not to the special macro
+% \pgfoothis. In this case you can say \obj.get handle(#1).
+
+\def\pgfoo@obj(#1){%
+ \edef#1{\noexpand\pgfoo@caller{\the\pgfoothis@count}}%
+}
+
+
+
+% The garbage collector
+%
+% Description:
+%
+% This method frees space ocupied by unused objects. Garbage are
+% objects that have been destroyed because of the end of the scope in
+% which they were created. In this case, however, the memory used by
+% this object is not immediately reused because the attributes of the
+% object are actually stored in global variables. When the garbage
+% collector is called, it will set all these global variables to
+% \relax, thereby ensuring that no memory is needed for them.
+
+\def\pgfoogc{%
+ {%
+ % We do this in a group...
+ \pgfoothis@count\pgfoo@objectcount% this is temporary...
+ \let\pgfoo@next=\pgfoo@dogc%
+ \pgfoo@next%
+ }%
+}
+\def\pgfoo@dogc{%
+ \advance\pgfoothis@count by 1\relax%
+ \expandafter\ifx\csname pgfooX\the\pgfoothis@count @class\endcsname\relax%
+ \let\pgfoo@next=\relax%
+ \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%
+ \expandafter\global\expandafter\let\csname pgfooX\the\pgfoothis@count @class\endcsname\relax%
+ \fi%
+ \pgfoo@next%
+}
+
+
+
+
+%
+%
+% Signal class
+%
+%
+
+\pgfooclass{signal}
+{
+ %
+ % This class implements signals.
+ %
+ % After you have created a signal object, you can call
+ % connect to connect a slot. Then, whenever the emit method is
+ % called, all connected methods get called.
+
+ % Attribute
+ \attribute emitter;
+ % Collects the objects that should be called.
+
+ % Constructor
+ \method signal() {}
+
+ % Connect a slot (method) #2 of object #1
+ \method connect(#1,#2) {%
+ {%
+ #1.get id(\pgf@tempid)%
+ % Save in emmiter
+ \pgfooget{emitter}\pgf@temp%
+ \let\pgfoo@signal@call=\relax% avoid expansion
+ \edef\pgf@temp{\pgf@temp\pgfoo@signal@call{\pgf@tempid}{#2}}%
+ \pgfoolet{emitter}\pgf@temp%
+ }%
+ }
+
+ \def\pgfoo@signal@call#1#2{%
+ \def\pgf@temp{\pgfooobj{#1}.#2}%
+ \expandafter\pgf@temp\expandafter(\pgfoo@signal@args)%
+ }
+
+ % Emit a signal
+ \method emit(#1) {%
+ \def\pgfoo@signal@args{#1}%
+ \pgfoovalueof{emitter}
+ }
+}
+
+
+
+
+\endinput
diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex
new file mode 100644
index 00000000000..ed13b25324c
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex
@@ -0,0 +1,111 @@
+% Copyright 2009 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/pgfmoduleparser.code.tex,v 1.1 2009/01/12 12:56:09 tantau Exp $
+
+%
+% This file defines commands for defining a letter-by-letter parser
+% based on a dfa.
+%
+
+
+
+
+% Parse the following text
+%
+% #1 = parser
+%
+% Description:
+%
+% This command starts the parser #1 in the initial state "initial". It
+% will parse the following text, stopping when the state "final" has
+% been reached.
+
+\def\pgfparserparse#1{%
+ \def\pgf@parser{#1}%
+ \def\pgf@parser@state{initial}%
+ \pgf@parser@parse%
+}
+\def\pgf@parser@parse{%
+ \futurelet\pgf@parser@symbol\pgf@parser@cont%
+}
+\def\pgf@parser@cont{%
+ % Ok, defined?
+ \expandafter\let\expandafter\pgf@parser@action%
+ \csname pgf@parser@a@\pgf@parser @\pgf@parser@state @\meaning\pgf@parser@symbol\endcsname%
+ \ifx\pgf@parser@action\relax%
+ \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
+ '\meaning\pgf@parser@symbol' in parser '\pgf@parser' in state
+ '\pgf@parser@state'}{}%
+ \fi%
+ \fi%
+ \pgf@parser@action%
+ \ifx\pgf@parser@symbol\pgfutil@sptoken%
+ \expandafter\pgf@parser@rid@space%
+ \else%
+ \expandafter\pgf@parser@rid@other%
+ \fi%
+}
+
+\def\pgf@parser@ridded{%
+ \ifx\pgf@parser@state\pgf@parser@final@text%
+ % done
+ \else%
+ \expandafter\pgf@parser@parse%
+ \fi%
+}
+
+\def\pgf@parser@final@text{final}
+
+{%
+ \def\:{\pgf@parser@rid@space} \expandafter\gdef\: {\futurelet\pgf@parser@ignore\pgf@parser@ridded}
+ \gdef\pgf@parser@rid@other{\afterassignment\pgf@parser@ridded\let\pgf@parser@ignore=}
+}
+
+
+
+% Switches the state
+%
+% #1 = new state
+%
+% Description:
+%
+% This command can be used inside a state action to switch to a
+% different state.
+
+\def\pgfparserswitch#1{\def\pgf@parser@state{#1}}
+
+
+
+
+% Defines an action to be taken in a state for some symbol
+%
+% #1 = parser
+% #2 = state
+% #3 = symbol text (result of saying \meaning on the symbol)
+% #4 = action
+%
+% Description:
+%
+% When the parser encounters #3 while being in state #2, then code #4
+% is executed.
+%
+% When #2 is set to the special text "all", then the symbol is handled
+% in all states by #4, except when a state defines something special
+% for this symbol
+
+\def\pgfparserdef#1#2#3#4{%
+ \expandafter\def\csname pgf@parser@a@#1@#2@#3\endcsname{#4}
+}
+
+
+\endinput
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 5e7a703fd37..ea55ca8517b 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.1 2008/01/15 10:27:34 tantau Exp $
+\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleplot.code.tex,v 1.8 2010/10/22 17:34:17 ludewich Exp $
% PGF's plotting interface works as follows:
@@ -33,7 +33,7 @@
% \pgfplotstreamend
%
% By themselves, the \pgfplotstreamxxxx commands do not do anything by
-% default. Rather, the ``use'' such a stream, you must first install a
+% 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.
%
@@ -118,6 +118,29 @@
+% This handler turns creates a series of lineto commands, with the
+% last command being a closepath, resulting in a closed path.
+%
+% 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%
+ }%
+}
+
+\def\pgf@plot@line@handler@close#1{%
+ \pgfpathmoveto{#1}%
+ \global\let\pgf@plotstreampoint=\pgfpathlineto%
+}
+
+
+
% More handlers are defined in pgflibraryplothandlers
@@ -187,8 +210,8 @@
\def\pgfplotxyfile#1{%
\begingroup%
\pgfplotstreamstart%
- \openin1=#1
- \ifeof1
+ \openin\r@pgf@reada=#1
+ \ifeof\r@pgf@reada
\PackageWarning{pgf}{Plot data file `#1' not found.}
\else
\catcode`\#=14
@@ -201,7 +224,7 @@
\let\pgf@savedpar=\par%
\def\pgf@partext{\par}
\def\pgf@readxyfile{%
- \read1 to \pgf@temp%
+ \pgfutil@read\r@pgf@reada to \pgf@temp%
\let\par=\pgf@savedpar%
\edef\pgf@temp{\pgf@temp}%
\ifx\pgf@temp\pgfutil@empty%
@@ -209,7 +232,7 @@
\else%
\expandafter\pgf@parsexyline\pgf@temp\pgf@stop%
\fi\fi%
- \ifeof1\else\expandafter\pgf@readxyfile\fi%
+ \ifeof\r@pgf@reada\else\expandafter\pgf@readxyfile\fi%
}
\def\pgf@parsexyline#1 #2 #3\pgf@stop{%
@@ -236,8 +259,8 @@
\def\pgfplotxyzfile#1{%
\begingroup%
\pgfplotstreamstart%
- \openin1=#1
- \ifeof1
+ \openin\r@pgf@reada=#1
+ \ifeof\r@pgf@reada
\PackageWarning{pgf}{Plot data file `#1' not found.}
\else
\catcode`\#=14
@@ -248,13 +271,13 @@
}
\def\pgf@readxyzfile{%
- \read1 to \pgf@temp%
+ \pgfutil@read\r@pgf@reada to \pgf@temp%
\ifx\pgf@temp\pgfutil@empty%
\else\ifx\pgf@temp\pgf@partext%
\else%
\expandafter\pgf@parsexyzline\pgf@temp\pgf@stop%
\fi\fi%
- \ifeof1\else\expandafter\pgf@readxyzfile\fi%
+ \ifeof\r@pgf@reada\else\expandafter\pgf@readxyzfile\fi%
}
\def\pgf@parsexyzline#1 #2 #3 #4\pgf@stop{%
@@ -285,38 +308,58 @@
{
\catcode`\%=12
\catcode`\"=12
- \xdef\pgf@gnuplot@head#1{set terminal table; set output "#1.table"; set format "%.5f"}
+ \xdef\pgf@gnuplot@head{set table \noexpand\pgf@plottablefile@quoted; set format "%.5f"}
}
-\newwrite\pgf@plotwrite
+\let\pgf@plotwrite=\w@pgf@writea
\newif\ifpgf@resample@plot
\def\pgfplotgnuplot{\pgfutil@ifnextchar[{\pgf@plotgnuplot}{\pgf@plotgnuplot[\jobname]}}%}
\def\pgf@plotgnuplot[#1]#2{%
\pgf@resample@plottrue%
+ \pgfutilpreparefilename{#1.gnuplot}%
+ \let\pgf@plotgnuplotfile=\pgfretval
+ \pgfutilpreparefilename{#1.table}%
+ \let\pgf@plottablefile=\pgfretval
+ \let\pgf@plottablefile@quoted=\pgfretvalquoted
% Check, whether it is up-to-date
- \openin\pgfutil@inputcheck=#1.gnuplot
+ \openin\pgfutil@inputcheck=\pgf@plotgnuplotfile\relax
\ifeof\pgfutil@inputcheck%
\else%
- \read\pgfutil@inputcheck to\pgf@temp% ignored
- \read\pgfutil@inputcheck to\pgf@plot@line%
+ \pgfutil@read\pgfutil@inputcheck to\pgf@temp% ignored
+ \pgfutil@read\pgfutil@inputcheck to\pgf@plot@line%
+ \closein\pgfutil@inputcheck
\edef\pgf@plot@code{#2\space}%
\ifx\pgf@plot@code\pgf@plot@line%
- \openin\pgfutil@inputcheck=#1.table
+ \openin\pgfutil@inputcheck=\pgfretval\relax
\ifeof\pgfutil@inputcheck%
\else%
+ \closein\pgfutil@inputcheck
\pgf@resample@plotfalse%
\fi%
\fi%
\fi
\ifpgf@resample@plot%
- \immediate\openout\pgf@plotwrite=#1.gnuplot
- \immediate\write\pgf@plotwrite{\pgf@gnuplot@head{#1}}%
- \immediate\write\pgf@plotwrite{#2}%
+ \immediate\openout\pgf@plotwrite=\pgf@plotgnuplotfile\relax
+ \immediate\pgfutil@write\pgf@plotwrite{\pgf@gnuplot@head}%
+ \immediate\pgfutil@write\pgf@plotwrite{#2}%
\immediate\closeout\pgf@plotwrite%
- \immediate\write18{gnuplot #1.gnuplot}
+ \immediate\pgfutil@write18{gnuplot \pgf@plotgnuplotfile}%
+ \fi%
+ % temporarily redefine \pgf@parsexyline
+ \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%
- \pgfplotxyfile{#1.table}
}
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 63f6bf5be9b..da75b3e2e43 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.4 2008/02/13 15:10:06 tantau Exp $
+\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleshapes.code.tex,v 1.13 2010/09/09 13:52:57 cjorssen Exp $
@@ -43,6 +43,7 @@
{%
\let\pgf@sh@savedmacros=\pgfutil@empty% MW
\let\pgf@sh@savedpoints=\pgfutil@empty%
+ \def\shape@name{#1}% CJ
\csname pgf@sh@s@#1\endcsname%
\pgf@sh@savedpoints%
\pgf@sh@savedmacros% MW
@@ -52,20 +53,30 @@
\pgf@y=-\pgf@y%
}%
\expandafter\pgfsavepgf@process\csname pgf@sh@sa@#3\endcsname{%
- \pgf@sh@reanchor{#1}{#2}%
+ \pgf@sh@reanchor{#1}{#2}% FIXME : this is double work!
}%
% Save the saved points and the transformation matrix
- \edef\pgf@test{#3}%
- \ifx\pgf@test\pgfutil@empty%
+ \edef\pgf@node@name{#3}%
+ \ifx\pgf@positionnodelater@macro\relax%
\else%
- \expandafter\xdef\csname pgf@sh@ns@#3\endcsname{#1}%
- \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@np@#3\endcsname}%
+ % 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%
+ %
+ \fi%
+ \ifx\pgf@node@name\pgfutil@empty%
+ \else%
+ \expandafter\xdef\csname pgf@sh@ns@\pgf@node@name\endcsname{#1}%
+ \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@np@\pgf@node@name\endcsname}%
\expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedpoints}%
- \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@ma@#3\endcsname}% MW
+ \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
- \expandafter\xdef\csname pgf@sh@nt@#3\endcsname{\pgf@temp}%
- \expandafter\xdef\csname pgf@sh@pi@#3\endcsname{\pgfpictureid}%
+ \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}}%
@@ -87,7 +98,18 @@
{\csname pgf@sh@fg@#1\endcsname#4}%
\pgfutil@ifundefined{pgf@sh@ffg@#1}{}%
{{\pgfscope\csname pgf@sh@ffg@#1\endcsname\endpgfscope}}%
- \pgf@nodecallback{#3}%
+ \ifx\pgf@positionnodelater@macro\relax%
+ \expandafter\pgf@nodecallback\expandafter{\pgf@node@name}%
+ \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%
+ \fi%
}%
}%
}
@@ -144,6 +166,109 @@
}
}
+
+
+% Create a node that is positioned later
+%
+% #1 = macro to be called after the next node has been created
+%
+% Description:
+%
+% You can use this command to create a node that is "positioned
+% later". The idea is the following: Normally, when a node is created
+% using a command like \pgfnode, the node is immediately inserted into
+% the current picture. In particular, you have no chance to change the
+% position of a created node after it has been create.
+%
+% Using \pgfpositionnodelater, you can change the default
+% behaviour. This command is not a replacement for \pgfnode, but is
+% called before such a command and will cause the following to happen:
+% The node is created, but not inserted into the picture. Instead, it
+% is stored in the box \pgfpositionnodelaterbox. Furthermore, the node
+% is not relevant for the picture's bounding box, but a bounding box
+% for the node is computed and stored in the macros
+% \pgfpositionnodelaterboundboxminx to
+% \pgfpositionnodelaterboundboxmaxy. Finally, the
+% macro #1 is called with the following macros setup:
+%
+% \pgfpositionnodelaterbox
+% A box register (box 0 by default) that stores the node's paths and
+% texts. You should move the contents of this box to a box of your
+% choice.
+%
+% \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@".
+%
+% \pgfpositionnodelaterminx
+% \pgfpositionnodelatermaxx
+% \pgfpositionnodelaterminy
+% \pgfpositionnodelatermaxy
+% These four macros store the bounding box as dimensions that are
+% guarenteed to end with "pt".
+%
+% By setting #1 to \relax (which is the default), you can switch off
+% the whole mechanism
+%
+% Once a late node has been created, you can add arbitrary code in the
+% same picture. Then, at some later point, you call
+% \pgfpositionnodenow to finally position the node at a given position.
+%
+% 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}
+\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,
+% now
+%
+% Description:
+%
+% 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
+% 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
+% have been positioned such that the anchor given upon invocation is
+% at (0,0) and the node is now shifted by #1 before being inserted
+% into the actual picture.
+
+\def\pgfpositionnodenow#1{%
+ {%
+ \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}%
+ \pgf@shift@node{\pgfpositionnodelatername}{\pgf@temp@shift}%
+ % Bounding box update...
+ \pgfpointtransformed{\pgfqpoint{\pgfpositionnodelaterminx}{\pgfpositionnodelaterminy}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}
+ \pgfpointtransformed{\pgfqpoint{\pgfpositionnodelatermaxx}{\pgfpositionnodelatermaxy}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}
+ % Naming and callbacks
+ \expandafter\pgfpositionnodenow@rename\pgfpositionnodelatername\relax%
+ }%
+}
+
+\def\pgfpositionnodenow@rename not yet positioned@#1\relax{%
+ \pgfnoderename{#1}{not yet positioned@#1}
+ \pgf@nodecallback{#1}%
+}
+
+
+
+
+
+
% Alias a node
%
% #1 = new node name
@@ -165,12 +290,68 @@
\pgf@node@gnamelet{pgf@sh@nt@#1}{pgf@sh@nt@#2}%
\pgf@node@gnamelet{pgf@sh@pi@#1}{pgf@sh@pi@#2}%
\pgf@node@gnamelet{pgf@sh@ma@#1}{pgf@sh@ma@#2}%
+ \pgf@nodecallback{#1}%
}
\def\pgf@node@gnamelet#1#2{%
\expandafter\let\expandafter\pgf@temp\csname #2\endcsname%
\expandafter\global\expandafter\let\csname #1\endcsname=\pgf@temp%
}
+% Rename a node
+%
+% #1 = new name
+% #2 = old name
+%
+% Description:
+%
+% Renames a node. This is like an alias, only the memory used for the
+% old name is freed.
+
+\def\pgfnoderename#1#2{%
+ \pgfnodealias{#1}{#2}%
+ \expandafter\global\expandafter\let\csname pgf@sh@ns@#2\endcsname\relax
+ \expandafter\global\expandafter\let\csname pgf@sh@np@#2\endcsname\relax
+ \expandafter\global\expandafter\let\csname pgf@sh@nt@#2\endcsname\relax
+ \expandafter\global\expandafter\let\csname pgf@sh@pi@#2\endcsname\relax
+ \expandafter\global\expandafter\let\csname pgf@sh@ma@#2\endcsname\relax
+}
+
+
+% Quickly create a coordinate node
+%
+% #1 = name
+% #2 = coordinate
+%
+% Description:
+%
+% Creates a node of shape coordinate. The following have the same
+% effect, only the second is much faster:
+%
+% { \pgftransformshift{\pgfpoint{1cm}{2cm} \pgfnode{coordinate}{center}{}{foo}{} }
+% \pgfcoordinate{foo}{\pgfpoint{1cm}{2cm}}
+
+\def\pgfcoordinate#1#2{%
+ \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}%
+ \fi%
+}
+
+\def\pgf@sh@redeferredanchor#1#2{% CJ
+ \expandafter\gdef\csname pgf@anchor@\shape@name @#1\endcsname{#2}}% CJ
+
+
+
+
+
\def\pgf@sh@resavedanchor#1#2{%
\pgf@process{#2}%
@@ -191,14 +372,12 @@
\pgf@sh@marshal%
}
-% MW
-\newtoks\toks@savedmacro
\def\pgf@sh@resavedmacro#1#2{%
\let#1\pgfutil@empty%
\def\addtosavedmacro##1{%
\expandafter\def\expandafter\pgf@sh@addtomacro@temp\expandafter{#1\noexpand\def\noexpand##1{##1}}%
- \expandafter\toks@savedmacro\expandafter{\pgf@sh@addtomacro@temp}%
- \expandafter\def\expandafter#1\expandafter{\the\toks@savedmacro}%
+ {\expandafter\pgfutil@toks@\expandafter{\pgf@sh@addtomacro@temp}\expandafter}%
+ \expandafter\def\expandafter#1\expandafter{\the\pgfutil@toks@}%
}%
#2\relax%
\edef\pgf@sh@marshal{%
@@ -212,12 +391,31 @@
\def\pgf@sh@reanchor#1#2{%
\pgfutil@ifundefined{pgf@anchor@#1@#2}%
{%
- \pgfmathsetcounter{pgf@counta}{#2}%
- \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\c@pgf@counta}{1pt}}%
+ \pgfutil@ifundefined{pgf@anchor@generic@#2}{%
+ \pgfmathsetcounter{pgf@counta}{#2}%
+ \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\c@pgf@counta}{1pt}}%
+ }{%
+ \csname pgf@anchor@generic@#2\endcsname{#1}%
+ }%
}%
{\csname pgf@anchor@#1@#2\endcsname}%
}
+% Defines a generic anchor, i.e. one which gets the associated shape
+% as first argument.
+%
+% #1: the anchor name.
+% #2: the code of the anchor. It may depend upon '##1', the shape's
+% name.
+%
+% The anchor will be defined locally in the current TeX scope.
+%
+% If the anchor will be referenced later by \pgfpointanchor, the macro \pgfreferencednodename
+% 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}%
+}%
% Retrieves an anchor of a shape
@@ -241,6 +439,7 @@
\pgfpointorigin}%
{%
\pgf@process{%
+ \edef\pgfreferencednodename{#1}% for use inside of anchors.
% MW install special macros
\csname pgf@sh@ma@#1\endcsname% MW
% install special coordinates
@@ -305,6 +504,7 @@
\pgfpointorigin}%
{%
\pgf@process{%
+ \edef\pgfreferencednodename{#1}% for use inside of anchors.
% MW install special macros
\csname pgf@sh@ma@#1\endcsname% MW
% install special coordinates
@@ -409,6 +609,7 @@
\let\savedanchor=\pgf@sh@savedanchor
\let\saveddimen=\pgf@sh@saveddimen
\let\savedmacro=\pgf@sh@savedmacro% MW
+ \let\deferredanchor=\pgf@sh@deferredanchor% CJ
\let\anchor=\pgf@sh@anchor
\let\anchorborder=\pgf@sh@anchorborder
\let\behindbackgroundpath=\pgf@sh@behindbgpath
@@ -443,6 +644,9 @@
\def\pgf@sh@savedmacro#1#2{% MW
\expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resavedmacro{#1}{#2}}}% MW
\def\pgf@sh@anchor#1#2{\expandafter\gdef\csname pgf@anchor@\shape@name @#1\endcsname{#2}}
+\def\pgf@sh@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}}
diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesorting.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesorting.code.tex
new file mode 100644
index 00000000000..b85fde14501
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesorting.code.tex
@@ -0,0 +1,69 @@
+% Copyright 2008 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/pgfmodulesorting.code.tex,v 1.1 2008/11/12 23:39:37 tantau Exp $
+
+%
+% This file defines commands for sorting data. This is useful for 3d plots,
+% but also for drawing things in the correct order.
+%
+
+
+\newcount\pgfsortingbuckets
+
+
+% Init the sorting
+%
+% #1 = number of buckets
+%
+% Description:
+%
+% This macro inits a sorting. At any time there can be only one active
+% sorting. When you init the sorting, #1 should be a number of
+% buckets. You can then call \pgfsortinginsert to insert code into the
+% buckets. Once you are done, calling \pgfsortingexecute will execute
+% first the code in buckets 0, then the code in bucket 1, and so on to
+% bucket number #1-1.
+%
+\def\pgfsortinginit#1{
+ \pgfsortingbuckets#1\relax%
+ \c@pgf@counta=0\relax
+ \pgfutil@loop
+ \ifnum\c@pgf@counta<\c@pgf@countb\relax%
+ \expandafter\global\expandafter\let\csname pgf@sort@\the\c@pgf@counta\endcsname\pgfutil@empty%
+ \advance\c@pgf@counta by1\relax%
+ \pgfutil@repeat
+}
+
+% Insert code into some bucket
+%
+% #1 = the bucket
+% #2 = the code
+%
+\def\pgfsortinginsert#1#1{
+ \expandafter\let\expandafter\pgf@temp\csname pgf@lib@sort@#1\endcsname%
+ \expandafter\def\expandafter\pgf@temp\expandafter{\pgf@temp#2}%
+ \expandafter\global\expandafter\let\csname pgf@lib@sort@\the\c@pgf@counta\endcsname\pgf@temp%
+}
+
+
+% After all code has been inserted into the buckets, you can call
+% this method to execute the code in the order of the buckets.
+\def\pgfsortingexecute{
+ \c@pgf@countb=\pgfoovalueof{buckets}\relax
+ \c@pgf@counta=0\relax
+ \pgfutil@loop
+ \ifnum\c@pgf@counta<\c@pgf@countb\relax%
+ \csname pgf@lib@sort@\the\c@pgf@counta\endcsname%
+ \advance\c@pgf@counta by1\relax%
+ \pgfutil@repeat
+}
+
+
+\endinput