From 1da164bf9c4fed03b30b98439a239f5a1873f9ae Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Wed, 6 Aug 2014 22:47:59 +0000
Subject: pgfplots (6aug14)

git-svn-id: svn://tug.org/texlive/trunk@34851 c570f23f-e606-0410-a88d-b1316a301751
---
 .../pgfcontrib/pgflibraryfillbetween.code.tex      | 122 ++++++++++++++++++---
 1 file changed, 106 insertions(+), 16 deletions(-)

(limited to 'Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/pgflibraryfillbetween.code.tex')

diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/pgflibraryfillbetween.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/pgflibraryfillbetween.code.tex
index bf2ebd6b64d..2b1eebdcb58 100644
--- a/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/pgflibraryfillbetween.code.tex
+++ b/Master/texmf-dist/tex/generic/pgfplots/pgfcontrib/pgflibraryfillbetween.code.tex
@@ -48,7 +48,8 @@
 	%     ...
 	%   end
 	%
-	% 'begin' has no arguments.
+	% 'begin' has one arguments: the number of following single
+	% streams.
 	/pgf/fill between/result stream/begin/.code=,%
 	%
 	% 'next ready' has macro arguments, but the macro \pgfretval
@@ -108,15 +109,15 @@
 		\ifx#3\pgfutil@empty
 			\pgfpathfillbetween@warning{second}%
 		\else
-			\pgfpathfillbetween@invoke{result stream/begin}%
 			%
 			\ifpgfpathfillbetween@split
 				\pgfpathfillbetween@compute@splitted{#2}{#3}%
 			\else
+				\pgfkeys{/pgf/fill between/result stream/begin=1}%
 				\pgfpathfillbetween@compute{#2}{#3}%
 				\pgfpathfillbetween@invoke{result stream/next ready}%
+				\pgfpathfillbetween@invoke{result stream/end}%
 			\fi
-			\pgfpathfillbetween@invoke{result stream/end}%
 		\fi
 	\fi
 	%
@@ -132,19 +133,84 @@
 % 'lineto'. This excludes the first moveto.
 %
 % The motivation is that fillbetween should ignore inner movetos.
+%
+% UPDATE: it turned out that replacing inner movetos is necessary, but
+% not sufficient. Now, this macro does more:
+% - it replaces isolated inner movetos by lineto
+% - if two successive inner movetos occur, it throws away the first
+%   one replaces the second by lineto
+% - if one or more trailing movetos occur in a path, these will be
+%   thrown away.
 \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}%
+		\pgfpathfillbetween@connect@inner@movetos@@{#2}%
 		\expandafter\def\expandafter\pgfretval\expandafter{\expandafter\pgfsyssoftpath@movetotoken\pgfretval}%
 	\else
-		\pgfutilstrreplace{\pgfsyssoftpath@movetotoken}{\pgfsyssoftpath@linetotoken}{#1#2}%
+		\pgfpathfillbetween@connect@inner@movetos@@{#1#2}%
 	\fi
 }%
 
+% Substitute all movetotokens by linetotokens.
+%
+% In addition, it should *deduplicate* movetos, i.e.
+% "moveto{<x>}{<y}moveto{<x2>}{<y2>}"
+% -> "moveto{<x2>}{<y2>}"
+%
+% and: trailing movetos should be discarded.
+\def\pgfpathfillbetween@connect@inner@movetos@@#1{%
+	% this implementation is derived from \pgfutilstrreplace - it does
+	% almost the same as
+	% s/\pgfsyssoftpath@movetotoken/pgfsyssoftpath@linetotoken/g
+	% -> but with the extra additions of deduplication and trailing
+	%  moveto removal.
+	\def\pgfretval{}%
+	\pgfpathfillbetween@search@and@replace@loop{#1}%
+}
+\def\pgfpathfillbetween@connect@inner@moveto@foundit@#1\pgfsyssoftpath@movetotoken#2#3#4{%
+	\ifx#4\pgf@EOI
+		% ah - a trailing moveto.
+		% In this case, we remember all until the moveto, but we omit
+		% the trailing moveto and its arguments.
+		\expandafter\def\expandafter\pgfretval\expandafter{\pgfretval #1}%
+		%
+		% ... and stop searching.
+		\let\pgf@loc@TMPa\relax
+	\else
+		\ifx#4\pgfsyssoftpath@movetotoken
+			% DEDUPLICATE: we have at least two successive movetos.
+			% silently skip the first moveto and its arguments and go on
+			% with the second moveto.
+			\def\pgf@loc@TMPa{\pgfpathfillbetween@connect@inner@moveto@foundit@#1\pgfsyssoftpath@movetotoken}%
+		\else
+			% substitute it by a lineto.
+			\expandafter\def\expandafter\pgfretval\expandafter{\pgfretval #1\pgfsyssoftpath@linetotoken{#2}{#3}}%
+			%
+			% ... continue the standard loop which skips over paths
+			% until the next moveto. Remember to re-insert '#4':
+			\def\pgf@loc@TMPa{\pgfpathfillbetween@connect@inner@moveto@foundit@@ #4}%
+		\fi
+	\fi
+	\pgf@loc@TMPa
+}%
+\def\pgfpathfillbetween@connect@inner@moveto@foundit@@#1\pgf@EOI{%
+	\pgfpathfillbetween@search@and@replace@loop{#1}%
+}%
+
+\def\pgfpathfillbetween@search@and@replace@loop#1{%
+	\pgfutil@in@{\pgfsyssoftpath@movetotoken}{#1}%
+	\ifpgfutil@in@
+		\def\pgf@loc@TMPa{\pgfpathfillbetween@connect@inner@moveto@foundit@ #1\pgf@EOI}%
+	\else
+		\expandafter\def\expandafter\pgfretval\expandafter{\pgfretval #1}%
+		\let\pgf@loc@TMPa=\relax
+	\fi
+	\pgf@loc@TMPa
+}%
+
 \def\pgfpathfillbetween@invoke#1{\pgfkeysvalueof{/pgf/fill between/#1/.@cmd}\pgfeov}
 
 \def\pgfpathfillbetween@replace@first@moveto#1#2\pgf@stop{%
@@ -216,6 +282,7 @@
 		\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
 	%
+	\pgfkeys{/pgf/fill between/result stream/begin=\pgfpathfilled@a@segments}%
 	% Recombine the pairs of segments (a_i, b_i), i = 0,..., N-1 in a
 	% filled way:
 	\def\c@pgfpathfilled@counter{0}%
@@ -230,6 +297,7 @@
 		%
 		\pgfutil@advancestringcounter\c@pgfpathfilled@counter
 	\repeatpgfmathloop
+	\pgfpathfillbetween@invoke{result stream/end}%
 }
 
 \def\pgfpathfillbetween@compute#1#2{%
@@ -307,8 +375,11 @@
 %
 % #1 a macro containing a softpath (i.e. something returned by
 % \pgfgetpath)
+%
+% SIDE--EFFECT: defines \pgfpointlastofsetpath  to be the last point of path #1
 \def\pgfsetpathandBB#1{%
-	\expandafter\pgfsetpath@protocolsizes@loop#1\pgf@stop
+	\let\pgfpointlastofsetpath=\pgfutil@empty
+	\expandafter\pgfsetpath@loop#1\pgf@stop
 	%
 	\pgfsetpath{#1}%
 }%
@@ -318,8 +389,10 @@
 %
 % #1 a macro containing a softpath (i.e. something returned by
 % \pgfgetpath)
+% SIDE--EFFECT: defines \pgfpointlastofsetpath  to be the last point of path #1
 \def\pgfaddpathandBB#1{%
-	\expandafter\pgfsetpath@protocolsizes@loop#1\pgf@stop
+	\let\pgfpointlastofsetpath=\pgfutil@empty
+	\expandafter\pgfsetpath@loop#1\pgf@stop
 	\pgfaddpath#1%
 }
 
@@ -410,12 +483,14 @@
 	}%
 }
 
-\def\pgfsetpath@protocolsizes@loop#1{%
+% Accumulates the path's bounding box, the last moveto, and the last
+% coord.
+\def\pgfsetpath@loop#1{%
 	\ifx#1\pgf@stop%
 		\let\pgfsetpathBB@protocolsizesnext=\relax%
 	\else%
 		\ifx#1\pgfsyssoftpath@movetotoken%
-			\let\pgfsetpathBB@protocolsizesnext=\pgfsetpathBB@protocolsizestoken@simple%
+			\let\pgfsetpathBB@protocolsizesnext=\pgfsetpathBB@protocolsizestoken@moveto%
 		\else%
 			\ifx#1\pgfsyssoftpath@linetotoken%
 				\let\pgfsetpathBB@protocolsizesnext=\pgfsetpathBB@protocolsizestoken@simple%
@@ -436,16 +511,27 @@
 	\fi%
 	\pgfsetpathBB@protocolsizesnext}
 
+\def\pgfsetpathBB@protocol@lastmoveto#1#2{%
+	\gdef\pgfsyssoftpath@lastmoveto{{#1}{#2}}%
+}
+
+\def\pgfsetpathBB@protocolsizestoken@moveto#1#2{%
+	% required for --cycle, among others:
+	\pgfsetpathBB@protocol@lastmoveto{#1}{#2}%
+	\pgfsetpathBB@protocolsizestoken@simple{#1}{#2}%
+}
 \def\pgfsetpathBB@protocolsizestoken@simple#1#2{%
+	\def\pgfpointlastofsetpath{\pgfqpoint{#1}{#2}}%
 	\pgf@protocolsizes{#1}{#2}%
-	\pgfsetpath@protocolsizes@loop%
+	\pgfsetpath@loop%
 }
 
 \def\pgfsetpathBB@protocolsizestoken@curveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{%
+	\def\pgfpointlastofsetpath{\pgfqpoint{#5}{#6}}%
 	\pgf@protocolsizes{#1}{#2}%
 	\pgf@protocolsizes{#3}{#4}%
 	\pgf@protocolsizes{#5}{#6}%
-	\pgfsetpath@protocolsizes@loop
+	\pgfsetpath@loop
 }
 
 \def\pgfsetpathBB@protocolsizestoken@rect#1#2\pgfsyssoftpath@rectsizetoken#3#4{%
@@ -455,7 +541,7 @@
 	\pgf@ya=#2\relax%
 	\advance\pgf@ya by#4\relax%
 	\pgf@protocolsizes{\pgf@xa}{\pgf@ya}%
-	\pgfsetpath@protocolsizes@loop
+	\pgfsetpath@loop
 }%
 
 % Defines \pgfretval to be the reversed path of #1.
@@ -606,7 +692,7 @@
 % 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
+% On output, both \pgfretval and \pgfintersectionsegments contain the number of computed segments. The
 % segments as such can be accessed via \pgfgetintersectionsegmentpath.
 %
 % #1 : should be '1' if the FIRST argument of
@@ -689,6 +775,7 @@
 		\pgfutil@advancestringcounter\c@pgf@path@result%
 		\let\pgfretval=\c@pgf@path@result%
 	\fi
+	\let\pgfintersectionsegments=\pgfretval
 }%
 
 % Defines \pgfretval to contain the desired path segment as softpath.
@@ -701,12 +788,15 @@
 % \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.
+%  The number of segments is \pgfintersectionsegments
 \def\pgfgetintersectionsegmentpath#1#2{%
 	\pgfcomputeintersectionsegments@set@src{#1}%
+	\pgfmathparse{#2}%
 	\afterassignment\pgfcomputeintersectionsegments@set@src@gobble
-	\c@pgf@countc=#2\relax%
+	\c@pgf@countc=\pgfmathresult\relax%
+	\ifnum\c@pgf@countc<0
+		\advance\c@pgf@countc by \pgfintersectionsegments\relax
+	\fi
 	\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'}%
-- 
cgit v1.2.3

