diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgfplots')
22 files changed, 3869 insertions, 170 deletions
diff --git a/Master/texmf-dist/tex/generic/pgfplots/libs/tikzlibrarypgfplots.decorations.softclip.code.tex b/Master/texmf-dist/tex/generic/pgfplots/libs/tikzlibrarypgfplots.decorations.softclip.code.tex new file mode 100644 index 00000000000..06b3c62dfe2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/libs/tikzlibrarypgfplots.decorations.softclip.code.tex @@ -0,0 +1,36 @@ +%-------------------------------------------- +% +% Package pgfplots +% +% Provides a user-friendly interface to create function plots (normal +% plots, semi-logplots and double-logplots). +% +% It is based on Till Tantau's PGF package. +% +% Copyright 2013 by Christian Feuersaenger +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see <http://www.gnu.org/licenses/>. +% +%-------------------------------------------- +% +% This library adds support for a "soft clip" decoration. It applies +% clipping to an input path, but rather than simply instructing the +% display driver to clip the path, it computes a new clip path from +% the input. +% +% This library is (currently) on top of tikz. + +\usetikzlibrary{decorations.softclip} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgfplots/libs/tikzlibrarypgfplots.fillbetween.code.tex b/Master/texmf-dist/tex/generic/pgfplots/libs/tikzlibrarypgfplots.fillbetween.code.tex new file mode 100644 index 00000000000..36c5b4ddf61 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/libs/tikzlibrarypgfplots.fillbetween.code.tex @@ -0,0 +1,167 @@ +%-------------------------------------------- +% +% Package pgfplots +% +% Provides a user-friendly interface to create function plots (normal +% plots, semi-logplots and double-logplots). +% +% It is based on Till Tantau's PGF package. +% +% Copyright 2013 by Christian Feuersaenger +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see <http://www.gnu.org/licenses/>. +% +%-------------------------------------------- + + +% This library adds support for high-level instructions for "fill area +% between two arbitrary plots of functions". +% +% It activates the syntax +% +% \addplot fill between[of=A and B]; +% +% where A and B are two plots named by 'name path='. +% +% In fact, this here is not much more than a low-level invocation of +% \pgfpathfillbetween +% and a couple of styles. It could become a TikZ library because it +% actually works on any two named paths, but it has its restrictions +% regarding the supported input paths: both need to be plots of +% functions (non-intersecting, should have at most one function value +% for each canvas X coord) + +\pgfutil@IfUndefined{pgfplotsset}{% + \pgferror{Please load pgfplots before pgfplots.fillbetween.}% + \endinput +}{}% + +\usetikzlibrary{fillbetween} +\usepgfplotslibrary{decorations.softclip} + +\pgfkeys{ + /pgfplots/every fill between plot/.style={/pgfplots/area legend,/tikz/fill}, + /tikz/soft clip assign/domain/.code args={#1:#2}{% + \edef\pgfplots@loc@TMPa{(axis cs:#1,\pgfkeysvalueof{/pgfplots/ymin}) rectangle (axis cs:#2,\pgfkeysvalueof{/pgfplots/ymax})}% + \pgfkeysalso{/tikz/soft clip assign/path/.expand once=\pgfplots@loc@TMPa}% + },% + /tikz/soft clip assign/y domain y/.style={/tikz/soft clip assign/domain y={#1}}, + /tikz/soft clip assign/domain y/.code args={#1:#2}{% + \edef\pgfplots@loc@TMPa{(axis cs:\pgfkeysvalueof{/pgfplots/xmin},#1) rectangle (axis cs:\pgfkeysvalueof{/pgfplots/xmax},#2)}% + \pgfkeysalso{/tikz/soft clip assign/path/.expand once=\pgfplots@loc@TMPa}% + },% + % + /pgfplots/execute at begin axis@@/.add={}{% + \gdef\pgfplotsfillbetween@list@of@layers@with@clippath{}% + \gdef\b@pgfplotsfillbetween@list@has@set@layers{0}% + }, +} + +\def\pgfplotsfillbetween@ensure@clipping@on@layer{% + \ifpgfplots@clip + \pgfkeysgetvalue{/tikz/fill between/on layer}\pgfplots@loc@TMPa + \edef\pgfplots@loc@TMPa{\pgfplots@loc@TMPa}% + % + % check if 'pre main,' is inside of the already prepared layers: + \def\pgfplots@loc@TMPb{\expandafter\pgfutil@in@\expandafter{\pgfplots@loc@TMPa,}}% + \expandafter\pgfplots@loc@TMPb\expandafter{\pgfplotsfillbetween@list@of@layers@with@clippath}% + % + \ifpgfutil@in@ + % ah - already prepared. Good, nothing left to do. + \else + \pgfplots@log3{fill between: found 'clip=true'. installing clip path for layer '\pgfplots@loc@TMPa'...}% + \xdef\pgfplotsfillbetween@list@of@layers@with@clippath{\pgfplots@loc@TMPa,\pgfplotsfillbetween@list@of@layers@with@clippath}% + % + \edef\pgfplots@loc@TMPb{% + \noexpand\pgfplotsextra{% + \noexpand\pgfplotsonlayer{\pgfplots@loc@TMPa}% + \noexpand\pgfplotspathaxisoutline + \noexpand\pgfusepath{clip}% + \noexpand\endpgfplotsonlayer + }% + }% + \pgfplots@loc@TMPb + % + \fi + \fi +}% + +% The options are from +% \addplot[#1] fill between[#2] #3; +% +% This method is invoked from the global \addplot dispatching. +\def\pgfplotslibraryfillbetween@addplot#1#2#3{% + % + \pgfplots@start@plot@with@behavioroptions{/pgfplots/every fill between plot,#1}% + % + \pgfkeysvalueof{/pgfplots/execute at end survey}% + \pgfplots@remember@survey@option@list + % + % + \pgfplotslibraryfillbetweenpreparecurrentlayer + % + \pgfplots@addplot@enqueue@coords{% + % precmd + }{% + % empty - this here is a TikZ instruction, not a "real" \addplot command + }{% + % the path instruction: + \tikzfillbetween[#2]{% + /pgfplots/.search also=/tikz,% + /pgfplots/.cd,% + #1% + }% + }{% + % post command. + }% +} + +% SIDE-EFFECT: modifies \b@pgfplotsfillbetween@list@has@set@layers and +% \pgfplotsfillbetween@list@of@layers@with@clippath +\def\pgfplotslibraryfillbetweenpreparecurrentlayer{% + \pgfkeysgetvalue{/tikz/fill between/on layer}\pgfplots@loc@TMPa + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \if0\b@pgfplotsfillbetween@list@has@set@layers + \pgfplots@log3{fill between: activating layered graphics}% + \pgfplotssetlateoptions{set layers}% + \gdef\b@pgfplotsfillbetween@list@has@set@layers{1}% + \fi + \pgfplotsfillbetween@ensure@clipping@on@layer + \fi +} + +\def\pgfplots@tikzfillbetween{\pgfutil@ifnextchar[{\pgfplots@tikzfillbetween@opt}{\pgfplots@tikzfillbetween@opt[]}} +\def\pgfplots@tikzfillbetween@opt[#1]#2{% + \pgfplots@addplot@enqueue@coords{% + % precmd + }{% + % empty - this here is a TikZ instruction, not a "real" \addplot command + }{% + % the path instruction: + \tikzfillbetween[#1]{#2}% + }{% + % post command. + }% +}% + +\expandafter\def\expandafter\pgfplots@replace@path@commands\expandafter{\pgfplots@replace@path@commands + \let\pgfplots@orig@tikzfillbetween=\tikzfillbetween + \let\tikzfillbetween=\pgfplots@tikzfillbetween +}% +\expandafter\def\expandafter\pgfplots@restore@path@commands\expandafter{\pgfplots@restore@path@commands + \let\tikzfillbetween=\pgfplots@orig@tikzfillbetween +} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgfplots/numtable/pgfplotstable.coltype.code.tex b/Master/texmf-dist/tex/generic/pgfplots/numtable/pgfplotstable.coltype.code.tex index b56d65147fc..8c0000b324c 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/numtable/pgfplotstable.coltype.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/numtable/pgfplotstable.coltype.code.tex @@ -77,7 +77,15 @@ } \def\pgfplotstablecoltype@finish{% %\message{COLLECTED \meaning\pgfplotstablecoltype@content}% - \pgfmathprintnumber{\pgfplotstablecoltype@content}% + \edef\pgfplotstablecoltype@content{\pgfplotstablecoltype@content}% + % + % trim white space: + \expandafter\pgfkeys@spdef\expandafter\pgfplotstablecoltype@content\expandafter{\pgfplotstablecoltype@content}% + % + \ifx\pgfplotstablecoltype@content\pgfutil@empty + \else + \pgfmathprintnumber{\pgfplotstablecoltype@content}% + \fi \endgroup }% diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_loader.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_loader.code.tex index 8b73f91fbf0..b3dcd2d6003 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_loader.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_loader.code.tex @@ -8,6 +8,15 @@ }{}% +\def\pgfplotsusecompatibilityfile#1{% + \pgfutil@IfUndefined{pgfplotsusecompatibilityfile@loaded@#1}{% + \expandafter\gdef\csname pgfplotsusecompatibilityfile@loaded@#1\endcsname{1}% + \input pgfplotsoldpgfsupp_#1 + }{% + % already loaded. + }% +}% + \def\pgfmathfloatrounddisplaystyle@shared@impl@WRONG#1#2{% {\toks0={#1}% \toks1=\expandafter{\pgfmathfloatrounddisplaystyle@e@mark #2}% @@ -62,5 +71,14 @@ }{% }% +\pgfutil@IfUndefined{pgfapplistnewempty}{% + \immediate\write16{Package pgfplots: loading complementary utilities for your pgf version...} + \csname newtoks\endcsname\t@pgf@toka + \csname newtoks\endcsname\t@pgf@tokb + \csname newtoks\endcsname\t@pgf@tokc + \gdef\pgfutil@advancestringcounter{\pgfplotsutil@advancestringcounter}% + \input pgfplotsoldpgfsupp_pgfutil-common-lists.tex +}{}% + \endinput diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_misc.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_misc.code.tex index abaf662bc40..0c47024409a 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_misc.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_misc.code.tex @@ -9,6 +9,41 @@ }{}% } +\def\tikz@key@name@path@wrong#1#2{% + \tikz@addmode{% + \pgfsyssoftpath@getcurrentpath\tikz@intersect@temppath@round% + \pgfprocessround\tikz@intersect@temppath@round\tikz@intersect@temppath% + \ifx\tikz@intersect@namedpaths\pgfutil@empty% + \else% + \tikz@intersect@namedpaths% + \pgfutil@ifundefined{tikz@intersect@path@name@#1}{}% + {% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\tikz@intersect@@temppath% + \expandafter\expandafter\expandafter{\csname tikz@intersect@path@name@#1\endcsname}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\tikz@intersect@temppath% + \expandafter\expandafter\expandafter{\expandafter\tikz@intersect@temppath\tikz@intersect@temppath}% + }% + \fi% + \tikz@intersect@addto@path@names{#1}{#2}% + }% +}% + +\def\tikz@key@name@path@new#1#2{% + \tikz@addmode{% + \pgfsyssoftpath@getcurrentpath\tikz@intersect@temppath@round% + \pgfprocessround\tikz@intersect@temppath@round\tikz@intersect@temppath% + \ifx\tikz@intersect@namedpaths\pgfutil@empty% + \else% + \tikz@intersect@namedpaths% + \fi% + \tikz@intersect@addto@path@names{#1}{#2}% + }% +}% + +\ifx\tikz@key@name@path@wrong\tikz@key@name@path + \let\tikz@key@name@path=\tikz@key@name@path@new +\fi + \def\pgfutil@insertatbegincurrentpagefrombox@WRONG#1{% \global\setbox\pgfutil@abb\hbox{\unhbox\pgfutil@abb#1}% } diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgflibraryintersections.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgflibraryintersections.code.tex new file mode 100644 index 00000000000..1356aaec9ab --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgflibraryintersections.code.tex @@ -0,0 +1,1013 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% This file is a copy of some part of PGF/Tikz. +%%% It has been copied here to provide : +%%% - compatibility with older PGF versions +%%% - availability of PGF contributions by Christian Feuersaenger +%%% which are necessary or helpful for pgfplots. +%%% +%%% For reasons of simplicity, I have copied the whole file, including own contributions AND +%%% PGF parts. The copyrights are as they appear in PGF. +%%% +%%% Note that pgfplots has compatible licenses. +%%% +%%% This copy has been modified in the following ways: +%%% - nested \input commands have been updated +%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% Date of this copy: Fr 14. Feb 21:37:39 CET 2014 %%% + + + +% Copyright 2008 by Mark Wibrow +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +% Note: at the time of this writing, the library has quadratic runtime. +% Experimentally, it performed well while computing ~12 intersections of two +% plots, each with 600 samples. It failed when the number of samples exceeded 700. + +\usepgflibrary{fpu} + +\newcount\pgf@intersect@solutions + +\newif\ifpgf@intersect@sort +\newif\ifpgf@intersect@sort@by@second@path + +\def\pgfintersectionsortbyfirstpath{% + \pgf@intersect@sorttrue% + \pgf@intersect@sort@by@second@pathfalse% +} + +\def\pgfintersectionsortbysecondpath{% + \pgf@intersect@sorttrue% + \pgf@intersect@sort@by@second@pathtrue% +} + +% #1: the index. It starts at 1 and ends with \pgfintersectionsolutions (inclusive). +% Invalid values will implicitly result in the origin. +\def\pgfpointintersectionsolution#1{% + \ifnum#1<1\relax% + \pgfpoint@intersect@solution@orgin% + \else% + \ifnum#1>\pgfintersectionsolutions\relax% + \pgfpoint@intersect@solution@orgin% + \else% + \csname pgfpoint@intersect@solution@#1\endcsname% + \fi% + \fi% +} + +% Gets the segment indices of solution #1. +% +% #1: the solution index (i.e. the same argument as in \pgfpointintersectionsolution) +% #2: [output] a macro name which will contain the segment index of the first path which contains the solution +% #3: [output] a macro name which will contain the segment index of the second path which contains the solution +% +% Example: \pgfintersectiongetsolutionsegmentindices{0}{\first}{\second} +% +% -> \first may be 0 if point #0 is in the 0'th segment +% -> \second may be 42 if point #0 is in the 42'th segment +% +% The "segment index" is actually close to the "time" of the solution. +% If a solution is at "time" 42.2, it will have segment index 42. +\def\pgfintersectiongetsolutionsegmentindices#1#2#3{% + \ifnum#1<1\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \ifnum#1>\pgfintersectionsolutions\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \def\pgf@temp##1##2##3##4{% + \edef#2{##1}% + \edef#3{##2}% + }% + \expandafter\let\expandafter\pgf@tempb\csname pgf@intersect@solution@props@#1\endcsname + \expandafter\pgf@temp\pgf@tempb + \fi% + \fi% +}% + +% Gets the time indices of solution #1. +% +% #1: the solution index (i.e. the same argument as in \pgfpointintersectionsolution) +% #2: [output] a macro name which will contain the time of the first path which contains the solution +% It will never be empty. +% #3: [output] a macro name which will contain the time of the second path which contains the solution +% It will never be empty. +% +% Example: \pgfintersectiongetsolutiontimes{0}{\first}{\second} +% +% -> \first may be 0.5 if point #0 is in just in the middle of the path +% -> \second may be 42.8 if point #0 is in the 42'th segment (compare +% \pgfintersectiongetsolutionsegmentindices) and is at 80% of the +% 42'th segment +% +% Note that the precise time inside of a segment may be unavailable +% (currently, it is only computed for curveto paths and not +% necessarily for lineto). If the precise time is unavailable, this +% call will return the value of +% \pgfintersectiongetsolutionsegmentindices (which is a +% "coarse-grained" time). +\def\pgfintersectiongetsolutiontimes#1#2#3{% + \ifnum#1<1\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \ifnum#1>\pgfintersectionsolutions\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \def\pgf@temp##1##2##3##4{% + \edef#2{##3}% + \edef#3{##4}% + % + % check for fallback to segment indices: + \ifx#2\pgfutil@empty \edef#2{##1}\fi + \ifx#3\pgfutil@empty \edef#3{##2}\fi + }% + \expandafter\let\expandafter\pgf@tempb\csname pgf@intersect@solution@props@#1\endcsname + \expandafter\pgf@temp\pgf@tempb + \fi% + \fi% +}% + +\def\pgfpoint@intersect@solution@orgin{% + \begingroup% + \pgftransforminvert% + \pgfpointorigin% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x=\pgf@x% + \global\pgf@y=\pgf@y% + \endgroup% +} + +% #1 code which assigns the first path using \pgfsetpath. +% #2 code which assigns the second path using \pgfsetpath. +% +% On output, the points, their properties, and the number of points are set. +% Use \pgfintersectionsolutions which expands to the number of intersections +\long\def\pgfintersectionofpaths#1#2{% + \begingroup% + \pgfinterruptpath% + #1% + \pgfgetpath\pgf@intersect@path@a% + \global\let\pgf@intersect@path@temp=\pgf@intersect@path@a% + \endpgfinterruptpath% + \endgroup% + \let\pgf@intersect@path@a=\pgf@intersect@path@temp% + % + \begingroup% + \pgfinterruptpath% + #2% + \pgfgetpath\pgf@intersect@path@b% + \global\let\pgf@intersect@path@temp=\pgf@intersect@path@b% + \endpgfinterruptpath% + \endgroup% + \let\pgf@intersect@path@b=\pgf@intersect@path@temp% + % + \pgf@intersect@solutions=0\relax% + \pgf@intersect@path@reset@a + % + \ifpgf@intersect@sort@by@second@path% + \let\pgf@intersect@temp=\pgf@intersect@path@a% + \let\pgf@intersect@path@a=\pgf@intersect@path@b% + \let\pgf@intersect@path@b=\pgf@intersect@temp% + \fi% + % + \pgfprocessround\pgf@intersect@path@a\pgf@intersect@path@a% + \pgfprocessround\pgf@intersect@path@b\pgf@intersect@path@b% + % + \let\pgf@intersect@token@after=\pgf@intersect@path@process@a% + \expandafter\pgf@intersectionofpaths\pgf@intersect@path@a\pgf@stop% + \edef\pgfintersectionsolutions{\the\pgf@intersect@solutions}% + \pgfmathloop% + \ifnum\pgfmathcounter>\pgfintersectionsolutions\relax% + \else% + \pgfutil@namelet{pgfpoint@intersect@solution@\pgfmathcounter}% + {pgfpoint@g@intersect@solution@\pgfmathcounter}% + \edef\pgf@marshal{\noexpand\pgf@intersection@set@properties{\csname pgfpoint@g@intersect@solution@\pgfmathcounter @props\endcsname}}% + \pgf@marshal + \ifpgf@intersect@sort% + \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}% + {pgf@g@intersect@solution@\pgfmathcounter @time@a}% + \fi% + \repeatpgfmathloop% + \ifpgf@intersect@sort% + \pgfintersectionsolutionsortbytime% + \fi% +} + +\def\pgf@intersection@set@properties#1{% + \pgfutil@namedef{pgf@intersect@solution@props@\pgfmathcounter}{#1}% +}% + +% #1 a global name prefix to store properties. +\def\pgf@intersection@store@properties#1{% + % we store the time offsets as well and make them available programmatically: + % note that \pgf@intersect@time@a and \pgf@intersect@time@b may be empty. + % + % However, \pgf@intersect@time@offset and + % \pgf@intersect@time@offset@b are *always* valid. In fact,they + % resemble a part of the time: it holds + % 0 <= \pgf@intersect@time@a < 1 + % and \pgf@intersect@time@offset > 0. + % + % If we have an intersection in segment 42 of path A, + % \pgf@intersect@time@offset will be 42. The time inside of that + % segment is given as number in the interval [0,1]. If it is 0.3, + % the total time will be 42.3 and that number will be stored as + % \pgf@intersect@time@a. + % + \expandafter\xdef\csname #1@props\endcsname{{\pgf@intersect@time@offset}{\pgf@intersect@time@offset@b}{\pgf@intersect@time@a}{\pgf@intersect@time@b}}% +} + +\def\pgf@intersectionofpaths#1{% + \ifx#1\pgf@stop% + \let\pgf@intersect@next=\relax% + \else% + \ifx#1\pgfsyssoftpath@movetotoken% + \let\pgf@intersect@next=\pgf@intersect@token@moveto% + \else% + \ifx#1\pgfsyssoftpath@linetotoken% + \let\pgf@intersect@next=\pgf@intersect@token@lineto% + \else% + \ifx#1\pgfsyssoftpath@closepathtoken% + \let\pgf@intersect@next=\pgf@intersect@token@lineto% + \else% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \let\pgf@intersect@next=\pgf@intersect@token@curveto% + \else% + \ifx#1\pgfsyssoftpath@rectcornertoken% + \let\pgf@intersect@next=\pgf@intersect@token@rect% + \fi% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgf@intersect@next} + +\def\pgf@intersect@token@moveto#1#2{% + \def\pgfpoint@intersect@start{\pgfqpoint{#1}{#2}}% + \pgf@intersectionofpaths% +} + +\def\pgf@intersect@token@lineto#1#2{% + \def\pgfpoint@intersect@end{\pgfqpoint{#1}{#2}}% + \def\pgf@intersect@type{line}% + \pgf@intersect@token@after% +} +\def\pgf@intersect@token@curveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{% + \def\pgfpoint@intersect@firstsupport{\pgfqpoint{#1}{#2}}% + \def\pgfpoint@intersect@secondsupport{\pgfqpoint{#3}{#4}}% + \def\pgfpoint@intersect@end{\pgfqpoint{#5}{#6}}% + \def\pgf@intersect@type{curve}% + \pgf@intersect@token@after% +} + +\def\pgf@intersect@token@rect#1#2\pgfsyssoftpath@rectsizetoken#3#4{% + \pgf@xa=#1\relax% + \advance\pgf@xa by#3\relax% + \pgf@ya=#2\relax% + \advance\pgf@ya by#4\relax% + \edef\pgf@marshal{% + \noexpand\pgfsyssoftpath@movetotoken{#1}{#2}% + \noexpand\pgfsyssoftpath@linetotoken{#1}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@xa}{#2}% + \noexpand\pgfsyssoftpath@closepathtoken{#1}{#2}% + }% + \expandafter\pgf@intersectionofpaths\pgf@marshal% +} + +\def\pgf@intersect@path@process@a{% + \pgf@intersect@path@getpoints@a% + \let\pgf@intersect@token@after=\pgf@intersect@path@process@b% + \pgf@intersect@path@reset@b + \expandafter\pgf@intersectionofpaths\pgf@intersect@path@b\pgf@stop% + \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@a% + \let\pgf@intersect@token@after=\pgf@intersect@path@process@a% + \c@pgf@counta=\pgf@intersect@time@offset\relax% + \advance\c@pgf@counta by1\relax% + \edef\pgf@intersect@time@offset{\the\c@pgf@counta}% + \pgf@intersectionofpaths% +} + +\def\pgf@intersect@path@reset@a{% + \def\pgf@intersect@time@offset{0}% + \def\pgf@intersect@time@a{}% +}% + +\def\pgf@intersect@path@reset@b{% + \def\pgf@intersect@time@offset@b{0}% + \def\pgf@intersect@time@b{}% +}% + +\def\pgf@intersect@path@getpoints@a{% + \let\pgfpoint@intersect@start@a=\pgfpoint@intersect@start% + \let\pgfpoint@intersect@end@a=\pgfpoint@intersect@end% + \let\pgfpoint@intersect@firstsupport@a=\pgfpoint@intersect@firstsupport% + \let\pgfpoint@intersect@secondsupport@a=\pgfpoint@intersect@secondsupport% + \let\pgf@intersect@type@a=\pgf@intersect@type% +} + +\def\pgf@intersect@path@process@b{% + \pgf@intersect@path@getpoints@b% + \csname pgf@intersect@\pgf@intersect@type@a @and@\pgf@intersect@type@b\endcsname% + \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@b% + \c@pgf@counta=\pgf@intersect@time@offset@b\relax% + \advance\c@pgf@counta by1\relax% + \edef\pgf@intersect@time@offset@b{\the\c@pgf@counta}% + \pgf@intersectionofpaths} + +\def\pgf@intersect@path@getpoints@b{% + \let\pgfpoint@intersect@start@b=\pgfpoint@intersect@start% + \let\pgfpoint@intersect@end@b=\pgfpoint@intersect@end% + \let\pgfpoint@intersect@firstsupport@b=\pgfpoint@intersect@firstsupport% + \let\pgfpoint@intersect@secondsupport@b=\pgfpoint@intersect@secondsupport% + \let\pgf@intersect@type@b=\pgf@intersect@type% +} + +\def\pgf@intersect@line@and@line{% + \pgf@intersectionoflines{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}% + {\pgfpoint@intersect@start@b}{\pgfpoint@intersect@end@b}% +}% + +\def\pgf@intersect@line@and@curve{% + \pgf@intersectionoflineandcurve% + {\pgf@process{\pgfpoint@intersect@start@a}}{\pgf@process{\pgfpoint@intersect@end@a}}% + {\pgf@process{\pgfpoint@intersect@start@b}}{\pgf@process{\pgfpoint@intersect@firstsupport@b}}% + {\pgf@process{\pgfpoint@intersect@secondsupport@b}}{\pgf@process{\pgfpoint@intersect@end@b}}% +} + +\def\pgf@intersect@curve@and@line{% + \pgf@intersectionofcurveandline% + {\pgf@process{\pgfpoint@intersect@start@a}}{\pgf@process{\pgfpoint@intersect@firstsupport@a}}% + {\pgf@process{\pgfpoint@intersect@secondsupport@a}}{\pgf@process{\pgfpoint@intersect@end@a}}% + {\pgf@process{\pgfpoint@intersect@start@b}}{\pgf@process{\pgfpoint@intersect@end@b}}% +} + +\def\pgf@intersect@curve@and@curve{% + \pgf@intersectionofcurves% + {\pgf@process{\pgfpoint@intersect@start@a}}{\pgf@process{\pgfpoint@intersect@firstsupport@a}}% + {\pgf@process{\pgfpoint@intersect@secondsupport@a}}{\pgf@process{\pgfpoint@intersect@end@a}}% + {\pgf@process{\pgfpoint@intersect@start@b}}{\pgf@process{\pgfpoint@intersect@firstsupport@b}}% + {\pgf@process{\pgfpoint@intersect@secondsupport@b}}{\pgf@process{\pgfpoint@intersect@end@b}}% +} + + +\def\pgfintersectionoflines#1#2#3#4{% + \pgf@intersect@solutions=0\relax% + \pgf@intersectionoflines{#1}{#2}{#3}{#4}% +} + +\def\pgf@intersectionoflines#1#2#3#4{% + \pgf@iflinesintersect{#1}{#2}{#3}{#4}% + {% + \pgfextract@process\pgf@intersect@solution@candidate{% + \pgfpointintersectionoflines{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}% + {\pgfpoint@intersect@start@b}{\pgfpoint@intersect@end@b}% + }% + \pgf@ifsolution@duplicate{\pgf@intersect@solution@candidate}{% + % ah - we a duplicate. Apparently, we have a hit on an + % endpoint. + }{% + \global\advance\pgf@intersect@solutions by1\relax% + \expandafter\global\expandafter\let\csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=\pgf@intersect@solution@candidate + \ifpgf@intersect@sort% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}}% + \edef\pgf@marshal{% + \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% + }% + \pgf@marshal% + \let\pgf@intersect@length@a=\pgfmathresult% + \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}% + \edef\pgf@marshal{% + \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + }% + \pgf@marshal% + \pgfmathdivide@{\pgfmathresult}{\pgf@intersect@length@a}% + \pgf@x=\pgfmathresult pt\relax% + \advance\pgf@x by\pgf@intersect@time@offset pt\relax% + \edef\pgf@intersect@time@a{\pgfmath@tonumber{\pgf@x}}% + \expandafter\global\expandafter\let\csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname= + \pgf@intersect@time@a + \else + \let\pgf@intersect@time@a=\pgfutil@empty + \fi% + \let\pgf@intersect@time@b=\pgfutil@empty + \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% + }% + % + }{}% +} + +% Test if two lines L1 and L2 intersect. +% +% #1 - first point P1 on L1. +% #2 - second point P2 on L1. +% #3 - first point P3 on L2. +% #2 - second point P4 on L2. +% #5 - code executed if intersection occurs. +% #6 - code executed if intersection does no occur. +% +% Let L1 be represented by P1+(P2-P1)s where 0<=s<=1 +% Let L2 be represented by P3+(P4-P3)t where 0<=t<=1 +% +% Then L1 and L2 intersect at +% +% s = |x2-x1 x3-x1| / |x4-x3 x2-x1| +% |y2-y1 y3-y1| |y4-y3 y2-y1| +% +% t = |x4-x3 x3-x1| / |x4-x3 x2-x1| +% |y4-y3 y3-y1| |y4-y3 y2-y1| +% +% with 0<=s,t<=1 +% +% s and t do not need to be calculated: +% +% Let s = A / C and t = B / C +% +% Then 0<=s<=1 if !(C=0) && ((A=0) || ((A>0) && !(C<A)) || ((A<0) && !(C>A))) +% 0<=t<=1 if !(C=0) && ((B=0) || ((B>0) && !(C<B)) || ((B<0) && !(C>B))) +% +\newif\ifpgf@s +\newif\ifpgf@t +\def\pgfiflinesintersect#1#2#3#4{% + \begingroup% + \pgf@iflinesintersect{\pgf@process{#1}}{\pgf@process{#2}}{\pgf@process{#3}}{\pgf@process{#4}}% + {\aftergroup\pgfutil@firstoftwo}{\aftergroup\pgfutil@secondoftwo}% + \endgroup% +} + +\def\pgf@iflinesintersect#1#2#3#4{% + #4\relax% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + #3\relax% + \advance\pgf@xc by-\pgf@x% + \advance\pgf@yc by-\pgf@y% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + #2\relax% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + #1\relax% + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \advance\pgf@xb by-\pgf@x% + \advance\pgf@yb by-\pgf@y% + % + % xc = x4-x3; yc=y4-y3; + % xb = x3-x1; yb=y3-y1; + % xa = x2-x1; ya=y2-y1; + % + % + % Normalise a little. 16384 may not be a robust choice. + % + \c@pgf@counta=\pgf@xa\divide\c@pgf@counta by16384\relax% + \c@pgf@countb=\pgf@xb\divide\c@pgf@countb by16384\relax% + \c@pgf@countc=\pgf@ya\divide\c@pgf@countc by16384\relax% + \c@pgf@countd=\pgf@yb\divide\c@pgf@countd by16384\relax% + \multiply\c@pgf@counta by\c@pgf@countd% + \multiply\c@pgf@countc by\c@pgf@countb% + \advance\c@pgf@counta by-\c@pgf@countc% + \pgfutil@tempcnta=\c@pgf@counta% + % + \c@pgf@counta=\pgf@xc\divide\c@pgf@counta by16384\relax% + \c@pgf@countc=\pgf@yc\divide\c@pgf@countc by16384\relax% + \multiply\c@pgf@countd by\c@pgf@counta% + \multiply\c@pgf@countb by\c@pgf@countc% + \advance\c@pgf@countd by-\c@pgf@countb% + \pgfutil@tempcntb=\c@pgf@countd% + % + \c@pgf@countb=\pgf@xa\divide\c@pgf@countb by16384\relax% + \c@pgf@countd=\pgf@ya\divide\c@pgf@countd by16384\relax% + \multiply\c@pgf@counta by\c@pgf@countd% + \multiply\c@pgf@countc by\c@pgf@countb% + \advance\c@pgf@counta by-\c@pgf@countc% + % + \pgf@sfalse% + \pgf@tfalse% + \ifnum\c@pgf@counta=0\relax% + \else% + \ifnum\pgfutil@tempcnta=0\relax% + \pgf@strue% + \else% + \ifnum\pgfutil@tempcnta>0\relax% + \ifnum\c@pgf@counta<\pgfutil@tempcnta% + \else% + \pgf@strue% + \fi% + \else% + \ifnum\c@pgf@counta>\pgfutil@tempcnta% + \else% + \pgf@strue% + \fi% + \fi% + \fi% + \ifnum\pgfutil@tempcntb=0\relax% + \pgf@ttrue% + \else% + \ifnum\pgfutil@tempcntb>0\relax% + \ifnum\c@pgf@counta<\pgfutil@tempcntb% + \else% + \pgf@ttrue% + \fi% + \else% + \ifnum\c@pgf@counta>\pgfutil@tempcntb% + \else% + \pgf@ttrue% + \fi% + \fi% + \fi% + \fi% + \let\pgf@intersect@next=\pgfutil@secondoftwo% + \ifpgf@s% + \ifpgf@t% + \let\pgf@intersect@next=\pgfutil@firstoftwo% + \fi% + \fi% + \pgf@intersect@next% +} + + + + +\def\pgfintersectionoflineandcurve#1#2#3#4#5#6{% + \pgf@intersect@solutions=0\relax% + \pgf@intersectionoflineandcurve{#1}{#2}{#3}{#4}{#5}{#6}% +} + +\def\pgf@intersectionoflineandcurve#1#2#3#4#5#6{% + \pgf@intersectionofcurves% + {\pgf@process{#1}}% + {% + \pgf@process{% + \pgfpointadd{#1\relax\pgf@x=0.666666\pgf@x\pgf@y=0.666666\pgf@y}% + {#2\relax\pgf@x=0.333333\pgf@x\pgf@y=0.333333\pgf@y}% + }% + }% + {% + \pgf@process{% + \pgfpointadd{#1\relax\pgf@x=0.333333\pgf@x\pgf@y=0.333333\pgf@y}% + {#2\relax\pgf@x=0.666666\pgf@x\pgf@y=0.666666\pgf@y}% + }% + }% + {\pgf@process{#2}}% + {\pgf@process{#3}}% + {\pgf@process{#4}}% + {\pgf@process{#5}}% + {\pgf@process{#6}}% +}% + +\def\pgf@intersectionofcurveandline#1#2#3#4#5#6{% + \pgf@intersectionofcurves% + {\pgf@process{#1}}% + {\pgf@process{#2}}% + {\pgf@process{#3}}% + {\pgf@process{#4}}% + {\pgf@process{#5}}% + {% + \pgf@process{% + \pgfpointadd{#5\relax\pgf@x=0.666666\pgf@x\pgf@y=0.666666\pgf@y}% + {#6\relax\pgf@x=0.333333\pgf@x\pgf@y=0.333333\pgf@y}% + }% + }% + {% + \pgf@process{% + \pgfpointadd{#5\relax\pgf@x=0.333333\pgf@x\pgf@y=0.333333\pgf@y}% + {#6\relax\pgf@x=0.666666\pgf@x\pgf@y=0.666666\pgf@y}% + }% + }% + {\pgf@process{#6}}% +}% + + + + +\def\pgfintersectiontolerance{0.1pt} +\def\pgfintersectiontolerancefactor{0.1} + + + +% Find the intersections of two bezier curves. +% +% #1 - #4 = curve 1. +% #5 - #8 = curve 2. +% #9 = the solution number. +% +% There is no guarantee of ordering of solutions. If there are +% no solutions, the origin is returned. +% +\def\pgfpointintersectionofcurves#1#2#3#4#5#6#7#8#9{% + \pgf@intersect@solutions=0\relax% + \pgf@intersectionofcurves% + {\pgf@process{#1}}{\pgf@process{#2}}{\pgf@process{#3}}{\pgf@process{#4}}% + {\pgf@process{#5}}{\pgf@process{#6}}{\pgf@process{#7}}{\pgf@process{#8}}% + \pgfpointintersectionsolution{#9}% +} + +% Return any intersection points of two curves C1 and C2. +% No order can be guaranteed for the solutions. +% +% #1, #2, #3, #4 - the points on C1 +% #5, #6, #7, #8 - the points on C2 +% +% Returns: +% +% \pgf@intersect@solutions - the number of solutions. +% \pgfpointintersectionsolution{<S>} - the point for soultion S. +% +% (Sort of) use: +% +% intersection(C1,C2) +% S = {}; +% intersection'(C1,C2); +% return S; +% +% intersection'(C1,C2) +% B1 = boundingbox(C1); +% B2 = boundingbox(C2); +% if intersect(B1,B2) +% if (B1.width < q) and (B1.height < q) and +% (B2.width < q) and (B2.height < q) +% S = S + {average_of_all_points(B1,B2)}; \\ is there a better choice? +% else +% Q = subdivideLeft(C1); +% R = subdivideRight(C1); +% intersection'(C2,Q); +% intersection'(C2,R); +% +% where q is a small value (tolerance). +% +\def\pgfintersectionofcurves#1#2#3#4#5#6#7#8{% + \pgf@intersect@solutions=0\relax% + \pgf@intersectionofcurves% + {\pgf@process{#1}}{\pgf@process{#2}}{\pgf@process{#3}}{\pgf@process{#4}}% + {\pgf@process{#5}}{\pgf@process{#6}}{\pgf@process{#7}}{\pgf@process{#8}}% +}% +\def\pgf@intersectionofcurves#1#2#3#4#5#6#7#8{% + \begingroup% + \dimendef\pgf@time@a=2\relax% + \dimendef\pgf@time@aa=4\relax% + \dimendef\pgf@time@b=6\relax% + \dimendef\pgf@time@bb=8\relax% + \pgf@time@a=0pt\relax% + \pgf@time@aa=1pt\relax% + \pgf@time@b=0pt\relax% + \pgf@time@bb=1pt\relax% + \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@b% + \let\pgf@curve@subdivde@after=\pgf@@intersectionofcurves% + \pgf@@intersectionofcurves{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}% + \endgroup% +} + +\def\pgf@@intersectionofcurves#1#2#3#4#5#6#7#8{% + \pgf@intersect@boundingbox@reset% + \pgf@intersect@boundingbox@update{#1}% + \pgf@intersect@boundingbox@update{#2}% + \pgf@intersect@boundingbox@update{#3}% + \pgf@intersect@boundingbox@update{#4}% + % (\pgf@xa, \pgf@ya) is lower-left + % (\pgf@xb, \pgf@yb) is upper-right + \edef\pgf@intersect@boundingbox@b{% + \noexpand\pgf@x=\the\pgf@xa% + \noexpand\pgf@y=\the\pgf@ya% + \noexpand\pgf@xa=\the\pgf@xb% + \noexpand\pgf@ya=\the\pgf@yb% + }% + \pgf@intersect@boundingbox@reset% + \pgf@intersect@boundingbox@update{#5}% + \pgf@intersect@boundingbox@update{#6}% + \pgf@intersect@boundingbox@update{#7}% + \pgf@intersect@boundingbox@update{#8}% + \edef\pgf@intersect@boundingbox@a{% + \noexpand\pgf@xb=\the\pgf@xa% + \noexpand\pgf@yb=\the\pgf@ya% + \noexpand\pgf@xc=\the\pgf@xb% + \noexpand\pgf@yc=\the\pgf@yb% + }% + \pgf@intersect@boundingbox@a% + \pgf@intersect@boundingbox@b% + % check if the two bounding boxes overlap: + \ifdim\pgf@xa<\pgf@xb% + \else% + \ifdim\pgf@x>\pgf@xc% + \else% + \ifdim\pgf@ya<\pgf@yb% + \else% + \ifdim\pgf@y>\pgf@yc% + \else% + % compute DIFFERENCE vectors: + \advance\pgf@xc by-\pgf@xb% + \advance\pgf@yc by-\pgf@yb% + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \let\pgf@intersect@subdivde=\relax% + % check if both difference vectors are point wise + % less than tolerance (i.e. |v|_infty < eps ). + % That means that both bounding boxes are "small enough" + \ifdim\pgf@xc<\pgfintersectiontolerance\relax% + \ifdim\pgf@xa<\pgfintersectiontolerance\relax% + \ifdim\pgf@yc<\pgfintersectiontolerance\relax% + \ifdim\pgf@ya<\pgfintersectiontolerance\relax% + \pgfextract@process\pgf@intersect@solution@candidate{% + % set (x,y) = mean(the 4 points of the two bounding boxes): + \pgf@intersect@boundingbox@a% + \pgf@intersect@boundingbox@b% + \pgf@x=0.25\pgf@x% + \advance\pgf@x by0.25\pgf@xa% + \advance\pgf@x by0.25\pgf@xb% + \advance\pgf@x by0.25\pgf@xc% + \pgf@y=0.25\pgf@y% + \advance\pgf@y by0.25\pgf@ya% + \advance\pgf@y by0.25\pgf@yb% + \advance\pgf@y by0.25\pgf@yc% + }% + % We must avoid duplicate solutions. + \let\pgf@intersect@subdivde=\pgf@stop% + \pgf@ifsolution@duplicate\pgf@intersect@solution@candidate{}% + {% + \global\advance\pgf@intersect@solutions by1\relax% + \begingroup + \advance\pgf@time@a by\pgf@time@aa% + \divide\pgf@time@a by2\relax% + \advance\pgf@time@a by\pgf@intersect@time@offset pt\relax% + \edef\pgf@intersect@time@a{\pgfmath@tonumber{\pgf@time@a}}% + % + \advance\pgf@time@b by\pgf@time@bb% + \divide\pgf@time@b by2\relax% + \advance\pgf@time@b by\pgf@intersect@time@offset@b pt\relax% + \edef\pgf@intersect@time@b{\pgfmath@tonumber{\pgf@time@b}}% + % + \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% + \expandafter\global\expandafter\let% + \csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=% + \pgf@intersect@solution@candidate% + \ifpgf@intersect@sort% + \expandafter\xdef% + \csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname% + {\pgf@intersect@time@a}% + \fi% + \endgroup + }% + \fi% + \fi% + \fi% + \fi% + \ifx\pgf@intersect@subdivde\pgf@stop% + \else% + \pgf@intersect@subdivide@curve{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}% + \fi% + \fi% + \fi% + \fi% + \fi% +} + +\def\pgf@intersect@subdivide@curve@b#1#2#3#4#5#6#7#8{% + \begingroup% + \advance\pgf@time@bb by\pgf@time@b\relax% + \divide\pgf@time@bb by2\relax% + \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@a% + \pgf@curve@subdivide@left{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}% + \endgroup% + \begingroup% + \advance\pgf@time@b by\pgf@time@bb\relax% + \divide\pgf@time@b by2\relax% + \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@a% + \pgf@curve@subdivide@right{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}% + \endgroup% +} + +\def\pgf@intersect@subdivide@curve@a#1#2#3#4#5#6#7#8{% + \begingroup% + \advance\pgf@time@aa by\pgf@time@a\relax% + \divide\pgf@time@aa by2\relax% + \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@b% + \pgf@curve@subdivide@left{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}% + \endgroup% + \begingroup% + \advance\pgf@time@a by\pgf@time@aa\relax% + \divide\pgf@time@a by2\relax% + \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@b% + \pgf@curve@subdivide@right{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}% + \endgroup% +} + +\def\pgf@intersect@boundingbox@reset{% + \pgf@xa=16000pt\relax% + \pgf@ya=16000pt\relax% + \pgf@xb=-16000pt\relax% + \pgf@yb=-16000pt\relax% +} + +\def\pgf@intersect@boundingbox@update#1{% + #1\relax% + \ifdim\pgf@x<\pgf@xa\pgf@xa=\pgf@x\fi% + \ifdim\pgf@y<\pgf@ya\pgf@ya=\pgf@y\fi% + \ifdim\pgf@x>\pgf@xb\pgf@xb=\pgf@x\fi% + \ifdim\pgf@y>\pgf@yb\pgf@yb=\pgf@y\fi% +} + +% The following subroutines are part of a conversion from pgfbasic +% math to FPU. This transition is necessary due to the restricted +% accuracy of pgfbasic. In order to limit the error rate of the +% transition pgfbasic -> FPU, I chose to +% keep the old "pattern" of sorts \advance\pgf@xa by0.5\pgf@y etc and +% simply adapt to some FPU call. +% +% The following routines constitute the "adapter": + +\def\pgf@float@adapter@setxy{% + \pgfmathfloatparsenumber{\pgf@sys@tonumber\pgf@x}\let\pgf@fpu@x=\pgfmathresult + \pgfmathfloatparsenumber{\pgf@sys@tonumber\pgf@y}\let\pgf@fpu@y=\pgfmathresult +}% +\def\pgf@float@adapter@mult#1=#2*#3{% + \pgfmathfloatmultiplyfixed@{#3}{#2}% + \let#1=\pgfmathresult +}% +\def\pgf@float@adapter@advance#1by#2*#3{% + \pgfmathfloatmultiplyfixed@{#3}{#2}% + \let\pgfutil@temp=\pgfmathresult + \pgfmathfloatadd@{#1}{\pgfutil@temp}% + \let#1=\pgfmathresult +}% + +\def\pgf@float@adapter@tostring#1{% + \pgfmathfloattofixed{#1}\edef#1{\pgfmathresult pt }% +}% + +\def\pgf@curve@subdivide@left#1#2#3#4{% + % + % The left curve (from t=0 to t=.5) + % + \begingroup + #1\relax% + \pgfutil@tempdima=\pgf@x% + \pgfutil@tempdimb=\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@mult\pgf@fpu@xa=.5*\pgf@fpu@x \pgf@float@adapter@mult\pgf@fpu@ya=.5*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xb=.25*\pgf@fpu@x \pgf@float@adapter@mult\pgf@fpu@yb=.25*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xc=.125*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@yc=.125*\pgf@fpu@y% + #2\relax% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@fpu@xa by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.5*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xb by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.5*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xc by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.375*\pgf@fpu@y% + #3\relax% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@fpu@xb by.25*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.25*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xc by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.375*\pgf@fpu@y% + #4\relax% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@fpu@xc by.125*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.125*\pgf@fpu@y% + % + \pgf@float@adapter@tostring\pgf@fpu@xa + \pgf@float@adapter@tostring\pgf@fpu@ya + \pgf@float@adapter@tostring\pgf@fpu@xb + \pgf@float@adapter@tostring\pgf@fpu@yb + \pgf@float@adapter@tostring\pgf@fpu@xc + \pgf@float@adapter@tostring\pgf@fpu@yc + \edef\pgf@marshal{% + \noexpand\pgf@curve@subdivde@after% + {\noexpand\pgf@x=\the\pgfutil@tempdima\noexpand\pgf@y=\the\pgfutil@tempdimb}% + {\noexpand\pgf@x=\pgf@fpu@xa\noexpand\pgf@y=\pgf@fpu@ya}% + {\noexpand\pgf@x=\pgf@fpu@xb\noexpand\pgf@y=\pgf@fpu@yb} + {\noexpand\pgf@x=\pgf@fpu@xc\noexpand\pgf@y=\pgf@fpu@yc}% + }% + \expandafter + \endgroup + \pgf@marshal% +} + +\def\pgf@curve@subdivide@right#1#2#3#4{% + % + % The right curve (from t=0.5 to t=1) + % + \begingroup + #1\relax% + \pgf@float@adapter@setxy + \pgf@float@adapter@mult\pgf@float@tmpa=.125*\pgf@fpu@x\pgf@float@adapter@mult\pgf@float@tmpb=.125*\pgf@fpu@y% + #2\relax% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@float@tmpa by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.375*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xa=.25*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@ya=.25*\pgf@fpu@y% + #3\relax% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@float@tmpa by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.375*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xa by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.5*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xb=.5*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@yb=.5*\pgf@fpu@y% + #4\relax% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@float@tmpa by.125*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.125*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xa by.25*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.25*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xb by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.5*\pgf@fpu@y% + \let\pgf@fpu@xc=\pgf@fpu@x\let\pgf@fpu@yc=\pgf@fpu@y% + % + \pgf@float@adapter@tostring\pgf@float@tmpa + \pgf@float@adapter@tostring\pgf@float@tmpb + \pgf@float@adapter@tostring\pgf@fpu@xa + \pgf@float@adapter@tostring\pgf@fpu@ya + \pgf@float@adapter@tostring\pgf@fpu@xb + \pgf@float@adapter@tostring\pgf@fpu@yb + \pgf@float@adapter@tostring\pgf@fpu@xc + \pgf@float@adapter@tostring\pgf@fpu@yc + \edef\pgf@marshal{% + \noexpand\pgf@curve@subdivde@after% + {\noexpand\pgf@x=\pgf@float@tmpa\noexpand\pgf@y=\pgf@float@tmpb}% + {\noexpand\pgf@x=\pgf@fpu@xa\noexpand\pgf@y=\pgf@fpu@ya} + {\noexpand\pgf@x=\pgf@fpu@xb\noexpand\pgf@y=\pgf@fpu@yb} + {\noexpand\pgf@x=\pgf@fpu@xc\noexpand\pgf@y=\pgf@fpu@yc}% + }% + \expandafter + \endgroup + \pgf@marshal% +} + + +% A solution S1 is considered a duplicate of S2, if +% +% |x1 - x2|f < q and |y1 - y2|f < q +% +% where q is a small value (tolerance). +% +% #1 - the solution. +% +\def\pgf@ifsolution@duplicate#1{% + #1% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \let\pgf@intersect@next=\pgfutil@secondoftwo% + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@intersect@solutions\relax% + \else% + \pgf@ifsolution@duplicate@{\pgfmathcounter}% + \repeatpgfmathloop% + \pgf@intersect@next% +} + +\def\pgf@ifsolution@duplicate@#1{% + \pgf@process{\csname pgfpoint@g@intersect@solution@#1\endcsname}% + \advance\pgf@x by-\pgf@xa% + \advance\pgf@y by-\pgf@ya% + \ifdim\pgf@x<0pt\relax\pgf@x=-\pgf@x\fi% + \ifdim\pgf@y<0pt\relax\pgf@y=-\pgf@y\fi% + % + \pgf@x=\pgfintersectiontolerancefactor\pgf@x% + \pgf@y=\pgfintersectiontolerancefactor\pgf@y% + \ifdim\pgf@x<\pgfintersectiontolerance\relax% + \ifdim\pgf@y<\pgfintersectiontolerance\relax% + \let\pgf@intersect@next=\pgfutil@firstoftwo% + \fi% + \fi% +}% + +\newif\ifpgf@intersect@solutions@sortfinish + +% Sort solutions according to their time index. +% +\def\pgfintersectionsolutionsortbytime{% + \pgf@intersect@solutions@sortfinishtrue% + \pgfmathloop% + \ifnum\pgfmathcounter=\pgfintersectionsolutions\relax% + \else% + \pgfutil@tempcnta=\pgfmathcounter% + \advance\pgfutil@tempcnta by1\relax% + \ifdim\csname pgf@intersect@solution@\pgfmathcounter @time@a\endcsname pt>% + \csname pgf@intersect@solution@\the\pgfutil@tempcnta @time@a\endcsname pt\relax% + \pgf@intersect@solutions@sortfinishfalse% + % + \pgfintersectionsolutionsortbytime@swap{pgfpoint@intersect@solution@\pgfmathcounter}% + {pgfpoint@intersect@solution@\the\pgfutil@tempcnta}% + % + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@\pgfmathcounter @time@a}% + {pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}% + % + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@props@\pgfmathcounter}% + {pgf@intersect@solution@props@\the\pgfutil@tempcnta}% + \fi% + \repeatpgfmathloop% + \ifpgf@intersect@solutions@sortfinish% + \else% + \expandafter\pgfintersectionsolutionsortbytime% + \fi% +} + +\def\pgfintersectionsolutionsortbytime@swap#1#2{% + \pgfutil@namelet{pgf@intersect@temp}{#1}% + \pgfutil@namelet{#1}{#2}% + \pgfutil@namelet{#2}{pgf@intersect@temp}% +}% + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.code.tex index 94625bf7aee..9f620fb6f82 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.code.tex @@ -14,7 +14,7 @@ %%% - nested \input commands have been updated %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% Date of this copy: Di 25. Dez 18:14:20 CET 2012 %%% +%%% Date of this copy: Sa 7. Dez 20:58:23 CET 2013 %%% diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.pdflinks.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.pdflinks.code.tex index 933080daadd..6286e9cebb0 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.pdflinks.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.pdflinks.code.tex @@ -14,7 +14,7 @@ %%% - nested \input commands have been updated %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% Date of this copy: Di 25. Dez 18:14:20 CET 2012 %%% +%%% Date of this copy: Sa 7. Dez 20:58:23 CET 2013 %%% diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.prettyprinter.code.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.prettyprinter.code.tex index a2ab1d2fada..da95f766fee 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.prettyprinter.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfmanual.prettyprinter.code.tex @@ -14,7 +14,7 @@ %%% - nested \input commands have been updated %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% Date of this copy: Di 25. Dez 18:14:20 CET 2012 %%% +%%% Date of this copy: Sa 7. Dez 20:58:23 CET 2013 %%% diff --git a/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfutil-common-lists.tex b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfutil-common-lists.tex new file mode 100644 index 00000000000..a47bd4eb96a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsupp_pgfutil-common-lists.tex @@ -0,0 +1,179 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% This file is a copy of some part of PGF/Tikz. +%%% It has been copied here to provide : +%%% - compatibility with older PGF versions +%%% - availability of PGF contributions by Christian Feuersaenger +%%% which are necessary or helpful for pgfplots. +%%% +%%% For reasons of simplicity, I have copied the whole file, including own contributions AND +%%% PGF parts. The copyrights are as they appear in PGF. +%%% +%%% Note that pgfplots has compatible licenses. +%%% +%%% This copy has been modified in the following ways: +%%% - nested \input commands have been updated +%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% Date of this copy: Sa 7. Dez 20:58:23 CET 2013 %%% + + + +% Copyright 2013 by Christian Feuersaenger +% +% 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. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 +% +% This list here is a general re-implementation of the list used in +% the PGF system layer. +% It employs two collect-buffers to reduce the runtime. +% +% - It has preasymptotical runtime O(N), but is O(N^2) asymptotically. +% - It requires only 5 macros per list. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Usage: +% \pgfapplistnewempty\macro +\def\pgfapplistnewempty#1{% + \expandafter\let\csname pgfapp@#1\endcsname=\pgfutil@empty + \expandafter\let\csname pgfapp@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\let\csname pgfapp@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#1@smallbuf@c\endcsname{0}% + \expandafter\def\csname pgfapp@#1@bigbuf@c\endcsname{0}% +}% + +% #1: the item to append +% #2: the list as macro name +\long\def\pgfapplistpushback#1\to#2{% + \begingroup + \c@pgf@counta=\csname pgfapp@#2@smallbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfapp@#2@smallbuf@c\endcsname=\pgf@glob@TMPa + \ifnum\csname pgfapp@#2@smallbuf@c\endcsname<40 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}% + \expandafter\edef\csname pgfapp@#2@smallbuf\endcsname{\the\t@pgf@toka}% + \else + \pgfapplistpushback@smallbufoverfl{#1}{#2}% + \fi +}% +\long\def\pgfapplistpushback@smallbufoverfl#1#2{% + \begingroup + \c@pgf@counta=\csname pgfapp@#2@bigbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfapp@#2@bigbuf@c\endcsname=\pgf@glob@TMPa + % + \ifnum\csname pgfapp@#2@bigbuf@c\endcsname<30 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2@bigbuf\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}% + \expandafter\edef\csname pgfapp@#2@bigbuf\endcsname{\the\t@pgf@toka\the\t@pgf@tokb}% + \expandafter\let\csname pgfapp@#2@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#2@smallbuf@c\endcsname{0}% + \else% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#2@bigbuf\endcsname}% + \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}% + \expandafter\edef\csname pgfapp@#2\endcsname{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}% + \expandafter\let\csname pgfapp@#2@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#2@smallbuf@c\endcsname{0}% + \expandafter\let\csname pgfapp@#2@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#2@bigbuf@c\endcsname{0}% + \fi% +}% +\def\pgfapplist@flushbuffers#1{% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#1\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#1@bigbuf\endcsname}% + \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfapp@#1@smallbuf\endcsname}% + \expandafter\edef\csname pgfapp@#1\endcsname{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}% + \expandafter\let\csname pgfapp@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#1@smallbuf@c\endcsname{0}% + \expandafter\let\csname pgfapp@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#1@bigbuf@c\endcsname{0}% +}% + +\def\pgfapplistlet#1=#2{% + \pgfapplist@flushbuffers{#2}% + \expandafter\let\expandafter#1\csname pgfapp@#2\endcsname +}% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% A variant of applist which has the same runtime requirements, but +% does PUSH FRONT only. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% Usage: +% \pgfprependlistnewempty{list} +\def\pgfprependlistnewempty#1{% + \expandafter\let\csname pgfpPRP@#1\endcsname=\pgfutil@empty + \expandafter\let\csname pgfpPRP@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\let\csname pgfpPRP@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#1@smallbuf@c\endcsname{0}% + \expandafter\def\csname pgfpPRP@#1@bigbuf@c\endcsname{0}% +}% + +% #1: the item to append +% #2: the list as macro name +\long\def\pgfprependlistpushfront#1\to#2{% + \begingroup + \c@pgf@counta=\csname pgfpPRP@#2@smallbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfpPRP@#2@smallbuf@c\endcsname=\pgf@glob@TMPa + \ifnum\csname pgfpPRP@#2@smallbuf@c\endcsname<40 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@smallbuf\endcsname}% + \t@pgf@tokb={#1}% + \expandafter\edef\csname pgfpPRP@#2@smallbuf\endcsname{\the\t@pgf@tokb\the\t@pgf@toka}% + \else + \pgfprependlistpushfront@smallbufoverfl{#1}{#2}% + \fi +}% +\long\def\pgfprependlistpushfront@smallbufoverfl#1#2{% + \begingroup + \c@pgf@counta=\csname pgfpPRP@#2@bigbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfpPRP@#2@bigbuf@c\endcsname=\pgf@glob@TMPa + % + \ifnum\csname pgfpPRP@#2@bigbuf@c\endcsname<30 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@bigbuf\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@smallbuf\endcsname}% + \t@pgf@tokc={#1}% + \expandafter\edef\csname pgfpPRP@#2@bigbuf\endcsname{\the\t@pgf@tokc\the\t@pgf@tokb\the\t@pgf@toka}% + \expandafter\let\csname pgfpPRP@#2@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#2@smallbuf@c\endcsname{0}% + \else% + \pgfprependlist@flushbuffers{#2}% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2\endcsname}% + \t@pgf@tokb={#1}% + \expandafter\edef\csname pgfpPRP@#2\endcsname{\the\t@pgf@tokb\the\t@pgf@toka}% + \fi% +}% +\def\pgfprependlist@flushbuffers#1{% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1@bigbuf\endcsname}% + \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1@smallbuf\endcsname}% + \expandafter\edef\csname pgfpPRP@#1\endcsname{\the\t@pgf@tokc\the\t@pgf@tokb\the\t@pgf@toka}% + \expandafter\let\csname pgfpPRP@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#1@smallbuf@c\endcsname{0}% + \expandafter\let\csname pgfpPRP@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#1@bigbuf@c\endcsname{0}% +}% +\def\pgfprependlistlet#1=#2{% + \pgfprependlist@flushbuffers{#2}% + \expandafter\let\expandafter#1\csname pgfpPRP@#2\endcsname +}% diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/pgflibraryfillbetween.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/pgflibraryfillbetween.code.tex new file mode 100644 index 00000000000..bf2ebd6b64d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/pgflibraryfillbetween.code.tex @@ -0,0 +1,1067 @@ +% Copyright 2013 by Christian Feuersaenger +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\usepgflibrary{intersections} +% FIXME : ARCHITECTURE VIOLATION: REQUIRES +% \usetikzlibrary{decorations.softclip} +% +%\usepgfmodule{decorations} + +\newif\ifpgfpathfillbetween@split + +\pgfkeys{% + /pgf/fill between/reverse/.is choice, + /pgf/fill between/reverse/.default=true, + /pgf/fill between/reverse/false/.code=\def\pgfpathfillbetween@reverse@mode{0},% + /pgf/fill between/reverse/true/.code=\def\pgfpathfillbetween@reverse@mode{1},% + % + % checks the coordinates of the first two path instructions as heuristics: + /pgf/fill between/reverse/auto/.code=\def\pgfpathfillbetween@reverse@mode{2},% + /pgf/fill between/reverse/auto, + /pgf/fill between/inner moveto/.is choice, + /pgf/fill between/inner moveto/connect/.code=\def\pgfpathfillbetween@inner@moveto{1}, + /pgf/fill between/inner moveto/keep/.code=\def\pgfpathfillbetween@inner@moveto{2}, + /pgf/fill between/inner moveto/connect, + % + % split=true allows to generate individual result paths for every + % region induced by the intersection points. Example: + % "color positive region in red and negative region in green". + % The case split=false results in just one output path + % (simpler+faster, but of course less powerful). + /pgf/fill between/split/.is if=pgfpathfillbetween@split, + /pgf/fill between/split/.default=true, + % + % Used to report results. This is mainly useful in conjunction + % with split=true: each result segment will be streamed. + % + % Results are reported in the sequence + % begin + % next ready + % next ready + % ... + % end + % + % 'begin' has no arguments. + /pgf/fill between/result stream/begin/.code=,% + % + % 'next ready' has macro arguments, but the macro \pgfretval + % contains the lowlevel path as result (i.e. you can write + % \pgfsetpath\pgfretval to activate it). + /pgf/fill between/result stream/next ready/.code={ + \pgfaddpathandBB{\pgfretval}% + },% + % + % 'end' has no arguments. + /pgf/fill between/result stream/end/.code=,% +}% + +% \pgfpathfillbetween[<options>]{<first path>}{<second path>} +% +% Generates a new path consisting of the "fill between" of the two arguments. +% #1: optional arguments with /pgf/fill between prefix +% #2: a macro containing the first path. More precisely, it is supposed to be a return value of \pgfgetpath. +% #3: a macro containing the second path (in a format understood by \pgfsetpath). It is supposed to be a return value of \pgfgetpath. +\def\pgfpathfillbetween{\pgfutil@ifnextchar[{\pgfpathfillbetween@opt}{\pgfpathfillbetween@opt[]}}% +\def\pgfpathfillbetween@opt[#1]#2#3{% + \begingroup + \pgfqkeys{/pgf/fill between}{#1}% + % + % remove any special round-corner-tokens: + \pgfprocessround{#2}{#2}% + \pgfprocessround{#3}{#3}% + % + \if1\pgfpathfillbetween@inner@moveto + % inner moveto=connect: + \pgfpathfillbetween@connect@inner@movetos#2% + \pgfpathfillbetween@connect@inner@movetos#3% + \fi + % + \if2\pgfpathfillbetween@reverse@mode + % reverse=auto + \expandafter\pgfpathfillbetween@heuristics@get@direction#2\pgf@stop + \let\pgfpath@filled@dir@first=\pgfretval + \expandafter\pgfpathfillbetween@heuristics@get@direction#3\pgf@stop + \let\pgfpath@filled@dir@second=\pgfretval + % + \ifx\pgfpath@filled@dir@first\pgfpath@filled@dir@second + % Ok, they (seem to) have the same direction. Reverse one of them: + \def\pgfpathfillbetween@reverse@mode{1}% + \else + \def\pgfpathfillbetween@reverse@mode{0}% + \fi + \fi + % + % softclip, if configured (no-op otherwise): + \pgfpathcomputesoftclippath{#2}{\pgfpathfillbetween@softclip@A}\let#2=\pgfretval% + \pgfpathcomputesoftclippath{#3}{\pgfpathfillbetween@softclip@B}\let#3=\pgfretval% + % + \ifx#2\pgfutil@empty + \pgfpathfillbetween@warning{first}% + \else + \ifx#3\pgfutil@empty + \pgfpathfillbetween@warning{second}% + \else + \pgfpathfillbetween@invoke{result stream/begin}% + % + \ifpgfpathfillbetween@split + \pgfpathfillbetween@compute@splitted{#2}{#3}% + \else + \pgfpathfillbetween@compute{#2}{#3}% + \pgfpathfillbetween@invoke{result stream/next ready}% + \fi + \pgfpathfillbetween@invoke{result stream/end}% + \fi + \fi + % + % + \endgroup +}% + +\def\pgfpathfillbetween@warning#1{% + \pgfwarning{fill between skipped: the #1 input path is empty.}% +}% + +% Replaces all 'moveto' operations inside of the soft path '#1' by +% 'lineto'. This excludes the first moveto. +% +% The motivation is that fillbetween should ignore inner movetos. +\def\pgfpathfillbetween@connect@inner@movetos#1{% + \expandafter\pgfpathfillbetween@connect@inner@movetos@#1\pgf@stop% + \let#1=\pgfretval +} +\def\pgfpathfillbetween@connect@inner@movetos@#1#2\pgf@stop{% + \ifx#1\pgfsyssoftpath@movetotoken + \pgfutilstrreplace{\pgfsyssoftpath@movetotoken}{\pgfsyssoftpath@linetotoken}{#2}% + \expandafter\def\expandafter\pgfretval\expandafter{\expandafter\pgfsyssoftpath@movetotoken\pgfretval}% + \else + \pgfutilstrreplace{\pgfsyssoftpath@movetotoken}{\pgfsyssoftpath@linetotoken}{#1#2}% + \fi +}% + +\def\pgfpathfillbetween@invoke#1{\pgfkeysvalueof{/pgf/fill between/#1/.@cmd}\pgfeov} + +\def\pgfpathfillbetween@replace@first@moveto#1#2\pgf@stop{% + \ifx#1\pgfsyssoftpath@movetotoken + \def\pgfretval{\pgfsyssoftpath@linetotoken #2}% + \else + \def\pgfretval{#1#2}% + \fi +}% + +\def\pgfpathfillbetween@compute@splitted#1#2{% + % 0. normalize path sequences. + % ATTENTION : there are implicit assumptions on the INTERNAL ORDER of the two paths! + % This implementation needs to loop over them synchronously, i.e. it processes + % the 0.th segment of a and the 0th of b, + % the 1.th segment of a and the 1th of b, + % and so on. Here, "i th segment" implies a sort order in ascending x direction. + % This is, however, a weakness of \pgfintersectionofpaths - it does not really support this kind of sorting. + % + % I work around this by restricting the implementation to the "common use-cases", i.e. to two plots of functions which do not intersect themselves (i.e. to "functions" in the original sense). This will probably (almost surely) fail for parametric functions or circles. + % + \if0\pgfpathfillbetween@reverse@mode + % reverse=false + % + % This means one plot is in direction '+' and one in '-', i.e. + % a: x ---> x ---> x + % b: x <--- x <--- x + % + % However, we have the implicit assumption that both paths can be processed synchronously, i.e. that they have the SAME direction. + % To this end, we have to reverse one of them here (since \pgfintersectionofpaths does not automatically sort results in a suitable way): + % + \pgf@reverse@path{#2}% + \let#2=\pgfretval + % + % However, we need to re-reverse the individual segments later-on... + % So: set 'reverse=true'. Will be respected when assembling the splitted segments... + \def\pgfpathfillbetween@reverse@mode{1}% + \fi + % + % 1. compute intersection points: + \pgf@intersect@sort@by@second@pathfalse + % + % FIXME : do we want to sort by time!? That might be needed for curvetos ... ? + \pgf@intersect@sortfalse + \pgfintersectionofpaths% + {% + \pgfsetpath#1% + }% + {% + \pgfsetpath#2% + }% + % + % FIXME : computing the intersections is fine... but it would be + % even finer to report the resulting points back to tikz! + % -> call the *tikz* intersection lib through some sort of callback!? + % + % 2. split the first involved path into the + % segments induced by the intersection points: + \pgfcomputeintersectionsegments{1}% + \let\pgfpathfilled@a@segments=\pgfretval +% + % 2. split the second involved path into the + % segments induced by the intersection points: + \pgfcomputeintersectionsegments{2}% + \let\pgfpathfilled@b@segments=\pgfretval + % + \ifnum\pgfpathfilled@a@segments=\pgfpathfilled@b@segments\relax + \else + \pgferror{Illegal internal state encountered: the number segments induced by the intersection points of the two paths DIFFER between the first and the second path: first path has \pgfpathfilled@a@segments\space whereas the second has \pgfpathfilled@b@segments.}% + \fi + % + % Recombine the pairs of segments (a_i, b_i), i = 0,..., N-1 in a + % filled way: + \def\c@pgfpathfilled@counter{0}% + \pgfmathloop + \ifnum\c@pgfpathfilled@counter<\pgfpathfilled@a@segments\relax + \expandafter\let\expandafter\pgf@loc@path@a\csname pgf@intersect@path@split@a@\c@pgfpathfilled@counter\endcsname + \expandafter\let\expandafter\pgf@loc@path@b\csname pgf@intersect@path@split@b@\c@pgfpathfilled@counter\endcsname + % + \pgfpathfillbetween@compute{\pgf@loc@path@a}{\pgf@loc@path@b}% + % report to the result stream. It knows how to deal with it: + \pgfpathfillbetween@invoke{result stream/next ready}% + % + \pgfutil@advancestringcounter\c@pgfpathfilled@counter + \repeatpgfmathloop +} + +\def\pgfpathfillbetween@compute#1#2{% +%\message{Combination of ^^J \meaning#1\space and ^^J \meaning#2...^^J}% + % + \if1\pgfpathfillbetween@reverse@mode + % reverse=true + % + % Ok, then reverse one of the paths. We choose the second one as that is easier to debug. + % FIXME : might make sense to determine which one is shorter... + \pgf@reverse@path{#2}% + \let#2=\pgfretval + \fi + % + % FIXME: what should I do if I have closed paths!? What is the + % expected behavior!? I know that the combination of two closed + % paths should probably be used as is, perhaps with even-odd-rule. + % This here should do the job. + % + % NOTE: I believe the 'split' fails to work with closed paths. + \pgfpathfillbetween@contains@closepathtoken{#1}% + \let\b@pgfpathfillbetween@contains@close@a=\pgfretval + \pgfpathfillbetween@contains@closepathtoken{#2}% + \let\b@pgfpathfillbetween@contains@close@b=\pgfretval + % + \def\b@pgfpathfillbetween@contains@close{0}% + \if1\b@pgfpathfillbetween@contains@close@b + \def\b@pgfpathfillbetween@contains@close{1}% + \fi + \if1\b@pgfpathfillbetween@contains@close@a + \def\b@pgfpathfillbetween@contains@close{1}% + \fi + % + \if0\b@pgfpathfillbetween@contains@close@b + \expandafter\pgfpathfillbetween@replace@first@moveto#2\pgf@stop + \let#2=\pgfretval + \fi + % + \t@pgf@toka=\expandafter{#1}% + \t@pgf@tokb=\expandafter{#2}% + % + \if0\b@pgfpathfillbetween@contains@close + % we need to close the resulting combined path, otherwise decorations will look strange: + \expandafter\pgfpathfillbetween@get@first@coord#1\pgf@stop + \t@pgf@tokc=\expandafter{\expandafter\pgfsyssoftpath@closepathtoken\pgfretval}% + \else + \t@pgf@tokc={}% + \fi + % + \edef\pgfretval{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}% + % +%\message{^^J = \meaning\pgfretval^^J}% + % that's it. +} + +% #1 a macro containing a softpath +% OUTPUT: +% \pgfretval = 1 if the path contains \pgfsyssoftpath@closepathtoken +% and 0 otherwise. +\def\pgfpathfillbetween@contains@closepathtoken#1{% + \expandafter\pgfutil@in@\expandafter\pgfsyssoftpath@closepathtoken\expandafter{#1}% + \ifpgfutil@in@ + \def\pgfretval{1}% + \else + \def\pgfretval{0}% + \fi +} + +\def\pgfpathfillbetween@get@first@coord#1#2#3#4\pgf@stop{% + \def\pgfretval{{#2}{#3}}% +}% + +% A utility function like \pgfsetpath which calls \pgfsetpath *and* protocols +% the size of each path segment (i.e. compute the bounding box). +% +% #1 a macro containing a softpath (i.e. something returned by +% \pgfgetpath) +\def\pgfsetpathandBB#1{% + \expandafter\pgfsetpath@protocolsizes@loop#1\pgf@stop + % + \pgfsetpath{#1}% +}% + +% Like \pgfsetpathandBB, but this here *appends* to the existing +% softpath. +% +% #1 a macro containing a softpath (i.e. something returned by +% \pgfgetpath) +\def\pgfaddpathandBB#1{% + \expandafter\pgfsetpath@protocolsizes@loop#1\pgf@stop + \pgfaddpath#1% +} + +% Like \pgfsetpath, but this here *appends* to the existing +% softpath. +% +% #1 a macro containing a softpath (i.e. something returned by +% \pgfgetpath) +\def\pgfaddpath#1{% + % append to any previous path elements: + \pgfgetpath\pgf@temp + \t@pgf@tokc=\expandafter{\pgf@temp}% + \t@pgf@toka=\expandafter{#1}% + \edef\pgfretval{\the\t@pgf@tokc\the\t@pgf@toka}% + \pgfsetpath{\pgfretval}% +} + +% Takes a softpath on input, replaces its first moveto by a lineto, +% and returns it as softpath. +% #1: a macro containing a softpath (i.e. the result of \pgfgetpath) +% +% On output, \pgfretval contains a modified path. +\def\pgfpathreplacefirstmoveto#1{% + \ifx#1\pgfutil@empty + \let\pgfretval=#1% + \else + \expandafter\pgfpathfillbetween@replace@first@moveto#1\pgf@stop + \fi +} + +% Defines \pgfretval to be '+' if the path's direction is "ascending" +% and "-" otherwise. +% +% Here, "ascending" means that its first two coordinates have +% ascending X coordinates. If the X coordinates are equal, the Y +% coordinates are used instead. +\def\pgfpathfillbetween@heuristics@get@direction#1#2#3{% + \pgfutil@ifnextchar\pgf@stop{% + % wow. it has just one path element... we can do nothing. + \def\pgfretval{+}% + \pgfutil@gobble + }{% + \pgfpathfillbetween@heuristics@get@direction@{#1}{#2}{#3}% + }% +}% + +% example: \pgfsyssoftpath@movetotoken{#2}{#3}\pgfsyssoftpath@linetotoken{#5}{#6}#7\pgf@stop +% example: +% \pgfsyssoftpath@movetotoken{#2}{#3} +% \pgfsyssoftpath@curvetosupportatoken{<x>}{<y>} +% \pgfsyssoftpath@curvetosupportbtoken{<x>}{<y>} +% \pgfsyssoftpath@curvetotoken{<x>}{<y>}\pgf@stop +\def\pgfpathfillbetween@heuristics@get@direction@#1#2#3#4#5#6#7\pgf@stop{% + \def\pgf@temp{#4}% + \def\pgf@tempb{\pgfsyssoftpath@curvetosupportatoken}% + \ifx\pgf@temp\pgf@tempb + % Ah - a curveto! Use the end-point for the heuristics. + \pgfpathfillbetween@heuristics@get@direction@curveto #1{#2}{#3}#4{#5}{#6}#7\pgf@stop + \else + % Ok, assume it is line to (or its variants): + \pgfpathfillbetween@heuristics@get@direction@@{#2}{#3}{#5}{#6}% + \fi +}% + +\def\pgfpathfillbetween@heuristics@get@direction@curveto#1#2#3\pgfsyssoftpath@curvetosupportatoken#4\pgfsyssoftpath@curvetotoken#5#6#7\pgf@stop{% + \pgfpathfillbetween@heuristics@get@direction@@{#2}{#3}{#5}{#6}% +}% + +% #1: x1 +% #2: y1 +% #3: x2 +% #4: y2 +\def\pgfpathfillbetween@heuristics@get@direction@@#1#2#3#4{% + \edef\pgfretval{% + \ifdim #1<#3\space + +% + \else + \ifdim #1=#3\space + \ifdim #2<#4\space + +% + \else + -% + \fi + \else + -% + \fi + \fi + }% +} + +\def\pgfsetpath@protocolsizes@loop#1{% + \ifx#1\pgf@stop% + \let\pgfsetpathBB@protocolsizesnext=\relax% + \else% + \ifx#1\pgfsyssoftpath@movetotoken% + \let\pgfsetpathBB@protocolsizesnext=\pgfsetpathBB@protocolsizestoken@simple% + \else% + \ifx#1\pgfsyssoftpath@linetotoken% + \let\pgfsetpathBB@protocolsizesnext=\pgfsetpathBB@protocolsizestoken@simple% + \else% + \ifx#1\pgfsyssoftpath@closepathtoken% + \let\pgfsetpathBB@protocolsizesnext=\pgfsetpathBB@protocolsizestoken@simple% + \else% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \let\pgfsetpathBB@protocolsizesnext=\pgfsetpathBB@protocolsizestoken@curveto% + \else% + \ifx#1\pgfsyssoftpath@rectcornertoken% + \let\pgfsetpathBB@protocolsizesnext=\pgfsetpathBB@protocolsizestoken@rect% + \fi% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgfsetpathBB@protocolsizesnext} + +\def\pgfsetpathBB@protocolsizestoken@simple#1#2{% + \pgf@protocolsizes{#1}{#2}% + \pgfsetpath@protocolsizes@loop% +} + +\def\pgfsetpathBB@protocolsizestoken@curveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{% + \pgf@protocolsizes{#1}{#2}% + \pgf@protocolsizes{#3}{#4}% + \pgf@protocolsizes{#5}{#6}% + \pgfsetpath@protocolsizes@loop +} + +\def\pgfsetpathBB@protocolsizestoken@rect#1#2\pgfsyssoftpath@rectsizetoken#3#4{% + \pgf@protocolsizes{#1}{#2}% + \pgf@xa=#1\relax% + \advance\pgf@xa by#3\relax% + \pgf@ya=#2\relax% + \advance\pgf@ya by#4\relax% + \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \pgfsetpath@protocolsizes@loop +}% + +% Defines \pgfretval to be the reversed path of #1. +% +% #1 is supposed to be a macro containing a path without rounding specials (i.e. a result +% of \pgfprocessround) +\def\pgfcomputereversepath#1{% + % unfortunately, this is already used by internal macros... + \pgf@reverse@path#1% +}% +\def\pgf@reverse@path#1{% + % ATTENTION: this here is a special implementation which + % operates directly on softpaths. It does not make use of \pgf@decorate@inputsegmentobjects@reverse (reverse path decoration) + % because (a) decorations require their own special format and (b) + % this implementation is faster (both with respect to runtime asymptotics and runtime constant). + \def\pgf@reverse@first@type{}% + \def\pgf@reverse@last@pt{}% + \def\b@pgf@reversepath@last@is@close{0}% + \pgfprependlistnewempty{pgfretval}% + \let\pgfreverse@iterate=\pgfreverse@checkfirst@then + \expandafter\pgf@reverse@loop#1\pgf@stop + % + \if 0\b@pgf@reversepath@last@is@close% + \expandafter\pgfreverse@prepend@last\expandafter{\pgf@reverse@first@type}{x}{x}% + \else + % as soon as a closepathtoken is encountered, the associated + % moveto is processed right away. + % + % FIXME : I doubt that the implementation works if more than + % one closepathtoken is in here ... + \fi + \pgfprependlistlet\pgfretval={pgfretval}% + % +}% + +\def\pgf@reverse@loop#1{% + \ifx#1\pgf@stop% + \let\pgfreverse@next=\relax% + \else% + \def\b@pgf@reversepath@last@is@close{0}% + \ifx#1\pgfsyssoftpath@movetotoken% + \let\pgfreverse@next=\pgfreverse@token@moveto% + \else% + \ifx#1\pgfsyssoftpath@linetotoken% + \let\pgfreverse@next=\pgfreverse@token@lineto% + \else% + \ifx#1\pgfsyssoftpath@closepathtoken% + \let\pgfreverse@next=\pgfreverse@token@close% + \else% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \let\pgfreverse@next=\pgfreverse@token@curveto% + \else% + \ifx#1\pgfsyssoftpath@rectcornertoken% + \let\pgfreverse@next=\pgfreverse@token@rect% + \fi% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgfreverse@next} + +\def\pgfreverse@checkfirst@then#1{% + \def\pgf@reverse@first@type{#1}% + \let\pgfreverse@iterate=\pgfutil@gobble +}% + +\def\pgfreverse@prepend@last#1#2#3{% + \ifx\pgf@reverse@last@pt\pgfutil@empty + \else + \t@pgf@toka={#1}% + \t@pgf@tokb=\expandafter{\pgf@reverse@last@pt}% + \edef\pgf@marshal{\the\t@pgf@toka\the\t@pgf@tokb}% + \expandafter\pgfprependlistpushfront\pgf@marshal\to{pgfretval}% + \fi + \def\pgf@reverse@last@pt{{#2}{#3}}% +}% + +\def\pgfreverse@token@moveto#1#2{% + \pgfreverse@iterate{\pgfsyssoftpath@movetotoken}% + \pgfreverse@prepend@last\pgfsyssoftpath@movetotoken{#1}{#2}% + \pgf@reverse@loop% +} + +\def\pgfreverse@token@lineto#1#2{% + \pgfreverse@iterate{\pgfsyssoftpath@linetotoken}% + \pgfreverse@prepend@last\pgfsyssoftpath@linetotoken{#1}{#2}% + \pgf@reverse@loop +} +\def\pgfreverse@token@close#1#2{% + % close tokens are complicated: they always correspond to the most + % recent moveto token. + % + % First: remember that the last encountered token was 'close': if + % this is the lastmost token, we must not insert a final moveto. + \def\b@pgf@reversepath@last@is@close{1}% + % + % Second: *append* + % \pgfsyssoftpath@closepathtoken{<lastx>}{<lasty>}. + % + % Appending is unsupported by the prepend-list, so we have to + % terminate it, append, and reinitialize it with the result: + \pgfprependlistlet\pgfretval={pgfretval}% + \t@pgf@toka=\expandafter{\pgfretval}% + \t@pgf@tokb={\pgfsyssoftpath@closepathtoken}% + \t@pgf@tokc=\expandafter{\pgf@reverse@last@pt}% + \edef\pgf@marshal{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}% + % + % ... create a new list with the result: + \pgfprependlistnewempty{pgfretval}% + \expandafter\pgfprependlistpushfront\pgf@marshal\to{pgfretval}% + % + % and prepend a moveto. + \pgfreverse@prepend@last\pgfsyssoftpath@movetotoken{#1}{#2}% + % + \pgf@reverse@loop +} + +\def\pgfreverse@token@curveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{% + \pgfreverse@iterate{\pgfsyssoftpath@curvetosupportatoken{#1}{#2}\pgfsyssoftpath@curvetosupportbtoken{#3}{#4}\pgfsyssoftpath@curvetotoken}% + \pgfreverse@prepend@last{\pgfsyssoftpath@curvetosupportatoken{#3}{#4}\pgfsyssoftpath@curvetosupportbtoken{#1}{#2}\pgfsyssoftpath@curvetotoken}{#5}{#6}% + \pgf@reverse@loop +} + +\def\pgfreverse@token@rect#1#2\pgfsyssoftpath@rectsizetoken#3#4{% + % FIXME: UNTESTED + \pgf@xa=#1\relax% + \advance\pgf@xa by#3\relax% + \pgf@ya=#2\relax% + \advance\pgf@ya by#4\relax% + \edef\pgf@marshal{% + \noexpand\pgfsyssoftpath@movetotoken + {% + {#1}{#2}% + \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@xa}{#2}% + \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@linetotoken{#1}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@closepathtoken{#1}{#2}% + }% + }% + \pgfreverse@iterate\pgfsyssoftpath@movetotoken + \edef\pgf@reverse@last@pt{{#1}{#2}}% + \expandafter\pgf@reverse@loop\pgf@marshal% +} + +% ---------------------------------------- +% Given that some intersections have been computed already (and are in +% the current scope), this command computes the intersection segments +% for one of the input arguments. +% +% On output, \pgfretval contains the number of computed segments. The +% segments as such can be accessed via \pgfgetintersectionsegmentpath. +% +% #1 : should be '1' if the FIRST argument of +% \pgfintersectionofpaths should be used and '2' the SECOND +% argument of \pgfintersectionofpaths should be used on input. +% +% EXAMPLE: +% +% \def\inputValue{% +% \pgfsyssoftpath@movetotoken {56.90549pt}{0.0pt}% +% \pgfsyssoftpath@linetotoken {85.35823pt}{28.45274pt}% +% \pgfsyssoftpath@linetotoken {113.81097pt}{0.0pt}% +% \pgfsyssoftpath@linetotoken {142.26372pt}{28.45274pt}% +% \pgfsyssoftpath@linetotoken {170.71646pt}{0.0pt}% +% } +% +% \pgfpointintersectionsolution{1}% +% \pgfplotsassertequalstok{\the\pgf@x, \the\pgf@y}{71.13918pt, 14.2278pt}{solution 1} +% \pgfpointintersectionsolution{2}% +% \pgfplotsassertequalstok{\the\pgf@x, \the\pgf@y}{99.59497pt, 14.2278pt}{solution 2} +% \pgfpointintersectionsolution{3}% +% \pgfplotsassertequalstok{\the\pgf@x, \the\pgf@y}{128.05057pt, 14.2278pt}{solution 3} +% \pgfpointintersectionsolution{4}% +% \pgfplotsassertequalstok{\the\pgf@x, \the\pgf@y}{156.50636pt, 14.2278pt}{solution 4} +% +% +% \pgfcomputeintersectionsegments{1}% +% +% \message{OUTPUT: \meaning\pgfretval^^J}% +% \expandafter\def\csname expected@a@0\endcsname{% +% \pgfsyssoftpath@movetotoken {56.90549pt}{0.0pt}% +% \pgfsyssoftpath@linetotoken{71.13918pt}{14.2278pt}% +% } +% \expandafter\def\csname expected@a@1\endcsname{% +% \pgfsyssoftpath@movetotoken{71.13918pt}{14.2278pt}% +% \pgfsyssoftpath@linetotoken {85.35823pt}{28.45274pt}% +% \pgfsyssoftpath@linetotoken{99.59497pt}{14.2278pt}% +% } +% \expandafter\def\csname expected@a@2\endcsname{% +% \pgfsyssoftpath@movetotoken{99.59497pt}{14.2278pt}% +% \pgfsyssoftpath@linetotoken {113.81097pt}{0.0pt}% +% \pgfsyssoftpath@linetotoken{128.05057pt}{14.2278pt}% +% } +% \expandafter\def\csname expected@a@3\endcsname{% +% \pgfsyssoftpath@movetotoken{128.05057pt}{14.2278pt}% +% \pgfsyssoftpath@linetotoken {142.26372pt}{28.45274pt}% +% \pgfsyssoftpath@linetotoken{156.50636pt}{14.2278pt}% +% } +% \expandafter\def\csname expected@a@4\endcsname{% +% \pgfsyssoftpath@movetotoken{156.50636pt}{14.2278pt}% +% \pgfsyssoftpath@linetotoken {170.71646pt}{0.0pt}% +% } +% % +\def\pgfcomputeintersectionsegments#1{% + \pgfcomputeintersectionsegments@set@src{#1}% + \ifnum\pgfintersectionsolutions=0 % + \pgfutil@namelet{pgf@intersect@path@split@\pgf@insert@intersections@src @0}{pgf@intersect@path@\pgf@insert@intersections@src}% + \def\pgfretval{0}% + \else + % + % This algorithm *relies* on an increasing sort order. Sort + % them: + \pgfintersectionsolutionsortbytime@@% + % + % + \pgfapplistnewempty{pgfretval@tmp}% + \def\pgf@insert@cursolution{1}% + \def\c@pgf@path@result{0}% + \let\c@pgf@path@segment=\c@pgf@countd + \let\c@pgf@path@segment@trg=\c@pgf@countc + \c@pgf@path@segment=0 % + \pgf@fillbetween@get@time@off{\pgf@insert@intersections@src}{\pgf@insert@cursolution}% + \c@pgf@path@segment@trg=\pgfretval\relax + % + \pgfutil@namelet{pgf@loc@TMPa}{pgf@intersect@path@\pgf@insert@intersections@src}% + \expandafter\pgf@insert@intersections@loop\pgf@loc@TMPa\pgf@stop + % + \pgfapplistlet\pgf@loc@TMPa={pgfretval@tmp}% + \expandafter\let\csname pgf@intersect@path@split@\pgf@insert@intersections@src @\c@pgf@path@result\endcsname=\pgf@loc@TMPa% + \pgfutil@advancestringcounter\c@pgf@path@result% + \let\pgfretval=\c@pgf@path@result% + \fi +}% + +% Defines \pgfretval to contain the desired path segment as softpath. +% +% @see \pgfsetpath +% @see \pgfsetpathandBB +% @see \pgfaddpathandBB +% +% #1: the value '1' if results for the FIRST argument of +% \pgfintersectionofpaths are requested or '2' if results for the +% SECOND path are requested (compare \pgfcomputeintersectionsegments). +% #2: the segment index (a number 0<= #2 < numbersegments). +% The number of segments is returned by +% \pgfcomputeintersectionsegments. +\def\pgfgetintersectionsegmentpath#1#2{% + \pgfcomputeintersectionsegments@set@src{#1}% + \afterassignment\pgfcomputeintersectionsegments@set@src@gobble + \c@pgf@countc=#2\relax% + \expandafter\let\expandafter\pgfretval\csname pgf@intersect@path@split@\pgf@insert@intersections@src @\the\c@pgf@countc\endcsname + \ifx\pgfretval\relax + \pgferror{There is no intersection segment '#2' in path '#1'}% + \fi +}% +\def\pgfcomputeintersectionsegments@set@src@gobble#1\relax{} + +\def\pgfcomputeintersectionsegments@set@src#1{% + \ifcase#1\relax + % 0 + \pgferror{illegal argument supplied.} + \or + \def\pgf@insert@intersections@src{a}% + \or + \def\pgf@insert@intersections@src{b}% + \else + \pgferror{illegal argument supplied.} + \fi +}% + +\def\pgfintersectionsolutionsortbytime@@{% + % this is an O(n^2) sort method. It might suffice provided that + % the number of intersections is small... and it is the same + % runtime as that of the intersection lib as such (which is, in + % fact, worse). + % + % Note that this bubble-sort-approach has the benefit that if the + % input sequence *is* actually sorted, that it will have no effect + % at all (linear time). + \pgf@intersect@solutions@sortfinishtrue% + \pgfmathloop% + \ifnum\pgfmathcounter<\pgfintersectionsolutions\relax% + \pgfutil@tempcnta=\pgfmathcounter% + \advance\pgfutil@tempcnta by1\relax% + % + % acquire the sort keys... + \pgfintersectiongetsolutiontimes{\pgfmathcounter}{\pgf@loc@tmp@A@a}{\pgf@loc@tmp@A@b}% + \pgfintersectiongetsolutiontimes{\the\pgfutil@tempcnta}{\pgf@loc@tmp@B@a}{\pgf@loc@tmp@B@b}% + % + \ifdim\csname pgf@loc@tmp@A@\pgf@insert@intersections@src\endcsname pt>% + \csname pgf@loc@tmp@B@\pgf@insert@intersections@src\endcsname pt\relax% + \pgf@intersect@solutions@sortfinishfalse% + % + \pgfintersectionsolutionsortbytime@swap{pgfpoint@intersect@solution@\pgfmathcounter}% + {pgfpoint@intersect@solution@\the\pgfutil@tempcnta}% + % + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@props@\pgfmathcounter}% + {pgf@intersect@solution@props@\the\pgfutil@tempcnta}% + \fi% + \repeatpgfmathloop% + \ifpgf@intersect@solutions@sortfinish% + \else% + \expandafter\pgfintersectionsolutionsortbytime@@% + \fi% +} + + +% #1: either 'a' or 'b', depending on the required part +% #2: the solution index (starting with 1) +% Defines \pgfretval to contain the result. +\def\pgf@fillbetween@get@time@off#1#2{% + \pgfintersectiongetsolutionsegmentindices{#2}{\pgf@temp@a}{\pgf@temp@b}% + \edef\pgfretval{\csname pgf@temp@#1\endcsname}% +}% + +% ---------------------------------------------------------------------------------- + + +% Splits a Bezier curve at a designated time 't' +% using decasteljau +%-------------------------------------------------- +% Point lerp(float t, Point A, Point B) { +% return A*(1-t) + B*t; // + and * overloaded for Points +% } +% +% void split(t, Point P[4], Point L[4], Point R[4]) { +% Point P01 = lerp(t, P[0], P[1]); +% Point P12 = lerp(t, P[1], P[2]); +% Point P23 = lerp(t, P[2], P[3]); +% Point P012 = lerp(t, P01, P12); +% Point P123 = lerp(t, P12, P13); +% Point Q = lerp(t, P012, P123); +% L[0] = P[0]; L[1] = P01; L[2] = P012; L[3] = Q; +% R[0] = Q; +% R[1] = P123; R[2] = P23; R[3] = P[3]; +% } +%-------------------------------------------------- +% INPUT: +% #1: a value in the range [0,1] which determines the split point +% #2,#3,#4,#5: the points of the curve, each of the form {<x>}{<y>} +% +% OUTPUT: +% \pgfretval@L{{<A>}{<B>}{<C>}{<D>}} +% \pgfretval@R{{<A>}{<B>}{<C>}{<D>}} +% +% @see \pgf@split@curveto@softpaths +\def\pgf@split@curveto#1#2#3#4#5{% + \begingroup + \pgf@xa=-#1pt % + \advance\pgf@xa by1pt % + \edef\pgf@split@one@m@t{\pgf@sys@tonumber\pgf@xa}% + % + \pgf@split@curveto@lerp{#1}{\pgf@split@one@m@t}{#2}{#3}% + \pgf@split@curveto@tomacro\pgf@split@curveto@p@AB + % + \pgf@split@curveto@lerp{#1}{\pgf@split@one@m@t}{#3}{#4}% + \pgf@split@curveto@tomacro\pgf@split@curveto@p@BC + % + \pgf@split@curveto@lerp{#1}{\pgf@split@one@m@t}{#4}{#5}% + \pgf@split@curveto@tomacro\pgf@split@curveto@p@CD + % + \pgf@split@curveto@lerp{#1}{\pgf@split@one@m@t}{\pgf@split@curveto@p@AB}{\pgf@split@curveto@p@BC}% + \pgf@split@curveto@tomacro\pgf@split@curveto@p@ABC + % + \pgf@split@curveto@lerp{#1}{\pgf@split@one@m@t}{\pgf@split@curveto@p@BC}{\pgf@split@curveto@p@CD}% + \pgf@split@curveto@tomacro\pgf@split@curveto@p@BCD + % + \pgf@split@curveto@lerp{#1}{\pgf@split@one@m@t}{\pgf@split@curveto@p@ABC}{\pgf@split@curveto@p@BCD}% + \pgf@split@curveto@tomacro\pgf@split@curveto@p@Q + % + \xdef\pgf@marshal{% + \edef\noexpand\pgfretval@L{{#2}{\pgf@split@curveto@p@AB}{\pgf@split@curveto@p@ABC}{\pgf@split@curveto@p@Q}}% + \edef\noexpand\pgfretval@R{{\pgf@split@curveto@p@Q}{\pgf@split@curveto@p@BCD}{\pgf@split@curveto@p@CD}{#5}}% + }% + \endgroup + \pgf@marshal +} + +% Splits a Bezier curve at a designated time 't' +% +% This variants takes a part of a softpath as input: +% +% #1: a curveto- a macro containing a softpath of the form +% <x><y>\pgfsyssoftpath@curvetosupportatoken<x><y>\pgfsyssoftpath@curvetosupportbtoken<x><y>\pgfsyssoftpath@curvetotoken<x><y> +% #2: t in [0,1] +% +% OUTPUT: \pgfretval@L contains the LEFT segment (in the same softpath format) and \pgfretval@R contains the RIGHT segment (in the softpath format), \pgfretval contains the intersection point (i.e. the point evaluated at 't') +\def\pgf@split@curveto@softpaths#1#2{% + \expandafter\pgf@split@curveto@softpaths@#1{#2}% +} + +\def\pgf@split@curveto@softpaths@#1#2\pgfsyssoftpath@curvetosupportatoken#3#4\pgfsyssoftpath@curvetosupportbtoken#5#6\pgfsyssoftpath@curvetotoken#7#8#9{% + \pgf@split@curveto{#9}% + {{#1}{#2}}% + {{#3}{#4}}% + {{#5}{#6}}% + {{#7}{#8}}% + \expandafter\pgf@split@curveto@softpaths@@\pgfretval@L\pgfretval@L + \expandafter\pgf@split@curveto@softpaths@@\pgfretval@R\pgfretval@R +}% + +\def\pgf@split@curveto@softpaths@@#1#2#3#4#5{% + % we can silently omit the moveto component. + \def#5{\pgfsyssoftpath@curvetosupportatoken#2\pgfsyssoftpath@curvetosupportbtoken#3\pgfsyssoftpath@curvetotoken#4}% + \def\pgfretval{#1}% +}% + +% ---------------------------------------------------------------------------------- + +% defines \pgf@x, \pgf@y to be A*(1-t) + B*t +% #1: the scalar value 't' in [0,1] +% #2: the scalar value '1-t' in [0,1] +% #3: a 2d point 'A' of the form {<x>}{<y>} +% #4: a 2d point 'B' of the form {<x>}{<y>} +\def\pgf@split@curveto@lerp#1#2#3#4{% + \pgfpointadd + {\pgfqpointscale{#2}{\expandafter\pgfqpoint#3}}% + {\pgfqpointscale{#1}{\expandafter\pgfqpoint#4}}% +}% + +\def\pgf@split@curveto@tomacro#1{% + \edef#1{{\the\pgf@x}{\the\pgf@y}}% +} + + +\def\pgfcomputeintersectionsegments@@{% +%\message{processing segment \the\c@pgf@path@segment\space (current solution \pgf@insert@cursolution/\pgfintersectionsolutions; target segment \the\c@pgf@path@segment@trg, currentxy \pgfinsert@intersect@tok@currentxy, lastxy \pgfinsert@intersect@tok@lastxy)^^J}% + \pgfmathloop + % we need to loop: it is fully acceptable if more than one + % solution is on the same segment. + \ifnum\c@pgf@path@segment=\c@pgf@path@segment@trg + % + \pgf@insert@intersections@split@segment + \expandafter\pgfapplistpushback\pgfretval\to{pgfretval@tmp}% + % + % + % report the current result segment! + \pgfapplistlet\pgf@loc@TMPa={pgfretval@tmp}% + \expandafter\let\csname pgf@intersect@path@split@\pgf@insert@intersections@src @\c@pgf@path@result\endcsname=\pgf@loc@TMPa% + \pgfutil@advancestringcounter\c@pgf@path@result% + % ... and start a new result segment. Keep in mind that it + % should start with a moveto: + \pgfapplistnewempty{pgfretval@tmp}% + \csname pgfpoint@intersect@solution@\pgf@insert@cursolution\endcsname% + \edef\pgf@loc@TMPa{\noexpand\pgfsyssoftpath@movetotoken{\the\pgf@x}{\the\pgf@y}}% + \expandafter\pgfapplistpushback\pgf@loc@TMPa\to{pgfretval@tmp}% + % + % + % OK, iterate: + \ifnum\pgf@insert@cursolution=\pgfintersectionsolutions\relax + % collect all remaining ones: + \c@pgf@path@segment@trg=10000000 % + \else + \pgfutil@advancestringcounter\pgf@insert@cursolution + \pgf@fillbetween@get@time@off{\pgf@insert@intersections@src}{\pgf@insert@cursolution}% + \c@pgf@path@segment@trg=\pgfretval\relax + \fi + \repeatpgfmathloop + \expandafter\pgfapplistpushback\pgfinsert@intersect@tok\to{pgfretval@tmp}% + \let\pgfinsert@intersect@tok@lastxy=\pgfinsert@intersect@tok@currentxy + \advance\c@pgf@path@segment by1 % +}% + +% INPUT: +% - \pgfinsert@intersect@tok@type is the current type (one of \pgfsyssoftpath@linetotoken or \pgfsyssoftpath@curvetotoken) +% - \pgf@insert@cursolution is the current intersection index +% - \pgfinsert@intersect@tok is the current path segment. On output, it is the *remaining* path segment. +% - \pgfinsert@intersect@tok@lastxy the (x,y) coordinates of the last seen coordinate. +% +% OUTPUT: +% - \pgfretval the segment which has been splitted off. It will be appended to the result. +% - \pgfinsert@intersect@tok the remaining path segment which is to be processed +% - \pgfinsert@intersect@tok@lastxy the (x,y) coordinates of the last seen coordinate which is to be processed. +\def\pgf@insert@intersections@split@segment{% + \ifx\pgfinsert@intersect@tok@type\pgfsyssoftpath@linetotoken + \csname pgfpoint@intersect@solution@\pgf@insert@cursolution\endcsname% + \edef\pgfretval{\noexpand\pgfsyssoftpath@linetotoken{\the\pgf@x}{\the\pgf@y}}% + % ... and keep \pgfinsert@intersect@tok at its current value (it is \pgfsyssoftpath@linetotoken{<next x>}{<next y>}) + \else + \ifx\pgfinsert@intersect@tok@type\pgfsyssoftpath@curvetotoken + % Ah; a curveto. That's more involved! + % First, get the time offset of the current intersection: + % + % Get the global time: + \pgfintersectiongetsolutiontimes{\pgf@insert@cursolution}{\pgf@split@it@time@a}{\pgf@split@it@time@b}% + % Get time at the beginning of the current solution segment: + \pgfintersectiongetsolutionsegmentindices{\pgf@insert@cursolution}{\pgf@split@it@timeoff@a}{\pgf@split@it@timeoff@b}% + % compute local time within the current solution segment: + \pgf@xa=\csname pgf@split@it@time@\pgf@insert@intersections@src\endcsname pt % + \advance\pgf@xa by-\csname pgf@split@it@timeoff@\pgf@insert@intersections@src\endcsname pt % + \edef\pgf@split@it@time{\pgf@sys@tonumber\pgf@xa}% + % + \let\pgf@split@it@start=\pgfinsert@intersect@tok@lastxy + % we have to insert the last XY coordinates: + \t@pgf@toka=\expandafter{\pgf@split@it@start}% + \t@pgf@tokb=\expandafter{\pgfinsert@intersect@tok}% + \edef\pgf@temp{\the\t@pgf@toka\the\t@pgf@tokb}% + % Split into TWO curveto operations! + \pgf@split@curveto@softpaths{\pgf@temp}{\pgf@split@it@time}% + % ok, the first returned sub-curveto is the result of this method... + \let\pgfretval=\pgfretval@L + % ... and the second is the "remainder" which is still to be processed. + \let\pgfinsert@intersect@tok=\pgfretval@R + \else + \pgferror{Unsupported path type \meaning\pgfinsert@intersect@tok@type. Cannot process these paths.}% + \fi + \fi + % + \csname pgfpoint@intersect@solution@\pgf@insert@cursolution\endcsname% + \edef\pgfinsert@intersect@tok@lastxy{{\the\pgf@x}{\the\pgf@y}}% +}% + +\def\pgf@insert@intersections@loop#1{% + \ifx#1\pgf@stop% + \let\pgfinsert@intersect@tok\pgfutil@empty% + \let\pgfinsert@intersect@tok@type\pgfutil@empty + \pgfcomputeintersectionsegments@@% + \let\pgfinsert@intersect@next=\relax% + \else% + \ifx#1\pgfsyssoftpath@movetotoken% + \let\pgfinsert@intersect@next=\pgfinsert@intersect@token@moveto% + \else% + \ifx#1\pgfsyssoftpath@linetotoken% + \let\pgfinsert@intersect@next=\pgfinsert@intersect@token@lineto% + \else% + \ifx#1\pgfsyssoftpath@closepathtoken% + \let\pgfinsert@intersect@next=\pgfinsert@intersect@token@close% + \else% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \let\pgfinsert@intersect@next=\pgfinsert@intersect@token@curveto% + \else% + \ifx#1\pgfsyssoftpath@rectcornertoken% + \let\pgfinsert@intersect@next=\pgfinsert@intersect@token@rect% + \fi% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgfinsert@intersect@next} + +\def\pgfinsert@intersect@token@moveto#1#2{% + \def\pgfinsert@intersect@tok{\pgfsyssoftpath@movetotoken{#1}{#2}}% + \let\pgfinsert@intersect@tok@type\pgfsyssoftpath@movetotoken + \def\pgfinsert@intersect@tok@lastxy{{#1}{#2}}% + \expandafter\pgfapplistpushback\pgfinsert@intersect@tok\to{pgfretval@tmp}% + \pgf@insert@intersections@loop% +} + +\def\pgfinsert@intersect@token@lineto#1#2{% + \def\pgfinsert@intersect@tok{\pgfsyssoftpath@linetotoken{#1}{#2}}% + \let\pgfinsert@intersect@tok@type\pgfsyssoftpath@linetotoken + \def\pgfinsert@intersect@tok@currentxy{{#1}{#2}}% + \pgfcomputeintersectionsegments@@% + \pgf@insert@intersections@loop +} +\def\pgfinsert@intersect@token@close#1#2{% + \def\pgfinsert@intersect@tok{\pgfsyssoftpath@closepathtoken{#1}{#2}}% + \let\pgfinsert@intersect@tok@type\pgfsyssoftpath@linetotoken + \def\pgfinsert@intersect@tok@currentxy{{#1}{#2}}% + \pgfcomputeintersectionsegments@@% + \pgf@insert@intersections@loop +} + +\def\pgfinsert@intersect@token@curveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{% + \def\pgfinsert@intersect@tok{\pgfsyssoftpath@curvetosupportatoken{#1}{#2}\pgfsyssoftpath@curvetosupportbtoken{#3}{#4}\pgfsyssoftpath@curvetotoken{#5}{#6}}% + \let\pgfinsert@intersect@tok@type\pgfsyssoftpath@curvetotoken + \def\pgfinsert@intersect@tok@currentxy{{#5}{#6}}% + \pgfcomputeintersectionsegments@@% + \pgf@insert@intersections@loop +} + +\def\pgfinsert@intersect@token@rect#1#2\pgfsyssoftpath@rectsizetoken#3#4{% + \pgf@xa=#1\relax% + \advance\pgf@xa by#3\relax% + \pgf@ya=#2\relax% + \advance\pgf@ya by#4\relax% + \edef\pgf@marshal{% + \noexpand\pgfsyssoftpath@movetotoken{#1}{#2}% + \noexpand\pgfsyssoftpath@linetotoken{#1}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@xa}{#2}% + \noexpand\pgfsyssoftpath@closepathtoken{#1}{#2}% + }% + \expandafter\pgf@insert@intersections@loop\pgf@marshal% +} + + +% #1: a macro containing the clip path. More precisely, it is supposed to be a return value of \pgfgetpath. +\def\pgffillbetweensetsoftclippathfirst#1{% + \let\pgfpathfillbetween@softclip@A=#1% +}% + +% #1: a macro containing the clip path. More precisely, it is supposed to be a return value of \pgfgetpath. +\def\pgffillbetweensetsoftclippathsecond#1{% + \let\pgfpathfillbetween@softclip@B=#1% +}% + +% #1: a macro containing the clip path. More precisely, it is supposed to be a return value of \pgfgetpath. +\def\pgffillbetweensetsoftclippath#1{% + \pgffillbetweensetsoftclippathfirst{#1}% + \pgffillbetweensetsoftclippathsecond{#1}% +} + +% Default: no clip paths +\pgffillbetweensetsoftclippathfirst{\pgfutil@empty} +\pgffillbetweensetsoftclippathsecond{\pgfutil@empty} +\endinput diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/tikzlibrarydecorations.softclip.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/tikzlibrarydecorations.softclip.code.tex new file mode 100644 index 00000000000..98fca71c047 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/tikzlibrarydecorations.softclip.code.tex @@ -0,0 +1,502 @@ +%-------------------------------------------- +% +% Package pgfplots +% +% Provides a user-friendly interface to create function plots (normal +% plots, semi-logplots and double-logplots). +% +% It is based on Till Tantau's PGF package. +% +% Copyright 2013 by Christian Feuersaenger +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see <http://www.gnu.org/licenses/>. +% +%-------------------------------------------- +% +% This library adds support for a "soft clip" decoration. It applies +% clipping to an input path, but rather than simply instructing the +% display driver to clip the path, it computes a new clip path from +% the input. +% +% This library is (currently) on top of tikz. + +\pgfutil@IfUndefined{pgfplotsset}{% + \pgferror{Please load pgfplots before pgfplots.fillbetween.}% + \endinput +}{}% + +\usetikzlibrary{intersections} + +\pgfplots@iffileexists{pgflibraryfillbetween.code.tex}{% + \usepgflibrary{fillbetween} +}{% + \pgfplotsusecompatibilityfile{pgflibraryfillbetween.code.tex}% +}% + +\pgfutil@IfUndefined{pgfintersectiongetsolutiontimes}{% + \pgfplotsusecompatibilityfile{pgflibraryintersections.code.tex}% +}{}% + + +\pgfkeys{ + % soft clip={(axis cs:0,0) rectangle (axis cs:1,1)} + % or + % soft clip={A} + % where 'A' is defined using 'name path=A' somewhere + /pgf/decoration/soft clip path/.initial=, + /pgf/decoration/every soft clipped path/.style={},% +} + +% #1 a macro containing a soft path +\def\tikzlibsoftclip@setkey@assign#1{% + \let\pgf@decoration@soft@clip=#1% +}% + +\tikzlibsoftclip@setkey@assign{\pgfutil@empty}% + +\pgfdeclaredecoration{soft clip}{replace}{ + + \state{replace}[width=\pgfdecoratedpathlength, + persistent precomputation={% + \pgfkeysgetvalue{/pgf/decoration/soft clip path}\pgf@temp + \def\tikz@marshal{\tikzlibsoftclip@setkey{\tikzlibsoftclip@setkey@assign}}% + \expandafter\tikz@marshal\pgf@temp\pgf@stop + } + ]{% + \ifx\pgf@decoration@soft@clip\pgfutil@empty + \pgfplotsthrow{invalid argument} + {\pgf@decoration@soft@clip}% + {The mandatory argument 'soft clip path=(A) rectangle (B)' has not been set}% + \pgfeov + \else + \tikzset{/pgf/decoration/every soft clipped path}% + \pgfpathcomputesoftclippath{\pgfdecoratedpath}{\pgf@decoration@soft@clip}% + \pgfsetpathandBB{\pgfretval}% + \fi + } +} + +% --------------------------------------------------------------------------------- +% +% SOFT-CLIPPING. +% +% "softclip" means to get rid of those parts of a path which are +% outside of a clip path. +% +% An example is to trim at the beginning and/or end of a +% path as part of fill-between ("poor-mans-clipping"). +% +% The difference to "real" clipping is that it is applied to the +% path, not to the viewer -- the path can still be drawn with any +% decorations, line widths, etc. +% +% Another difference is that this feature is (considerably) less sophisticated. +% +% #1: the input path +% #2: the clip path (if it is empty, no clipping will be applied) +% OUTPUT: +% \pgfretval is #1 with modifications +\def\pgfpathcomputesoftclippath#1#2{% + \ifx#2\pgfutil@empty + \let\pgfretval=#1% + \else + \ifx#1\pgfutil@empty + \let\pgfretval=#1% + \else + \pgfpathcomputesoftclippath@{#1}{#2}% + \fi + \fi +} + +\def\pgfpathcomputesoftclippath@#1#2{% + \begingroup + \pgfprocessround{#1}{#1}% + \pgfprocessround{#2}{#2}% + % + % + \pgfpathcomputesoftclippath@is@first@outside@of@path{#1}{#2}% + \let\b@pgffill@is@outside@clip=\pgfretval + % +%\message{computing soft clip path for ^^J\meaning#1 and ^^J\meaning#2^^J first point of input is outside of clip path=\b@pgffill@is@outside@clip^^J}% + % + % FIXME : it might be that I need to sort them ... !? but + % other tests indicate that I should not!? + %\pgfintersectionsortbyfirstpath + \pgf@intersect@sortfalse + \pgfintersectionofpaths% + {% + \pgfsetpath#1% + }% + {% + \pgfsetpath#2% + }% + % + % + \ifnum\pgfintersectionsolutions=0 % + \if1\b@pgffill@is@outside@clip + % entire path is outside of the clipped area. + \let\pgfretval=\pgfutil@empty + \else + \let\pgfretval=#1% + \fi + \else + % split the first involved path into the + % segments induced by the intersection points: + \pgfcomputeintersectionsegments{1}% + \let\pgfpathfilled@a@segments=\pgfretval + % + % Now, create a new path which contains only those + % segments which are INSIDE of the clip path. + % + % I assume that I can rely on "even/odd" matching: if the + % first is inside, the second is outside, the third + % inside, etc. + \pgfapplistnewempty{pgfretval@tmp}% + \def\c@pgfpathfilled@counter{0}% + \pgfmathloop + \ifnum\c@pgfpathfilled@counter<\pgfpathfilled@a@segments\relax + \if0\b@pgffill@is@outside@clip + \expandafter\let\expandafter\pgf@loc@path@a\csname pgf@intersect@path@split@a@\c@pgfpathfilled@counter\endcsname + \expandafter\pgfapplistpushback\pgf@loc@path@a\to{pgfretval@tmp}% + \fi + \pgfpathfillbetween@negate\b@pgffill@is@outside@clip + % + \pgfutil@advancestringcounter\c@pgfpathfilled@counter + \repeatpgfmathloop + \pgfapplistlet\pgfretval={pgfretval@tmp}% + \fi + % + \global\let\pgf@glob@TMPa=\pgfretval% + \endgroup + \let\pgfretval=\pgf@glob@TMPa +} + +% #1: input path (non-empty) +% #2: soft clip path +% Defines "\def\pgfretval{1}" if (the first point of #1 is outside or on the path #2) +% Defines "\def\pgfretval{0}" if (the first point of #1 is inside of the path #2) +\def\pgfpathcomputesoftclippath@is@first@outside@of@path#1#2{% + % APPROACH: shoot a line starting at the first coordinate of the + % first path through "the middle of #2". Then make an even/odd + % check on the number of intersections. + % + % FIXME : for now, I only support (x,y) rectangle (X,Y) anyway -- + % optimize for that case!? This here might be too complex... + \begingroup + \expandafter\pgfpathfillbetween@get@first@coord#1\pgf@stop + \let\pgfpathfilled@a@firstcoord=\pgfretval% + % + % Get some point "in the middle of #2": + \pgfpathcomputesoftclippath@accum@pseudo@mean#2% + \edef\pgfpathfilled@b@center{\noexpand\pgfqpoint\pgfretval}% + % + % We have to shoot *through* #2, not just into the middle of #2. + % Consequently, we need to know how big #2 is: + \pgfpathcomputesoftclippath@is@first@outside@of@path@getBB#2% + \let\pgf@size@hint=\pgfretval + % + % Now, compute a target point such that our shot goes through it: + \pgfqpointscale{% + \pgf@size@hint + }{% + \pgfpointnormalised{% + \pgfpointdiff% + {\expandafter\pgfqpoint\pgfpathfilled@a@firstcoord}% + {\pgfpathfilled@b@center}% + }% + }% + % collect intermediate results as \pgf@xa/\pgf@ya are overwritten: + \edef\pgf@direction@vector{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \pgfpointadd{\pgfpathfilled@b@center}{\pgf@direction@vector}% + \edef\pgfpathfilled@shoot@line@trg{{\the\pgf@x}{\the\pgf@y}}% + % + % this here is our path! + \edef\pgf@direction@path{% + \noexpand\pgfsyssoftpath@movetotoken\pgfpathfilled@a@firstcoord + \noexpand\pgfsyssoftpath@linetotoken\pgfpathfilled@shoot@line@trg + }% + % + % ... ok, compute intersections. This should be fairly fast as + % our second path has just 1 segment, i.e. it will be O(N) where N + % is the number of segments in #2. + \pgf@intersect@sortfalse + \pgfintersectionofpaths% + {% + \pgfsetpath#2% + }% + {% + \pgfsetpath\pgf@direction@path% + }% + % + \ifnum\pgfintersectionsolutions=0 % + % this must not happen! We have taken great care such that we + % *have* at least 1 intersection points! + \pgferror{Illegal state encountered: the computation of a softpath failed. The failure occurred while computing whether the first input coordinate is inside of the clip path (found no intersections)}% + \fi + % + \pgfpathcomputesoftclippath@if@is@first@on@boundary{% + % AH! The first point is ON the boundary of the clip path. + % This is equivalent to the condition that the first + % intersection point equals the first point. + % + % In this case, we say that it is OUTSIDE of the clip path! + % + % This is actually related to + % 1. the fact that the input path is splitted into segments + % induced by the intersection points in order to apply + % soft-clipping. + % 2. the fact that the clipping is based on an even/odd + % matching (in/out). + % + % In that setup, we want to skip the segment until the first + % intersection point - after all, it is "empty" anyway. + % + % To this end, we have to say that this first (empty) segment + % is OUTSIDE: + \def\pgfretval{1}% + }{% + \ifodd\pgfintersectionsolutions\relax% + \def\pgfretval{0}% + \else + \def\pgfretval{1}% + \fi + }% + \pgfmath@smuggleone\pgfretval + \endgroup +} + +\def\pgfpathcomputesoftclippath@if@is@first@on@boundary#1#2{% + \pgfpathcomputesoftclippath@compute@infty@norm{% + \pgfpointdiff% + {\expandafter\pgfqpoint\pgfpathfilled@a@firstcoord}% + {\pgfpointintersectionsolution{1}}% + }% + \ifdim\pgf@x<\pgfintersectiontolerance\relax + % YES: the first point IS on the boundary: the first + % intersection solution == first point. + #1% + \else + % No, it is NOT equal to the first intersection solution - and + % thus NOT on the boundary. + #2% + \fi +}% + +% Defines \pgf@x to be the infty norm of vector #1 +\def\pgfpathcomputesoftclippath@compute@infty@norm#1{% + \pgf@process{#1}% + \ifdim\pgf@x<0sp \global\pgf@x=-\pgf@x\fi + \ifdim\pgf@y<0sp \global\pgf@y=-\pgf@y\fi + \ifdim\pgf@x<\pgf@y + \global\pgf@x=\pgf@y + \fi +} + +% Defines \pgfretval to be a *scalar* "size indicator" (1-norm) of the bounding +% box of #1. +% +% #1: a macro containing a softpath. +\def\pgfpathcomputesoftclippath@is@first@outside@of@path@getBB#1{% + \begingroup + \pgf@getpathsizes\pgf@interrupt@pathsizes + % we only need the path size here: + \pgf@relevantforpicturesizefalse + \expandafter\pgfsetpath@protocolsizes@loop#1\pgf@stop + \pgfpointdiff + {\pgfqpoint\pgf@pathminx\pgf@pathminy}% + {\pgfqpoint\pgf@pathmaxx\pgf@pathmaxy}% + % compute |v|_1 = x + y (both components are non-negative anyway): + \pgf@xa=\pgf@x + \advance\pgf@xa by\pgf@y + \xdef\pgf@glob@TMPa{\pgf@sys@tonumber\pgf@xa}% + \pgf@setpathsizes\pgf@interrupt@pathsizes + \endgroup + \let\pgfretval=\pgf@glob@TMPa +}% + +% Defines \pgfretval to be of a "pseudo" mean of path #1. +% +% Here, "pseudo" refers to the fact that the mean will only be +% accumulated over the "first couple of coordinates" to avoid numeric +% overflows in TeX's math engine. +\def\pgfpathcomputesoftclippath@accum@pseudo@mean#1{% + \begingroup + \let\pgfsyssoftpath@movetotoken\pgfpathcomputesoftclippath@accum@pseudo@mean@ + \let\pgfsyssoftpath@linetotoken\pgfpathcomputesoftclippath@accum@pseudo@mean@ + \let\pgfsyssoftpath@closepathtoken\pgfpathcomputesoftclippath@accum@pseudo@mean@ + \let\pgfsyssoftpath@curvetotoken\pgfpathcomputesoftclippath@accum@pseudo@mean@ + \let\pgfsyssoftpath@curvetosupportatoken\pgfpathcomputesoftclippath@accum@pseudo@mean@relax + \let\pgfsyssoftpath@curvetosupportbtoken\pgfpathcomputesoftclippath@accum@pseudo@mean@relax + \c@pgf@countc=0 % + \pgf@xa=0pt % + \pgf@ya=0pt % + #1% + \divide\pgf@xa by\c@pgf@countc + \divide\pgf@ya by\c@pgf@countc + \edef\pgfretval{{\the\pgf@xa}{\the\pgf@ya}}% + \pgfmath@smuggleone\pgfretval + \endgroup +}% +\def\pgfpathcomputesoftclippath@accum@pseudo@mean@relax#1#2{} +\def\pgfpathcomputesoftclippath@accum@pseudo@mean@#1#2{% + \ifnum\c@pgf@countc<4 + % avoid overflows. 4 must be sufficient for now. + \advance\pgf@xa by#1\relax + \advance\pgf@ya by#2\relax + \advance\c@pgf@countc by1 % + \fi +} + + +% #1: of the form '{<x>}{<y>}' +% #2: of the form '{<x>}{<y>}' +\def\pgfpathfillbetween@check@x@less@than#1#2{% + \edef\pgf@temp{#1#2}% + \expandafter\pgfpathfillbetween@check@x@less@than@\pgf@temp +}% + +% #1: x1 +% #2: y1 +% #3: x2 +% #4: y2 +\def\pgfpathfillbetween@check@x@less@than@#1#2#3#4{% + \ifdim#1>#3\relax + % <= + \def\pgfretval{0}% + \else + \def\pgfretval{1}% + \fi +}% + +\def\pgfpathfillbetween@negate#1{% + \if0#1% + \def#1{1}% + \else + \def#1{0}% + \fi +} + +\pgfkeys{ + /tikz/soft clip assign/name/.code={\tikzgetnamedpath{#1}}, + /tikz/soft clip assign/path/.code={\tikzlibsoftclip@setkey@@#1\pgf@stop}, +} + +% +% \tikzlibsoftclip@setkey{<\macro>} <path name>\pgf@stop +% +% OR +% +% \tikzlibsoftclip@setkey{<\macro>} (<A>) rectangle (<B>)\pgf@stop +% +% #1: a macro which is called with the resulting clip path as argument #1. +\def\tikzlibsoftclip@setkey#1#2\pgf@stop{% + \pgfutil@in@{=}{#2}% + \ifpgfutil@in@ + \pgfqkeys{/tikz/soft clip assign}{#2}% + \else + \def\pgf@temp{#2}% + \pgfplots@command@to@string\pgf@temp\pgf@temp + % + \tikzifisnamedpath{\pgf@temp}{% + \pgfkeysalso{/tikz/soft clip assign/name={#2}}% + }{% + \pgfkeysalso{/tikz/soft clip assign/path={#2}}% + }% + \fi + #1{\pgfretval}% +} + +\def\tikzlibsoftclip@setkey@@{% + % + \tikz@scan@one@point\tikzlibsoftclip@setkey@bb@scan@a +}% + +\def\tikzlibsoftclip@setkey@bb@scan@a#1{% + \def\tikzlibsoftclip@setkey@bb@a{#1}% + \pgfutil@ifnextchar r{% + \tikzlibsoftclip@setkey@bb@scan@rectangle + }{% + \tikzlibsoftclip@setkey@@error + }% +}% + +\def\tikzlibsoftclip@setkey@bb@scan@rectangle rectangle{% + \tikz@scan@one@point\tikzlibsoftclip@setkey@bb@scan@b +}% + +\def\tikz@gobble@until@stop#1\pgf@stop{}% + +\def\tikzlibsoftclip@setkey@bb@scan@b#1{% + \def\tikzlibsoftclip@setkey@bb@b{#1}% + \pgfutil@ifnextchar \pgf@stop{% + \tikzlibsoftclip@setkey@@activate + \tikz@gobble@until@stop + }{% + \tikzlibsoftclip@setkey@@error + }% +}% + +\def\tikzlibsoftclip@setkey@@error#1\pgf@stop{% + \def\pgfplots@loc@TMPa{#1}% + \pgfplots@command@to@string\pgfplots@loc@TMPa\pgfplots@loc@TMPb + \pgfplotsthrow{invalid argument} + {\pgfplots@loc@TMPa}% + {fill between: the argument of 'soft clip' has an unexpected format near '\pgfplots@loc@TMPb'; expected '(<pt>) rectangle (<pt>)'}% + \pgfeov +}% + +% INPUT: +% - two PGF points \tikzlibsoftclip@setkey@bb@a and \tikzlibsoftclip@setkey@bb@b. +% +% POSTCONDITION: \pgfretval contains the resulting path. +\def\tikzlibsoftclip@setkey@@activate{% + % Expand points to {<x>}{<y>} ... + \pgf@process{\tikzlibsoftclip@setkey@bb@a}% + \edef\tikzlibsoftclip@setkey@bb@a{{\the\pgf@x}{\the\pgf@y}}% + \pgf@process{\tikzlibsoftclip@setkey@bb@b}% + \edef\tikzlibsoftclip@setkey@bb@b{{\the\pgf@x}{\the\pgf@y}}% + % + \pgfinterruptpath + \pgf@relevantforpicturesizefalse% + \expandafter\pgfqpoint\tikzlibsoftclip@setkey@bb@a + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \expandafter\pgfqpoint\tikzlibsoftclip@setkey@bb@b + \pgf@xb=\pgf@x + \pgf@yb=\pgf@y + % + \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}% + \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}% + \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}% + \pgfpathclose + \pgfgetpath\pgfplots@loc@TMPa + \global\let\pgfplots@glob@TMPa=\pgfplots@loc@TMPa + \endpgfinterruptpath + % + \let\pgfretval=\pgfplots@glob@TMPa +}% +% --------------------------------------------------------------------------------- + +% Executes #2 if #1 is a named path and #3 otherwise. +\def\tikzifisnamedpath#1#2#3{% + \pgfutil@IfUndefined{tikz@intersect@path@name@#1}{% + \def\tikz@next{#3}% + }{% + \def\tikz@next{#2}% + }% + \tikz@next +}% + + diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/tikzlibraryfillbetween.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/tikzlibraryfillbetween.code.tex new file mode 100644 index 00000000000..6446027318f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/tikzlibraryfillbetween.code.tex @@ -0,0 +1,442 @@ +%-------------------------------------------- +% +% Package pgfplots +% +% Provides a user-friendly interface to create function plots (normal +% plots, semi-logplots and double-logplots). +% +% It is based on Till Tantau's PGF package. +% +% Copyright 2013 by Christian Feuersaenger +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see <http://www.gnu.org/licenses/>. +% +%-------------------------------------------- + + +% This library adds support for high-level instructions for "fill area +% between two arbitrary plots of functions". +% +% It activates the syntax \pgfpathfillbetween +% where A and B are two plots named by 'name path='. +% +% In fact, this here is not much more than a low-level invocation of +% \pgfpathfillbetween +% and a couple of styles. It could become a TikZ library because it +% actually works on any two named paths, but it has its restrictions +% regarding the supported input paths: both need to be plots of +% functions (non-intersecting, should have at most one function value +% for each canvas X coord) + +\pgfutil@IfUndefined{pgfplotsset}{% + \pgferror{Please load pgfplots before pgfplots.fillbetween.}% + \endinput +}{}% + +\usetikzlibrary{intersections} +\usetikzlibrary{decorations.softclip} + +% COMPATIBILITY WITH PGF RELEASE: +\pgfutil@IfUndefined{pgfintersectiongetsolutiontimes}{% + \pgfplotsusecompatibilityfile{pgflibraryintersections.code.tex}% +}{}% +\def\tikz@key@name@path@wrong#1#2{% + \tikz@addmode{% + \pgfsyssoftpath@getcurrentpath\tikz@intersect@temppath@round% + \pgfprocessround\tikz@intersect@temppath@round\tikz@intersect@temppath% + \ifx\tikz@intersect@namedpaths\pgfutil@empty% + \else% + \tikz@intersect@namedpaths% + \pgfutil@ifundefined{tikz@intersect@path@name@#1}{}% + {% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\tikz@intersect@@temppath% + \expandafter\expandafter\expandafter{\csname tikz@intersect@path@name@#1\endcsname}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\tikz@intersect@temppath% + \expandafter\expandafter\expandafter{\expandafter\tikz@intersect@temppath\tikz@intersect@temppath}% + }% + \fi% + \tikz@intersect@addto@path@names{#1}{#2}% + }% +}% + +\def\tikz@key@name@path@new#1#2{% + \tikz@addmode{% + \pgfsyssoftpath@getcurrentpath\tikz@intersect@temppath@round% + \pgfprocessround\tikz@intersect@temppath@round\tikz@intersect@temppath% + \ifx\tikz@intersect@namedpaths\pgfutil@empty% + \else% + \tikz@intersect@namedpaths% + \fi% + \tikz@intersect@addto@path@names{#1}{#2}% + }% +}% + +\ifx\tikz@key@name@path@wrong\tikz@key@name@path + \immediate\write16{Package pgfplots: loading complementary 'name path' implementation for your pgf version...} + \let\tikz@key@name@path=\tikz@key@name@path@new +\fi +% ------------------------------------------------------------ + + +\pgfkeys{% + /tikz/fill between/of/.code=\tikzlibraryfillbetween@parse#1\pgf@stop, + % + /tikz/fill between/on layer/.initial=pre main, + /tikz/fill between/every segment/.style={}, + /tikz/fill between/every odd segment/.style={}, + /tikz/fill between/every even segment/.style={}, + % + % soft clip={(axis cs:0,0) rectangle (axis cs:1,1)} + /tikz/fill between/soft clip/.style={ + /tikz/fill between/soft clip first={#1},% + /tikz/fill between/soft clip second={#1},% + },% + /tikz/fill between/soft clip first/.initial=,% + /tikz/fill between/soft clip second/.initial=, + % + % #1: drawing options. + /tikz/fill between/@draw style/.style={ + /pgf/fill between/result stream/begin/.code={% + \gdef\tikzsegmentindex{0}% + },% + /pgf/fill between/result stream/next ready/.code={% + \let\pgflibraryfill@path=\pgfretval + \def\pgfplots@loc@TMPa{% + /tikz/fill between/every segment, + #1,% + /tikz/fill between/every segment no \tikzsegmentindex/.try, + }% + \ifodd\tikzsegmentindex\relax + \expandafter\def\expandafter\pgfplots@loc@TMPa\expandafter{\pgfplots@loc@TMPa + /tikz/fill between/every odd segment, + }% + \else + \expandafter\def\expandafter\pgfplots@loc@TMPa\expandafter{\pgfplots@loc@TMPa + /tikz/fill between/every even segment, + }% + \fi + % + \expandafter\fill\expandafter[\pgfplots@loc@TMPa] + \pgfextra \pgfsetpathandBB{\pgflibraryfill@path}\endpgfextra;% + \pgfplotsutil@advancestringcounter@global\tikzsegmentindex + },% + /pgf/fill between/result stream/end/.code=,% + }, + /tikz/fill between/.search also={/pgf/fill between,/pgfplots}, + % + % + % + %-------------------------------------------------- + % /pgfplots/execute at begin axis@@/.add={% + % \def\b@pgfplotslibraryfill@added + % }{% + % + % },% + %-------------------------------------------------- +} + +\def\tikzlibraryfillbetween@parse#1 and #2\pgf@stop{% + \def\tikz@fillbetween@a{#1}% + \def\tikz@fillbetween@b{#2}% +}% + +% \tikzfillbetween[<options>]{<draw style>} +% +% <options> must contain 'of=<A> and <B>' and may configure how the +% area is computed. +% +% <draw style> affects every drawn region. +% +\def\tikzfillbetween{\pgfutil@ifnextchar[{\tikzfillbetween@opt}{\tikzfillbetween@opt[]}} +\def\tikzfillbetween@opt[#1]#2{% + \begingroup + \pgfqkeys{/tikz/fill between}{% + % prepare the low-level path generation instruction(s): + /tikz/fill between/@draw style={#2},% + % + % set up input options: + #1,% + }% + % automagically try to use the correct layer: + \pgfkeysgetvalue{/tikz/fill between/on layer}\tikzlibraryfillbetween@path@layer@name + \tikzlibraryfillbetween@determine@layer + % + \ifx\tikzlibraryfillbetween@path@layer@name\pgfutil@empty \else + \pgfonlayer{\tikzlibraryfillbetween@path@layer@name}% + \fi + % + \tikzlibraryfillbetween@path@generatepath + % + \ifx\tikzlibraryfillbetween@path@layer@name\pgfutil@empty \else + \endpgfonlayer% + \fi + % + \endgroup +}% + +% Defines \tikzlibraryfillbetween@path@layer@name +\def\tikzlibraryfillbetween@determine@layer{% + \ifx\tikzlibraryfillbetween@path@layer@name\pgfutil@empty + \else + \pgfutil@IfUndefined{pgf@layerlist}{% + % hm. No layers active!? A pity... + \tikzlibraryfillbetween@path@warn@layer + \let\tikzlibraryfillbetween@path@layer@name\pgfutil@empty% + }{% + \edef\pgfplots@loc@TMPa{\noexpand\pgfutil@in@{\tikzlibraryfillbetween@path@layer@name}}% + \expandafter\pgfplots@loc@TMPa\expandafter{\pgf@layerlist}% + \ifpgfutil@in@ + \else + \tikzlibraryfillbetween@path@warn@layer + \let\tikzlibraryfillbetween@path@layer@name\pgfutil@empty% + \fi + }% + \fi +}% + +\def\tikzlibraryfillbetween@path@warn@layer{% + \pgfplots@warning{'fill between': Could not activate graphics layer '\tikzlibraryfillbetween@path@layer@name'. Filled path will be on top of the other ones. Please ensure that '\tikzlibraryfillbetween@path@layer@name' is somewhere in the layer list (or set '/tikz/fill between/on layer=').}% +}% + +\def\tikzlibraryfillbetween@parse@softclip{% + \pgfkeysgetvalue{/tikz/fill between/soft clip first}\pgf@temp + \pgfkeysgetvalue{/tikz/fill between/soft clip second}\pgf@tempb + \ifx\pgf@temp\pgf@tempb + % Ah - both have the same value! + \ifx\pgf@temp\pgfutil@empty + % ... and both are empty. + \pgffillbetweensetsoftclippath{\pgfutil@empty}% + \else + % ... and both contain some path! Process it (once): + \def\tikz@marshal{\tikzlibsoftclip@setkey{\pgffillbetweensetsoftclippath}}% + \expandafter\tikz@marshal\pgf@temp\pgf@stop + \fi + \else + % handle 'soft clip first': + \ifx\pgf@temp\pgfutil@empty + \pgffillbetweensetsoftclippathfirst{\pgfutil@empty}% + \else + \def\tikz@marshal{\tikzlibsoftclip@setkey{\pgffillbetweensetsoftclippathfirst}}% + \expandafter\tikz@marshal\pgf@temp\pgf@stop + \fi + % + % handle 'soft clip second': + \pgfkeysgetvalue{/tikz/fill between/soft clip second}\pgf@tempb + \ifx\pgf@tempb\pgfutil@empty + \pgffillbetweensetsoftclippathsecond{\pgfutil@empty}% + \else + \def\tikz@marshal{\tikzlibsoftclip@setkey{\pgffillbetweensetsoftclippathsecond}}% + \expandafter\tikz@marshal\pgf@tempb\pgf@stop + \fi + \fi +}% + +\def\tikzlibraryfillbetween@path@generatepath{% + % + \tikzlibraryfillbetween@parse@softclip + % + \tikzlibraryfillbetween@path@check + \expandafter\let\expandafter\tikz@fillbetween@a@path + \csname tikz@intersect@path@name@\tikz@fillbetween@a\endcsname + \expandafter\let\expandafter\tikz@fillbetween@b@path + \csname tikz@intersect@path@name@\tikz@fillbetween@b\endcsname + % + \pgfpathfillbetween{\tikz@fillbetween@a@path}{\tikz@fillbetween@b@path}% +}% + +\def\tikzlibraryfillbetween@path@check{% + \pgfutil@IfUndefined{tikz@intersect@path@name@\tikz@fillbetween@a}{% + \pgferror + {fill between: the mandatory argument 'of=<name path A> and <name path B> is missing or has empty arguments. Please ensure that the option has been set and that both path names have been assigned (perhaps you need 'name path global=\tikz@fillbetween@a' somewhere?)}% + }{}% + \pgfutil@IfUndefined{tikz@intersect@path@name@\tikz@fillbetween@b}{% + \pgferror + {fill between: the mandatory argument 'of=<name path A> and <name path B> is missing or has empty arguments. Please ensure that the option has been set and that both path names have been assigned (perhaps you need 'name path global=\tikz@fillbetween@b' somewhere?)}% + }{}% +} + + +%----------------------------------------- +% +% Utilities to work with path segments +% +%----------------------------------------- + +% Defines \pgfretval such that it contains the named path '#1' +\def\tikzgetnamedpath#1{% + \pgfutil@IfUndefined{tikz@intersect@path@name@#1}{% + \pgferror{There is no named path called '#1'. Perhaps you misspelled it?}% + }{% + \expandafter\let\expandafter\pgfretval + \csname tikz@intersect@path@name@#1\endcsname + }% +}% + +\def\tikznamecurrentpath#1{% + \pgfgetpath\pgf@temp + \pgfprocessround\pgf@temp\pgf@tempb% + \expandafter\global\expandafter\let\csname tikz@intersect@path@name@#1\endcsname=\pgf@tempb +}% + +% --------------------------------------------------------------------------------------- + +\newif\iftikzpathsegments@reverse +\def\tikzlibrarysegments@parse#1 and #2\pgf@stop{% + \def\tikz@path@segments@a{#1}% + \def\tikz@path@segments@b{#2}% +}% + + +\pgfkeys{ + % allows to append intersection segments to the current path by + % writing + % \path[intersection segments={of=first and second, sequence=A0 -- B1 -- B3 A3[reverse] -- A1}]; + /tikz/intersection segments/.code={% + \tikzpathintersectionsegments[#1]% + }, + /tikz/segments/of/.code=\tikzlibrarysegments@parse#1\pgf@stop, + /tikz/segments/of={} and {}, + /tikz/segments/sequence/.initial=A0 -- B1, + /tikz/segments/reverse/.is if=tikzpathsegments@reverse, + /tikz/segments/reverse/.default=true, +} + +% Programmatic method to do the same as 'intersection +% segments={<options>} +% +% #1: <options> +\def\tikzpathintersectionsegments[#1]{% + \begingroup + \pgfqkeys{/tikz/segments}{#1}% + \tikzgetnamedpath{\tikz@path@segments@a}% + \let\tikz@path@segments@A=\pgfretval + \tikzgetnamedpath{\tikz@path@segments@b}% + \let\tikz@path@segments@B=\pgfretval + % + % this macro will be called whenever we need an intersection + % segment. Perhaps we do not need it at all + \def\tikz@ensurehascomputedintersection{% + % compute intersections using the PGF intersection lib... + \pgfintersectionofpaths{\pgfsetpath\tikz@path@segments@A}{\pgfsetpath\tikz@path@segments@B}% + % + % ... and compute the intersection *segments* for both input + % paths... + \pgfcomputeintersectionsegments1% + \pgfcomputeintersectionsegments2% + \let\tikz@ensurehascomputedintersection=\relax + }% + % + \pgfkeysgetvalue{/tikz/segments/sequence}\tikz@sequence + % + \def\b@tikz@isect@nextismoveto{1}% + \expandafter\tikzpathintersectionsegments@parse@loop\tikz@sequence\pgf@stop + \endgroup +}% + +\def\tikzpathintersectionsegments@parse@loop{% + \pgfutil@ifnextchar-{% + \tikz@isect@p@lineto + }{% + \pgfutil@ifnextchar A{% + \tikz@isect@p@next + }{% + \pgfutil@ifnextchar B{% + \tikz@isect@p@next + }{% + \pgfutil@ifnextchar\pgf@stop{% + \tikz@isect@finish + }{% + \tikz@isect@p@error + }% + }% + }% + }% +}% + +\def\tikz@isect@finish\pgf@stop{}% + +\def\tikz@isect@p@lineto--{% + \def\b@tikz@isect@nextismoveto{0}% + \tikzpathintersectionsegments@parse@loop +}% + +\def\tikz@isect@p@error#1\pgf@stop{% + \pgferror{The argument of 'sequence' has an unexpected format near '#1'. Please write something like A0 -- B1 -- A1}% +} + +\def\tikz@isect@p@next#1#2{% + \pgfutil@ifnextchar[{% + \tikz@isect@p@next@opt{#1}{#2}% + }{% + \tikz@isect@p@next@opt{#1}{#2}[]% + }% +}% +\def\tikz@isect@p@next@opt#1#2[#3]{% + \begingroup + % + % set keys (if any): + \def\tikz@temp{#3}% + \ifx\tikz@temp\pgfutil@empty + \else + \pgfqkeys{/tikz/segments}{#3}% + \fi + % + % parse arguments: + \edef\pgfmathresult{#2}% + \def\tikz@temp{*}% + \ifx\pgfmathresult\tikz@temp + \def\b@tikz@select@all{1}% + \else + \def\b@tikz@select@all{0}% + \tikz@ensurehascomputedintersection + \pgfmathparse{round(#2)}% + \let\tikz@index=\pgfmathresult + \fi + % + \if A#1% + \def\tikz@path{1}% + \else + \if B#1% + \def\tikz@path{2}% + \else + \def\tikz@path{}% + \pgferror{The argument of 'sequence' has an unexpected format near '#1#2': expected A#2 or B#2}% + \fi + \fi + % + % + % PROCESS IT: + \ifx\tikz@path\pgfutil@empty + \else + \if1\b@tikz@select@all% + % ok... select the *entire* path. + % #1 = A|B : + \expandafter\let\expandafter\pgfretval\csname tikz@path@segments@#1\endcsname + \else + \pgfgetintersectionsegmentpath{\tikz@path}{\tikz@index}% + \fi + \iftikzpathsegments@reverse + \pgf@reverse@path\pgfretval + \fi + \if0\b@tikz@isect@nextismoveto + \pgfpathreplacefirstmoveto\pgfretval + \fi + \pgfaddpathandBB\pgfretval + \fi + \endgroup + \def\b@tikz@isect@nextismoveto{1}% + \tikzpathintersectionsegments@parse@loop +}% + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplots.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplots.code.tex index ed2a7dabe4a..38c2f5c3578 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/pgfplots.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplots.code.tex @@ -571,7 +571,7 @@ /pgfplots/set layers*/.default={/pgfplots/layers/standard}, /pgfplots/@set layers arg/.initial=, /pgfplots/layers/.search also=/pgfplots, - /pgfplots/layers/standard/.define layer set={axis background,axis grid,axis ticks,axis lines,axis tick labels,main,axis descriptions,axis foreground}{ + /pgfplots/layers/standard/.define layer set={axis background,axis grid,axis ticks,axis lines,axis tick labels,pre main,main,axis descriptions,axis foreground}{ grid style= {/pgfplots/on layer=axis grid}, tick style= {/pgfplots/on layer=axis ticks}, axis line style= {/pgfplots/on layer=axis lines}, @@ -583,7 +583,7 @@ axis background@ style={/pgfplots/on layer=axis background}, 3d box foreground style={/pgfplots/on layer=axis foreground}, }, - /pgfplots/layers/axis on top/.define layer set={axis background,main,axis grid,axis ticks,axis lines,axis tick labels,axis descriptions,axis foreground}{ + /pgfplots/layers/axis on top/.define layer set={axis background,pre main,main,axis grid,axis ticks,axis lines,axis tick labels,axis descriptions,axis foreground}{ /pgfplots/layers/standard }, /pgfplots/on layer/.initial=, @@ -1916,7 +1916,9 @@ /pgfplots/execute at end plot@@/.initial=,% an internal variant /pgfplots/execute at end survey/.initial=,% /pgfplots/execute at begin axis/.initial=, + /pgfplots/execute at begin axis@@/.initial=,% an internal variant /pgfplots/execute at end axis/.initial=, + /pgfplots/execute at end axis@@/.initial=,% an internal variant /pgfplots/execute for finished point/.initial=, /pgfplots/before end axis/.code=, /pgfplots/after end axis/.code=, @@ -3641,6 +3643,7 @@ /pgfplots/compat/anchors/1.7/.style= {/pgfplots/compat/anchors/1.3},% /pgfplots/compat/anchors/1.8/.style= {/pgfplots/compat/anchors/1.3},% /pgfplots/compat/anchors/1.9/.style= {/pgfplots/compat/anchors/1.3},% + /pgfplots/compat/anchors/1.10/.style= {/pgfplots/compat/anchors/1.3},% /pgfplots/compat/anchors/newest/.style= {/pgfplots/compat/anchors/1.3},% /pgfplots/compat/anchors/default/.style={/pgfplots/compat/anchors/1.3},% % @@ -3654,6 +3657,7 @@ /pgfplots/compat/empty line/1.7/.style= {/pgfplots/compat/empty line/1.4},% /pgfplots/compat/empty line/1.8/.style= {/pgfplots/compat/empty line/1.4},% /pgfplots/compat/empty line/1.9/.style= {/pgfplots/compat/empty line/1.4},% + /pgfplots/compat/empty line/1.10/.style= {/pgfplots/compat/empty line/1.4},% /pgfplots/compat/empty line/newest/.style= {/pgfplots/compat/empty line/1.4},% /pgfplots/compat/empty line/default/.style= {/pgfplots/compat/empty line/1.4},% % @@ -3667,6 +3671,7 @@ /pgfplots/compat/path replacement/1.7/.style= {/pgfplots/compat/path replacement/1.5.1}, /pgfplots/compat/path replacement/1.8/.style= {/pgfplots/compat/path replacement/1.5.1}, /pgfplots/compat/path replacement/1.9/.style= {/pgfplots/compat/path replacement/1.5.1}, + /pgfplots/compat/path replacement/1.10/.style= {/pgfplots/compat/path replacement/1.5.1}, /pgfplots/compat/path replacement/newest/.style= {/pgfplots/compat/path replacement/1.5.1},% /pgfplots/compat/path replacement/default/.style= {/pgfplots/compat/path replacement/pre 1.3},% %ellipse/.is if=pgfplots@path@replace@ellipse, @@ -3690,6 +3695,7 @@ /pgfplots/compat/axis line style post 1.8, },% /pgfplots/compat/labels/1.9/.style= {/pgfplots/compat/labels/1.8},% + /pgfplots/compat/labels/1.10/.style= {/pgfplots/compat/labels/1.8},% /pgfplots/compat/labels/newest/.style= {/pgfplots/compat/labels/1.8},% /pgfplots/compat/labels/default/.style= {/pgfplots/compat/labels/pre 1.3},% maintain backwards compatibility % @@ -3727,6 +3733,7 @@ /pgfplots/nodes near coords ybar stacked configuration, }, },% + /pgfplots/compat/bar nodes/1.10/.style= {/pgfplots/compat/bar nodes/1.9},% /pgfplots/compat/bar nodes/newest/.style= {/pgfplots/compat/bar nodes/1.9},% /pgfplots/compat/bar nodes/default/.style= {/pgfplots/compat/bar nodes/pre 1.3},% maintain backwards compatibility /pgfplots/compat/bar nodes/default, @@ -3755,6 +3762,7 @@ /pgfplots/compat/scaling/1.7/.style={/pgfplots/compat/scaling/1.6}, /pgfplots/compat/scaling/1.8/.style={/pgfplots/compat/scaling/1.6}, /pgfplots/compat/scaling/1.9/.style={/pgfplots/compat/scaling/1.6}, + /pgfplots/compat/scaling/1.10/.style={/pgfplots/compat/scaling/1.6}, /pgfplots/compat/scaling/newest/.style={/pgfplots/compat/scaling/1.6}, /pgfplots/compat/scaling/default/.style={/pgfplots/compat/scaling/1.4}, % @@ -3768,6 +3776,7 @@ /pgfplots/compat/scale mode/1.7/.style={/pgfplots/compat/scale mode/1.6}, /pgfplots/compat/scale mode/1.8/.style={/pgfplots/compat/scale mode/1.6}, /pgfplots/compat/scale mode/1.9/.style={/pgfplots/compat/scale mode/1.6}, + /pgfplots/compat/scale mode/1.10/.style={/pgfplots/compat/scale mode/1.6}, /pgfplots/compat/scale mode/newest/.style={/pgfplots/compat/scale mode/1.6}, /pgfplots/compat/scale mode/default/.style={/pgfplots/compat/scale mode/1.5}, % @@ -3782,6 +3791,7 @@ /pgfplots/compat/plot3graphics/1.7/.style= {/pgfplots/compat/plot3graphics/1.6},% /pgfplots/compat/plot3graphics/1.8/.style= {/pgfplots/compat/plot3graphics/1.6},% /pgfplots/compat/plot3graphics/1.9/.style= {/pgfplots/compat/plot3graphics/1.6},% + /pgfplots/compat/plot3graphics/1.10/.style= {/pgfplots/compat/plot3graphics/1.6},% /pgfplots/compat/plot3graphics/newest/.style= {/pgfplots/compat/plot3graphics/1.6},% /pgfplots/compat/plot3graphics/default/.style= {/pgfplots/compat/plot3graphics/1.5},% % @@ -3822,6 +3832,7 @@ /pgfplots/compat/bar width by units/1.7/.code= {\def\b@pgfplots@compat@bar@width@units{0}},% /pgfplots/compat/bar width by units/1.8/.style= {/pgfplots/compat/bar width by units/1.7}, /pgfplots/compat/bar width by units/1.9/.style= {/pgfplots/compat/bar width by units/1.7}, + /pgfplots/compat/bar width by units/1.10/.style= {/pgfplots/compat/bar width by units/1.7}, /pgfplots/compat/bar width by units/newest/.style= {/pgfplots/compat/bar width by units/1.7}, /pgfplots/compat/bar width by units/default/.style={/pgfplots/compat/bar width by units/pre 1.3}, % @@ -3835,6 +3846,7 @@ /pgfplots/compat/BB/1.7/.style= {/pgfplots/compat/BB/pre 1.3},% /pgfplots/compat/BB/1.8/.style= {/pgfplots/clip bounding box=upper bound},% /pgfplots/compat/BB/1.9/.style= {/pgfplots/compat/BB/1.8},% + /pgfplots/compat/BB/1.10/.style= {/pgfplots/compat/BB/1.8},% /pgfplots/compat/BB/newest/.style= {/pgfplots/compat/BB/1.8}, /pgfplots/compat/BB/default/.style={/pgfplots/compat/BB/pre 1.3}, % @@ -3848,13 +3860,14 @@ /pgfplots/compat/general/1.7/.style= {/pgfplots/compat/general/1.5},% /pgfplots/compat/general/1.8/.style= {/pgfplots/compat/general/1.5},% /pgfplots/compat/general/1.9/.style= {/pgfplots/compat/general/1.5},% + /pgfplots/compat/general/1.10/.style= {/pgfplots/compat/general/1.5},% /pgfplots/compat/general/newest/.style= {/pgfplots/compat/general/1.8}, /pgfplots/compat/general/default/.style={/pgfplots/compat/general/1.5}, % /pgfplots/compat/show suggested version/.is if=pgfplots@show@suggested@version, /pgfplots/compat/show suggested version=true, /pgfplots/compat/current/.initial=, - /pgfplots/compat/mostrecent/.initial=1.9, + /pgfplots/compat/mostrecent/.initial=1.10, % this is OK since 1.10 did not change anything. /pgfplots/compat/.style={% % ATTENTION: *every* /pgfplots/compat/ setting needs to accept % the same choices due to this construction: @@ -4125,7 +4138,13 @@ \draw[/pgfplots/every inner #1 axis line,% decorate,% #1discont,% - decoration={pre length=\csname #1disstart\endcsname, post length=\csname #1disend\endcsname}] + decoration={% + % these keys appears to be checked via an \ifx on + % '0pt'. Make sure that this \ifx works by means of + % the expand twice construction: + pre length/.expand twice=\csname #1disstart\endcsname,% + post length/.expand twice=\csname #1disend\endcsname% + }] \pgfextra \csname pgfplotspointonorientedsurfaceabsetupforset#3\endcsname{\csname pgfplots@logical@ZERO@#3\endcsname}{2}% \pgfpathmoveto{\pgfplotspointonorientedsurfaceab{\csname pgfplots@#1min\endcsname}{\csname pgfplots@logical@ZERO@#2\endcsname}}% @@ -4145,7 +4164,7 @@ % centered axis lines handled elsewhere. \else \scope[/pgfplots/every outer #1 axis line, - #1discont,decoration={pre length=\csname #1disstart\endcsname, post length=\csname #1disend\endcsname}] + #1discont,decoration={pre length/.expand twice=\csname #1disstart\endcsname, post length/.expand twice=\csname #1disend\endcsname}] \pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn{0}{% \draw decorate { \pgfextra @@ -5023,9 +5042,7 @@ \pgfplotsutil@advancestringcounter@global\c@pgfplots@label }% % - % this is a work-around to support the memoir class (it overwrites - % \label in sub - \let\sf@@memsub@label=\pgfplots@original@LaTeX@label@loadtime + \pgfplots@label@configure@package@workarounds % \pgfutil@IfUndefined{label}{% }{% @@ -5037,6 +5054,26 @@ \gdef\c@pgfplots@label{0}% \def\theHpgfplotslink{\theHsection.\c@pgfplots@label}% +\def\pgfplots@label@configure@package@workarounds{% + % this is a work-around to support the memoir class (it overwrites + % \label in sub + \let\sf@@memsub@label=\pgfplots@original@LaTeX@label@loadtime + % + \ifx\label\mcaption@label + % this is a work-around to support the mcaption class: it + % simply remembers the label name and invokes \label later-on. + % This appears to be wrong in this context: I want to generate + % a pgfplots label. + % + % If someone writes \label{fig:one}, that label will be + % redeclared in the margin - which appears to be correct. And + % that will still work. + % + % This here will activate pgfplots' labels: + \let\label=\pgfplots@original@LaTeX@label@loadtime + \fi +} + % this is deprecated. Use \ref{#1} instead. \def\pgfplotslegendfromname#1{% \pgfplots@texdist@protect\pgfplotslegendfromname@{#1}% @@ -9453,6 +9490,7 @@ }% \def\pgfplots@set@options#1{% + \pgfplots@check@global@colorspace@overrides \pgfplots@bb@isactivetrue \pgfplots@curplot@threedimfalse \global\pgfplots@threedimfalse @@ -9696,11 +9734,46 @@ \pgfkeyslet{/tikz/on layer}\pgfutil@empty% }% % + \pgfplots@set@patched@options + % \pgfplots@set@options@sanitize - \pgfplots@check@global@colorspace@overrides \pgfplots@notify@options@are@set } +\def\pgfplots@set@patched@options{% + \pgfkeysdef{/pgfplots/@@@tmp}{% + \let\tikz@intersect@def=\gdef + \pgfkeys{/tikz/name path={##1}}% + }% + \pgfkeysgetvalue{/pgfplots/@@@tmp/.@cmd}\pgfplots@name@path@global@cmd@pgf@two@ten + % + \pgfkeysifdefined{/tikz/name path/.@cmd}{% + % 'name path' does not work inside of a pgfplots axis because + % pgfplots unnecessarily introduces extra \scopes around each path :-/ + % it needs to be 'name path global'. + % PATCH IT: + \pgfkeysgetvalue{/tikz/name path global/.@cmd}\pgfplots@loc@TMPa% + \ifx\pgfplots@loc@TMPa\pgfplots@name@path@global@cmd@pgf@two@ten + % ah - we operate against PGF 2.10 . In this case, we must + % not indirect from 'name path' to 'name path global' - would lead to + % an indefinite loop. + % Patch absolutely: + \pgfkeysgetvalue{/tikz/name path/.@cmd}\pgfplots@name@path@cmd@pgf@two@ten% + \pgfkeysdef{/tikz/name path}{% + % see the value of + % \pgfplots@name@path@global@cmd@pgf@two@ten to verify + % this patch: + \let\tikz@intersect@def=\gdef + \pgfplots@name@path@cmd@pgf@two@ten{##1}\pgfeov + }% + \else + \pgfkeysdef{/tikz/name path}{\pgfkeysalso{/tikz/name path global={##1}}}% + \fi + }{% + \pgfkeysdef{/tikz/name path}{\pgfplots@error{'name path' is undefined. Please load \string\usetikzlibrary{intersections} or \string\usepgfplotslibrary{fillbetween}}}% + }% +} + % EMPTY. This will be overridden by tex-engine specific code. % At the time of this writing, the latex driver will check for xcolor % configuration options and will override @@ -9987,19 +10060,23 @@ \def\pgfplots@interruptdatabb{\pgfplots@bb@isactivefalse} \def\endpgfplots@interruptdatabb{\pgfplots@bb@isactivetrue} +\def\pgfplots@search@also@tikz{% + % make sure the search path is set. + % Inside of an axis, this is already ok. + \pgfkeysifdefined{/pgfplots/.unknown/.@cmd}% + {\relax}% search path in /pgfplots is already set + {% +%\message{DEBUG: re-initializing /pgfplots/.search also=/tikz in current plot style!}% + \pgfkeysalso{/pgfplots/.search also=/tikz}% + }% +}% + % A helper method which defines % `/tikz/current plot style' to be {#1} --- with properly set key % search paths. \def\pgfplots@define@currentplotstyle@as#1{% \pgfkeysdef{/tikz/current plot style}{% - % make sure the search path is set. - % Inside of an axis, this is already ok. - \pgfkeysifdefined{/pgfplots/.unknown/.@cmd}% - {\relax}% search path in /pgfplots is already set - {% -%\message{DEBUG: re-initializing /pgfplots/.search also=/tikz in current plot style!}% - \pgfkeysalso{/pgfplots/.search also=/tikz}% - }% + \pgfplots@search@also@tikz % % Make sure that % \addplot[every mark/.append style={...}] @@ -10416,22 +10493,10 @@ % defines \pgfplotsaxisupdatelimitsforcoordinate etc. \pgfplots@prepare@axis@API \pgfkeysvalueof{/pgfplots/execute at begin axis}% + \pgfkeysvalueof{/pgfplots/execute at begin axis@@}% \def\pgfplots@phase@name{s}% % - \let\pgfplots@orig@scope=\scope - \let\pgfplots@orig@endscope=\endscope - \let\scope=\pgfplots@replacement@for@scope - \let\endscope=\pgfplots@replacement@for@endscope - % - \let\pgfplots@orig@pgfonlayer=\pgfonlayer - \let\pgfplots@orig@endpgfonlayer=\endpgfonlayer - \let\pgfonlayer=\pgfplots@replacement@for@onlayer - \let\endpgfonlayer=\pgfplots@replacement@for@endonlayer - % - \let\pgfplots@orig@pgfplotsonlayer=\pgfplotsonlayer - \let\pgfplots@orig@endpgfplotsonlayer=\endpgfplotsonlayer - \let\pgfplotsonlayer=\pgfplots@replacement@for@onlayer - \let\endpgfplotsonlayer=\pgfplots@replacement@for@endonlayer + \pgfplots@replace@path@commands % % allow layer changes within the environment; reset: \pgfkeyslet{/pgfplots/on layer}\pgfutil@empty @@ -10450,16 +10515,9 @@ \xdef\numplots{\the\pgfplots@numplots}% \pgfkeysvalueof{/pgfplots/before end axis/.@cmd}\pgfeov% \pgfkeysvalueof{/pgfplots/execute at end axis}% + \pgfkeysvalueof{/pgfplots/execute at end axis@@}% % - % restore old \path command: - \let\path=\pgfplots@orig@path - \let\plot=\pgfplots@orig@plot - \let\scope=\pgfplots@orig@scope - \let\endscope=\pgfplots@orig@endscope - \let\pgfonlayer=\pgfplots@orig@pgfonlayer - \let\endpgfonlayer=\pgfplots@orig@endpgfonlayer - \let\pgfplotsonlayer=\pgfplots@orig@pgfplotsonlayer - \let\endpgfplotsonlayer=\pgfplots@orig@endpgfplotsonlayer + \pgfplots@restore@path@commands % \pgfplotssurveyphase@setactiveplothandlers % @@ -10597,6 +10655,35 @@ \aftergroup\pgfplots@cell@picture@remembered } +\def\pgfplots@replace@path@commands{% + \let\pgfplots@orig@scope=\scope + \let\pgfplots@orig@endscope=\endscope + \let\scope=\pgfplots@replacement@for@scope + \let\endscope=\pgfplots@replacement@for@endscope + % + \let\pgfplots@orig@pgfonlayer=\pgfonlayer + \let\pgfplots@orig@endpgfonlayer=\endpgfonlayer + \let\pgfonlayer=\pgfplots@replacement@for@onlayer + \let\endpgfonlayer=\pgfplots@replacement@for@endonlayer + % + \let\pgfplots@orig@pgfplotsonlayer=\pgfplotsonlayer + \let\pgfplots@orig@endpgfplotsonlayer=\endpgfplotsonlayer + \let\pgfplotsonlayer=\pgfplots@replacement@for@onlayer + \let\endpgfplotsonlayer=\pgfplots@replacement@for@endonlayer +}% + +\def\pgfplots@restore@path@commands{% + % restore old \path command: + \let\path=\pgfplots@orig@path + \let\plot=\pgfplots@orig@plot + \let\scope=\pgfplots@orig@scope + \let\endscope=\pgfplots@orig@endscope + \let\pgfonlayer=\pgfplots@orig@pgfonlayer + \let\endpgfonlayer=\pgfplots@orig@endpgfonlayer + \let\pgfplotsonlayer=\pgfplots@orig@pgfplotsonlayer + \let\endpgfplotsonlayer=\pgfplots@orig@endpgfplotsonlayer +} + % visualizes selected phases. % % #1 a comma-separated list of selected phases. May be empty. diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplots.revision.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplots.revision.tex index 7268171ec4b..15c577d4957 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/pgfplots.revision.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplots.revision.tex @@ -5,10 +5,10 @@ \catcode`\:=12 \catcode`\+=12 \catcode`\-=12 -\gdef\pgfplotsrevision{1.9} -\gdef\pgfplotsversion{1.9} -\gdef\pgfplotsversiondatetime{2013-10-03 13:31:02 +0200} -\gdef\pgfplotsrevisiondatetime{2013-10-03 13:31:02 +0200} +\gdef\pgfplotsrevision{1.10-2-gb39fe75} +\gdef\pgfplotsversion{1.10} +\gdef\pgfplotsversiondatetime{2014-02-28 13:30:07 +0100} +\gdef\pgfplotsrevisiondatetime{2014-03-03 21:18:27 +0100} \gdef\pgfplots@glob@TMPa#1-#2-#3 #4\relax{#1/#2/#3} \xdef\pgfplotsversiondate{\expandafter\pgfplots@glob@TMPa\pgfplotsversiondatetime\relax} \xdef\pgfplotsrevisiondate{\expandafter\pgfplots@glob@TMPa\pgfplotsrevisiondatetime\relax} diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplots.scaling.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplots.scaling.code.tex index 478c3fe2bef..a1b51498005 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/pgfplots.scaling.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplots.scaling.code.tex @@ -526,15 +526,19 @@ \def\pgfplots@scaleaxes@to@BB@prepare@plotbox@limits@#1{% \expandafter\ifx\csname pgfplots@#1\endcsname\pgfutil@empty + % Ah - we have no unit vector in this direction. \expandafter\def\csname pgfplots@plotbox@#1min\endcsname{0}% \expandafter\def\csname pgfplots@plotbox@#1max\endcsname{1}% \expandafter\def\csname b@pgfplots@plotbox@#1isunit\endcsname{1}% \else + % we have a unit vector... prepare for limits. Note that the + % unit vector has been prepared for data scaling already. \pgfutil@namelet{pgfplots@plotbox@#1min}{pgfplots@#1min}% \pgfutil@namelet{pgfplots@plotbox@#1max}{pgfplots@#1max}% \expandafter\def\csname b@pgfplots@plotbox@#1isunit\endcsname{0}% \if2\pgfplots@scale@mode@choice % scale mode=stretch to fill + % do NOT rescale unit vectors for stretch to fill : \expandafter\def\csname b@pgfplots@rescale@#1\endcsname{0}% \fi \fi @@ -549,6 +553,7 @@ \def\pgfplots@scaleaxes@to@BB@#1#2{% \begingroup +%\message{SCALING: scale mode choice = \pgfplots@scale@mode@choice^^J}% % \pgfplots@scaleaxes@to@BB@prepare@plotbox@limits \def\pgfplots@target@limitrescale@x{1}% diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex index 5692a8abc79..02ff3e96b1b 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex @@ -28,6 +28,8 @@ % - coordinate input: \addplot and its variants, % - coordinate loops, % - single coordinate processing +% +% -> see \pgfplots@addplot % To be called inside of an axis as soon as the axis is ready and all @@ -3345,7 +3347,10 @@ % #1,#2: see \pgfplots@PREPARE@COORD@STREAM \def\pgfplots@PREPARE@COORD@STREAM@end@#1{% \pgfkeysvalueof{/pgfplots/execute at end survey}% + % FIXME : move this the \pgfplotsplothandlersurveyend of mesh plot + % handler: \pgfkeyssetvalue{/pgfplots/mesh/num points}{\pgfplots@current@point@coordindex}% + % \pgfplotsplothandlersurveyend \ifx\pgfplots@metamin\pgfutil@empty \else @@ -3394,15 +3399,9 @@ \pgfplotspreparemeshkeydefaults% \pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting x% \pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting y% - \t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,% - /pgfplots/.cd,/pgfplots/every axis plot post}% - \edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}% - \ifpgfplots@curplot@isirrelevant - % for \label commands: - \expandafter\pgfplots@rememberplotspec@for@label\expandafter{\pgfplots@addplot@survey@@optionlist}% - \else - \expandafter\pgfplots@rememberplotspec\expandafter{\pgfplots@addplot@survey@@optionlist}% - \fi + % + \pgfplots@remember@survey@option@list + % % warning: rememberplotspec calls list macros which % overwrite \t@pgfplots@toka \t@pgfplots@toka=\expandafter{\pgfplots@addplot@survey@@optionlist}% @@ -3507,6 +3506,18 @@ \pgfplots@end@plot }% +\def\pgfplots@remember@survey@option@list{% + \t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,% + /pgfplots/.cd,/pgfplots/every axis plot post}% + \edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}% + \ifpgfplots@curplot@isirrelevant + % for \label commands: + \expandafter\pgfplots@rememberplotspec@for@label\expandafter{\pgfplots@addplot@survey@@optionlist}% + \else + \expandafter\pgfplots@rememberplotspec\expandafter{\pgfplots@addplot@survey@@optionlist}% + \fi +}% + % Defines \pgfplotsretval to contain a comma-separated-list of % visualization phase names. May be empty. % @@ -4521,6 +4532,39 @@ }% }% % + \pgfplots@start@plot@with@behavioroptions@setkeys{#1}% + % + % enable FPU after any \pgfplotsset operations. Otherwise things like + % linewidth=... which use the math parser might fail. + \ifpgfplots@usefpu + \pgfkeys{/pgf/fpu=true}% + \fi + % + % make sure it is reset, just in case it is not supported by the + % input method. + \pgfplotsscanlinelengthinitzero + % + \pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler + \pgfplotsresetplothandler + \pgfplots@basiclevel@plothandler + % + \pgfplots@countplots@init + % + % hooks: + \pgfkeysvalueof{/pgfplots/execute at begin plot@@}% + \pgfkeysvalueof{/pgfplots/execute at begin plot}% + % + \if1\pgfplots@colorbar@set@src + \t@pgfplots@tokc={/pgfplots/point meta rel=per plot}% + \t@pgfplots@toka=\expandafter{\pgfplots@addplot@survey@@optionlist}% + \edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc,\the\t@pgfplots@toka}% + \fi + % + % + \pgfplots@validate@plot@domain@arguments +} + +\def\pgfplots@start@plot@with@behavioroptions@setkeys#1{% % these styles may contain behavior options (error bars, % samples,... ) activate them! % @@ -4561,36 +4605,9 @@ \pgfplotsset{/pgfplots/every axis plot no \the\pgfplots@numplots/.try,/pgfplots/every axis plot post}% \fi % - % enable FPU after any \pgfplotsset operations. Otherwise things like - % linewidth=... which use the math parser might fail. - \ifpgfplots@usefpu - \pgfkeys{/pgf/fpu=true}% - \fi - % - % make sure it is reset, just in case it is not supported by the - % input method. - \pgfplotsscanlinelengthinitzero - % - \pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler - \pgfplotsresetplothandler - \pgfplots@basiclevel@plothandler - % - \pgfplots@countplots@init - % - % hooks: - \pgfkeysvalueof{/pgfplots/execute at begin plot@@}% - \pgfkeysvalueof{/pgfplots/execute at begin plot}% - % - \if1\pgfplots@colorbar@set@src - \expandafter\def\expandafter\pgfplots@addplot@survey@@optionlist\expandafter{\pgfplots@addplot@survey@@optionlist,% - /pgfplots/point meta rel=per plot}% - \fi - % \t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,#1}% this allows '#' inside of '#1' \edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}% % - % - \pgfplots@validate@plot@domain@arguments } \long\def\pgfplotssurveyphaseaddoptionsbeforesurveybegins#1{% @@ -4743,12 +4760,43 @@ } \long\def\pgfplots@addplotimpl@f#1#2f{% \pgfplotsutil@ifnextchar i{% - \pgfplots@addplotimpl@file{#1}{#2}% + \pgfplots@addplotimpl@fil{#1}{#2}% }{% \pgfplots@addplotimpl@function{#1}{#2}% }% }% +\long\def\pgfplots@addplotimpl@fil#1#2il{% + \pgfplotsutil@ifnextchar e{% + \pgfplots@addplotimpl@file{#1}{#2}% + }{% + \pgfplots@addplotimpl@fillbetween{#1}{#2}% + }% +}% + +\def\pgfplots@addplotimpl@fillbetween#1#2l between{% + \pgfplotsutil@ifnextchar[{% + \pgfplots@addplotimpl@fillbetween@opt{#1}{#2}% + }{% + \pgfplots@addplotimpl@fillbetween@opt{#1}{#2}[]% + }% +} +% \addplot[#1] [#2] fill between[#3] #4; +\long\def\pgfplots@addplotimpl@fillbetween@opt#1#2[#3]#4;{\pgfplots@addplotimpl@fillbetween@opt@{#1}{#2}{#3}{#4}}% + +\long\def\pgfplots@addplotimpl@fillbetween@opt@#1#2#3#4{% + \pgfkeysifdefined{/tikz/fill between/of/.@cmd}{% + \pgfplotslibraryfillbetween@addplot{#1,#2}{#3}{#4}% + }{% + \pgfplotsthrow{invalid argument} + {\pgfplots@loc@TMPa}% + {Please load \string\usepgfplotslibrary{fillbetween} in order to use `\string\addplot\space fill between'.}% + \pgfeov + }% + % + \pgfplots@end@plot% +}% + \def\pgfplots@gobble@until@semicolon#1;{} % PRECONDITION: @@ -5494,7 +5542,7 @@ } % \addplot[#1] [#2] file{#3} #4; -\def\pgfplots@addplotimpl@file#1#2ile{% +\def\pgfplots@addplotimpl@file#1#2e{% \pgfplotsutil@ifnextchar[{% \pgfplots@addplotimpl@file@opt{#1}{#2}% }{% @@ -6452,6 +6500,7 @@ \let\pgfplots@addplotimpl@expression@curly@IS=\pgfplots@addplotimpl@expression@curly \let\pgfplots@addplotimpl@function@opt@IS=\pgfplots@addplotimpl@function@opt \let\pgfplots@addplotimpl@file@opt@IS=\pgfplots@addplotimpl@file@opt + \let\pgfplots@addplotimpl@fillbetween@opt@IS=\pgfplots@addplotimpl@fillbetween@opt \let\pgfplots@addplotimpl@table@fromstructure@IS=\pgfplots@addplotimpl@table@fromstructure \let\pgfplots@addplotimpl@table@fromfile@IS=\pgfplots@addplotimpl@table@fromfile \let\pgfplots@addplotimpl@graphics@IS=\pgfplots@addplotimpl@graphics@ @@ -6462,6 +6511,7 @@ \long\def\pgfplots@addplotimpl@expression@curly@AS#1#2#3#4;{\pgfplots@addplotimpl@expression@curly@{#1}{#2}{#3}{#4}}% \def\pgfplots@addplotimpl@function@opt@AS#1#2[#3]#4#5;{\pgfplots@addplotimpl@function@opt@{#1}{#2}{#3}{#4}{#5}}% \def\pgfplots@addplotimpl@file@opt@AS#1#2[#3]#4#5;{\pgfplots@addplotimpl@file@opt@{#1}{#2}{#3}{#4}{#5}}% + \long\def\pgfplots@addplotimpl@fillbetween@opt@AS#1#2[#3]#4;{\pgfplots@addplotimpl@fillbetween@opt@{#1}{#2}{#3}{#4}}% \long\def\pgfplots@addplotimpl@table@fromstructure@AS#1#2from#3#4;{\pgfplots@addplotimpl@table@startprocessing{#1}{#2}{#3}{#4}}% \long\def\pgfplots@addplotimpl@table@fromfile@AS#1#2#3#4;{\pgfplots@addplotimpl@table@startprocessing{#1}{#2}{#3}{#4}}% \long\def\pgfplots@addplotimpl@coordinates@AS#1#2plot coordinates#3#4;{\pgfplots@addplotimpl@coordinates@{#1}{#2}{#3}{#4}}% @@ -6475,6 +6525,7 @@ \let\pgfplots@addplotimpl@expression@curly=\pgfplots@addplotimpl@expression@curly@AS \let\pgfplots@addplotimpl@function@opt=\pgfplots@addplotimpl@function@opt@AS \let\pgfplots@addplotimpl@file@opt=\pgfplots@addplotimpl@file@opt@AS + \let\pgfplots@addplotimpl@fillbetween@opt=\pgfplots@addplotimpl@file@opt@AS \let\pgfplots@addplotimpl@table@fromstructure=\pgfplots@addplotimpl@table@fromstructure@AS \let\pgfplots@addplotimpl@table@fromfile=\pgfplots@addplotimpl@table@fromfile@AS \let\pgfplots@addplotimpl@coordinates=\pgfplots@addplotimpl@coordinates@AS @@ -6922,91 +6973,47 @@ %\message{NO cache hit for \string\pgfplotspointplotattime{#1}^^J}% \begingroup % + % + \edef\pgfplots@time{#1}% + \pgfplotscoordmathparsemacro{default}{\pgfplots@time}% \pgfkeysgetvalue{/tikz/pos segment}\pgfplots@pos@segment % - % 1. compute the total length of the plot (by integrating along a linear spline) +\iffalse + % this here is a simple experiment which finds x or y + % values. IMPLEMENT IT! + \def\pgfplotspointattime@do@set@current@value{% + \pgfplotscoordmath{default}{parsenumber}{\pgfplots@current@point@y}% + \let\pgfplotspointattime@value@current=\pgfmathresult + }% + \def\pgfplotspointattime@do@set@target@value{% + \let\pgfplotspointattime@value@target=\pgfplots@time + }% + \def\pgfplots@ifpointattime@do@set@current@value@accumulates##1##2{##2}% +\fi % - \def\pgfplots@coord@stream@start@{% - \ifx\pgfplots@pos@segment\pgfutil@empty - \let\c@pgfplots@segments=\pgfutil@empty - \else - \def\c@pgfplots@segments{0}% - \c@pgf@countd=\pgfplots@pos@segment\relax - \edef\pgfplots@pos@segment{\the\c@pgf@countd}% - \fi - \pgfplotscoordmath{default}{zero}% - \let\pgfplots@len@total=\pgfmathresult - \let\pgfplots@last@processed=\pgfutil@empty - \def\pgfplots@last@was@empty{1}% - }% - \def\pgfplotspointattime@do{}% - \def\pgfplots@coord@stream@coord@{% -%\message{plot at time (#1, segment \pgfplots@pos@segment): processing (\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z)^^J}% - \ifx\pgfplots@current@point@x\pgfutil@empty - \if1\pgfplots@last@was@empty - \else - % oh. a jump... start new length segment - \ifx\c@pgfplots@segments\pgfutil@empty - \else - \ifx\pgfplots@pos@segment\c@pgfplots@segments - \let\pgfplots@coord@stream@coord@=\relax - \fi - \pgfplotsutil@advancestringcounter\c@pgfplots@segments - \fi - \fi - \let\pgfplots@last@processed=\pgfutil@empty - \def\pgfplots@last@was@empty{1}% - \else - \ifx\pgfplots@pos@segment\c@pgfplots@segments - \ifx\pgfplots@last@processed\pgfutil@empty - \else - \pgfplotsplothandlerserializepointto{\pgfplots@cur}% - \pgfplotsplothandlersurveydifflen{\pgfplots@last@processed}{\pgfplots@cur}% - \pgfplotscoordmath{default}{op}{add}{{\pgfmathresult}{\pgfplots@len@total}}% - \let\pgfplots@len@total=\pgfmathresult -%\message{plot at time (#1, segment \pgfplots@pos@segment): length \pgfplots@len@total^^J}% - \pgfplotspointattime@do - \fi - % - \pgfplotsplothandlerserializepointto{\pgfplots@last@processed}% - \fi - \def\pgfplots@last@was@empty{0}% - \fi - }% + \let\pgfplotspointattime@do=\relax + \let\pgfplots@coord@stream@start@=\pgfplots@coord@stream@start@plot@at@time + \let\pgfplots@coord@stream@coord@=\pgfplots@coord@stream@coord@plot@at@time \def\pgfplots@coord@stream@end@{}% - \let\pgfplots@coord@stream@coord@orig=\pgfplots@coord@stream@coord@ - \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@plot@timer@args}% - % - % Now, we have the total length. Now, try to find time #1! - \edef\pgfplots@time{#1}% - \pgfplotscoordmathparsemacro{default}{\pgfplots@time}% + \pgfplots@ifpointattime@do@set@current@value@accumulates{% + % 1. compute the total length of the plot (by integrating along a linear spline) + % + % we need to compute the TOTAL length in order to set the + % target values. + \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@plot@timer@args}% + }{}% % - \pgfplotscoordmath{default}{op}{multiply}{{\pgfplots@time}{\pgfplots@len@total}}% - \let\pgfplots@len@thresh=\pgfmathresult + \pgfplotspointattime@do@set@target@value % \pgfplotscoordmath{default}{zero}% \let\pgfplots@len@last=\pgfmathresult \let\pgfplots@len@last@last=\pgfplots@len@last -%\message{plot at time (#1, segment \pgfplots@pos@segment): total length=\pgfplots@len@total; target len \pgfplots@len@thresh\space (#1)^^J}% +%\message{plot at time (#1, segment \pgfplots@pos@segment): total length=\pgfplotspointattime@value@current; target len \pgfplotspointattime@value@target\space (#1)^^J}% % \def\pgfplots@HIT{0}% \let\pgfplots@last@last=\pgfutil@empty - \let\pgfplots@coord@stream@coord@=\pgfplots@coord@stream@coord@orig - \def\pgfplotspointattime@do{% - \pgfplotscoordmath{default}{if less than} - {\pgfplots@len@thresh} - {\pgfplots@len@total} - {% HIT! - \def\pgfplots@HIT{1}% - \pgfplotspointattime@pointbetween@two - \let\pgfplots@coord@stream@coord@=\relax - }{% - }% - \let\pgfplots@len@last@last=\pgfplots@len@last - \let\pgfplots@len@last=\pgfplots@len@total - \let\pgfplots@last@last=\pgfplots@last@processed - \pgfplotsplothandlerserializepointto{\pgfplots@cur}% - }% + \let\pgfplots@coord@stream@coord@=\pgfplots@coord@stream@coord@plot@at@time + \let\pgfplotspointattime@do=\pgfplotspointattime@do@find@target@value \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@plot@timer@args}% \if\pgfplots@HIT0% \let\pgfplots@last@processed=\pgfplots@last@last @@ -7031,14 +7038,130 @@ \pgfplotsplothandlerpointtokeys{/data point}% \fi } + +% coordinate streaming method for use in +% \pgfplotspointplotattime +\def\pgfplots@coord@stream@start@plot@at@time{% + \ifx\pgfplots@pos@segment\pgfutil@empty + \let\c@pgfplots@segments=\pgfutil@empty + \else + \def\c@pgfplots@segments{0}% + \c@pgf@countd=\pgfplots@pos@segment\relax + \edef\pgfplots@pos@segment{\the\c@pgf@countd}% + \fi + \pgfplotscoordmath{default}{zero}% + \let\pgfplotspointattime@value@current=\pgfmathresult + \let\pgfplots@last@processed=\pgfutil@empty + \def\pgfplots@last@was@empty{1}% +}% + + +% coordinate streaming method for use in +% \pgfplotspointplotattime +% +% It invokes \pgfplotspointattime@do{} whenever is has found a line +% segment. +\def\pgfplots@coord@stream@coord@plot@at@time{% +%\message{plot at time (#1, segment \pgfplots@pos@segment): processing (\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z)^^J}% + \ifx\pgfplots@current@point@x\pgfutil@empty + \if1\pgfplots@last@was@empty + \else + % oh. a jump... start new length segment + \ifx\c@pgfplots@segments\pgfutil@empty + \else + \ifx\pgfplots@pos@segment\c@pgfplots@segments + \let\pgfplots@coord@stream@coord@=\relax + \fi + \pgfplotsutil@advancestringcounter\c@pgfplots@segments + \fi + \fi + \let\pgfplots@last@processed=\pgfutil@empty + \def\pgfplots@last@was@empty{1}% + \else + \ifx\pgfplots@pos@segment\c@pgfplots@segments + \pgfplotsplothandlerserializepointto{\pgfplots@cur}% + \pgfplotspointattime@do@set@current@value + % + \ifx\pgfplots@last@processed\pgfutil@empty + \else + \pgfplotspointattime@do + \fi + % + \let\pgfplots@len@last@last=\pgfplots@len@last + \let\pgfplots@len@last=\pgfplotspointattime@value@current + \let\pgfplots@last@last=\pgfplots@last@processed + \let\pgfplots@last@processed=\pgfplots@cur + \fi + \def\pgfplots@last@was@empty{0}% + \fi +}% + +% A macro which is invoked whenever \pgfplotspointplotattime found a +% line segment. +% +% INPUT: +% - \pgfplots@cur : serialized current point. This current point's +% properties are available in the macros +% \pgfplots@current@point@[xyz] etc. +% - \pgfplots@last@processed : serialized last point +% - \pgfplotspointattime@value@current : the accumulated length so far +% +\def\pgfplotspointattime@do{} + +% \pgfplots@ifpointattime@do@set@current@value@accumulates{<true code>}{<false code>} +% +% is invokes to test if \pgfplotspointattime@do@set@current@value +% accumulates stuff. If so, it will invoke <true code>. If it does NOT +% accumulate stuff, it will invoke <false code> +\def\pgfplots@ifpointattime@do@set@current@value@accumulates#1#2{% + % the default "time fraction" implementation accumulates: + #1\relax +} + +\def\pgfplotspointattime@do@set@current@value{% + \ifx\pgfplots@last@processed\pgfutil@empty + \else + \pgfplotsplothandlersurveydifflen{\pgfplots@last@processed}{\pgfplots@cur}% + \pgfplotscoordmath{default}{op}{add}{{\pgfmathresult}{\pgfplotspointattime@value@current}}% + \let\pgfplotspointattime@value@current=\pgfmathresult + \fi +%\message{plot at time (#1, segment \pgfplots@pos@segment): length \pgfplotspointattime@value@current^^J}% +}% + +% Needs to define \pgfplotspointattime@value@target . +% +% This value is the search target: once the loop realizes that it +% passed \pgfplotspointattime@value@target, it will report a hit in the current +% interval. +\def\pgfplotspointattime@do@set@target@value{% + \pgfplotscoordmath{default}{op}{multiply}{{\pgfplots@time}{\pgfplotspointattime@value@current}}% + \let\pgfplotspointattime@value@target=\pgfmathresult +}% + +\def\pgfplotspointattime@do@find@target@value{% + % compare \pgfplotspointattime@value@target and \pgfplotspointattime@value@current to see if + % we passed the target interval: + \pgfplotscoordmath{default}{if less than} + {\pgfplotspointattime@value@target} + {\pgfplotspointattime@value@current} + {% HIT! + \def\pgfplots@HIT{1}% + \pgfplotspointattime@pointbetween@two + % + % we cannot stop the loop; what we can turn it into no-op: + \let\pgfplots@coord@stream@coord@=\relax + }{% + }% +}% + \def\pgfplotspointattime@pointbetween@two{% - \pgfplotscoordmath{default}{op}{subtract}{{\pgfplots@len@thresh}{\pgfplots@len@last}}% + \pgfplotscoordmath{default}{op}{subtract}{{\pgfplotspointattime@value@target}{\pgfplots@len@last}}% \let\pgfplots@tmp=\pgfmathresult - \pgfplotscoordmath{default}{op}{subtract}{{\pgfplots@len@total}{\pgfplots@len@last}}% + \pgfplotscoordmath{default}{op}{subtract}{{\pgfplotspointattime@value@current}{\pgfplots@len@last}}% \pgfplotscoordmath{default}{op}{divide}{{\pgfplots@tmp}{\pgfmathresult}}% \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% \let\pgfplots@time@between@two=\pgfmathresult -%\message{HIT between \pgfplots@len@last\space and \pgfplots@len@total\space (\pgfplots@time@between@two)^^J}% +%\message{HIT of \pgfplotspointattime@value@target\space between \pgfplots@len@last\space and \pgfplotspointattime@value@current\space (\pgfplots@time@between@two)^^J}% \ifx\pgfplots@last@processed\pgfutil@empty \pgfplotsplothandlerserializepointto{\pgfplots@cur}% \else diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplotsmeshplothandler.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplotsmeshplothandler.code.tex index 6e9bd868185..e1430c929cb 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/pgfplotsmeshplothandler.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplotsmeshplothandler.code.tex @@ -1942,7 +1942,7 @@ \pgfplotsplothandlersurveyend@mesh \let\pgfplotsplothandlersurveystart=\pgfplotsplothandlersurveystart@default \let\pgfplotsplothandlersurveyend=\pgfplotsplothandlersurveyend@default - \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@default + \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@default@noreset@of@pointmeta \pgfplotsplothandlersurveystart \expandafter\pgfplotstable@isloadedtable\expandafter{\pgfplotsplothandlermesh@patchtable}{% \pgfplots@error{Sorry, 'patch table={<loaded table>}' has not been implemented; it would probably be too slow :-(. Please provide a file name or inline table data}% @@ -1987,11 +1987,10 @@ \let\pgfplotsplothandlermesh@patchtable@init=\relax }% \def\pgfplotsplothandlermesh@patchtable@rowlistener@exceptionmsg{% - \pgfplotsplothandlermesh@patchtable:\pgfplotstablelineno\space\space could not read column no \the\c@pgf@countb: '\pgfplots@current@vertexindex' is no valid index into the array of \pgfplotsarraysizeof\pgfplots@verts\space coordinates% + patch table \pgfplotsplothandlermesh@patchtable\space line \pgfplotstablelineno: could not read column no \the\c@pgf@countb: expected '\pgfplots@current@vertexindex' to be a valid index into the vertex arrays (the \pgfplotsarraysizeof\pgfplots@verts\space input coordinates)% }% \def\pgfplotsplothandlermesh@patchtable@rowlistener{% \pgfplotsplothandlermesh@patchtable@init% - \let\pgfplotsexceptionmsg=\pgfplotsplothandlermesh@patchtable@rowlistener@exceptionmsg % \ifpgfplotsplothandlermesh@patchtable@hascdata \ifpgfplotsplothandlermesh@patchtable@cdata@individual @@ -2015,7 +2014,9 @@ \pgfmathfloattoint\pgfmathresult \let\pgfplots@current@vertexindex=\pgfmathresult % + \let\pgfplotsexceptionmsg=\pgfplotsplothandlermesh@patchtable@rowlistener@exceptionmsg \pgfplotsarrayselect\pgfplots@current@vertexindex\of\pgfplots@verts\to\pgfplots@stored@pt + \let\pgfplotsexceptionmsg=\relax % \ifpgfplotsplothandlermesh@patchtable@cdata@individual \c@pgf@countc=\c@pgf@countb\relax @@ -2027,7 +2028,6 @@ \fi \advance\c@pgf@countb by1 \pgfutil@repeat - \let\pgfplotsexceptionmsg=\relax } \def\pgfplotsplothandlermesh@patchtable@stream#1,#2,#3;#4;{% \def\pgfplots@current@point@x{#1}% diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplotsplothandlers.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplotsplothandlers.code.tex index d9bec6a91cf..36e891d4fd4 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/pgfplotsplothandlers.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplotsplothandlers.code.tex @@ -539,6 +539,13 @@ % eventually). This DV engine stores data point entries in keys, % namely those in the key path /data point. See the pgf manual. \def\pgfplotsplothandlersurveypoint@default{% + % reset it. NOTE: this migh be done multiple times. But better one + % too much than one too few... + \def\pgfplots@set@perpointmeta@done{0}% + % + \pgfplotsplothandlersurveypoint@default@noreset@of@pointmeta +}% +\def\pgfplotsplothandlersurveypoint@default@noreset@of@pointmeta{% \pgfplotsaxisparsecoordinate \pgfplotsaxispreparecoordinate \ifpgfplotsaxisparsecoordinateok @@ -1605,7 +1612,17 @@ \tikz@plot@handler \pgf@plotstreamstart }% - \def\pgfplotsplothandlername{hist}% + % + % let \pgfplotsplothandlername to the one of the handler. + % Note that \pgfplotsplothandlername is the *visualization* layer + \begingroup + \pgfplotsset{/pgfplots/hist/handler}% + \pgfplotsresetplothandler + \tikz@plot@handler + \xdef\pgfplots@glob@TMPa{\pgfplotsplothandlername}% + \endgroup + \let\pgfplotsplothandlername=\pgfplots@glob@TMPa% + % \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@hist \let\pgfplotsplothandlersurveystart=\pgfplotsplothandlersurveystart@hist \let\pgfplotsplothandlersurveyend=\pgfplotsplothandlersurveyend@hist @@ -2744,7 +2761,7 @@ plot to file/scanline marks/always/.code={\def\pgfplotsplothandlertofile@scanlinemarks{2}}, plot to file/scanline marks/true/.code={\def\pgfplotsplothandlertofile@scanlinemarks{2}}, plot to file/scanline marks/if in input, - plot to file/col sep/.initial=\pgfplots@TAB, + plot to file/col sep/.initial=\pgfplots@SPACE, plot to file/end-of-scanline content/.initial=, } diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex index 66e9cd8693f..88e1bea367b 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex @@ -60,7 +60,7 @@ % special case. \begingroup \c@pgf@counta=#1\relax - \ifnum\c@pgf@counta<0 + \ifdim#1.#2pt<0pt % \advance\c@pgf@counta by-1 \pgfmathsubtract@{1}{0.#2}% \expandafter\pgfplots@is@log@tick@a@minor@tick@pos@IDENTIFY@LOGi\pgfmathresult\relax diff --git a/Master/texmf-dist/tex/generic/pgfplots/sys/pgflibrarypgfplots.surfshading.pgfsys-dvipdfmx.def b/Master/texmf-dist/tex/generic/pgfplots/sys/pgflibrarypgfplots.surfshading.pgfsys-dvipdfmx.def index 29deb7dfa1b..59662c4edfa 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/sys/pgflibrarypgfplots.surfshading.pgfsys-dvipdfmx.def +++ b/Master/texmf-dist/tex/generic/pgfplots/sys/pgflibrarypgfplots.surfshading.pgfsys-dvipdfmx.def @@ -165,7 +165,6 @@ }% \special{pdf: close @pgfplotsPattern\pgfplotslibrarysurf@count\space }% }% - \pgfplots@loc@TMPb \edef#1{% /pgfplotsSurface\pgfplotslibrarysurf@count\space @pgfplotsPattern\pgfplotslibrarysurf@count }% diff --git a/Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex b/Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex index 56e472968b7..58ae93cbc1a 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/util/pgfplotsutil.code.tex @@ -240,6 +240,7 @@ \catcode`\%=12 \gdef\pgfplots@PERCENT@TEXT{%} \catcode`\^^I=12 +\gdef\pgfplots@SPACE{ } \gdef\pgfplots@TAB{^^I} \catcode`\#=12 \gdef\pgfplots@ROUTE{#}} |