texlive[67306] Master/texmf-dist: tikz-nfold (8jun23)

commits+karl at tug.org commits+karl at tug.org
Thu Jun 8 23:02:22 CEST 2023


Revision: 67306
          http://tug.org/svn/texlive?view=revision&revision=67306
Author:   karl
Date:     2023-06-08 23:02:22 +0200 (Thu, 08 Jun 2023)
Log Message:
-----------
tikz-nfold (8jun23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/tikz-nfold/README.md
    trunk/Master/texmf-dist/doc/latex/tikz-nfold/tikz-nfold-doc.pdf
    trunk/Master/texmf-dist/doc/latex/tikz-nfold/tikz-nfold-doc.tex
    trunk/Master/texmf-dist/tex/latex/tikz-nfold/tikzlibrarynfold.code.tex

Modified: trunk/Master/texmf-dist/doc/latex/tikz-nfold/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tikz-nfold/README.md	2023-06-08 21:01:56 UTC (rev 67305)
+++ trunk/Master/texmf-dist/doc/latex/tikz-nfold/README.md	2023-06-08 21:02:22 UTC (rev 67306)
@@ -1,5 +1,5 @@
 # tikz-nfold 
-## Version 0.1.2
+## Version 0.1.3
 
 This library adds higher-order paths to [TikZ](https://ctan.org/pkg/pgf) and also fixes some graphical issues with TikZ' `double` paths, used e.g. in wide arrows. It is also compatible with [tikz-cd](https://ctan.org/pkg/tikz-cd), adding support for triple and higher arrows. See the [documentation](tikz-nfold-doc.pdf) for full details.
 

Modified: trunk/Master/texmf-dist/doc/latex/tikz-nfold/tikz-nfold-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tikz-nfold/tikz-nfold-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tikz-nfold/tikz-nfold-doc.tex	2023-06-08 21:01:56 UTC (rev 67305)
+++ trunk/Master/texmf-dist/doc/latex/tikz-nfold/tikz-nfold-doc.tex	2023-06-08 21:02:22 UTC (rev 67306)
@@ -329,6 +329,8 @@
 \section{Version history}
 
 \begin{itemize}
+  \item \textbf{v0.1.3}: Bug fixes
+  \item \textbf{v0.1.2}: Bug fixes
   \item \textbf{v0.1.1}: Closing paths and structural changes
   \begin{itemize}
     \item Support for closed paths (\texttt{cycle} and \verb|\pgfpathclose|)

Modified: trunk/Master/texmf-dist/tex/latex/tikz-nfold/tikzlibrarynfold.code.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tikz-nfold/tikzlibrarynfold.code.tex	2023-06-08 21:01:56 UTC (rev 67305)
+++ trunk/Master/texmf-dist/tex/latex/tikz-nfold/tikzlibrarynfold.code.tex	2023-06-08 21:02:22 UTC (rev 67306)
@@ -276,30 +276,41 @@
 \newif\ifpgf at nfold@angletoosharp
 % This stores whether we need the intersections library for an arrow tip but it is not loaded
 \newif\ifpgf at nfold@intersectionsnotloaded
+% This stores whether the currently processed connected sub-path is the final one on this path
+\newif\ifpgf at nfold@lastconnsubpath
 
 
 \def\pgf at nfold@parser at handlesegment{%
-  \if\pgf at nfold@cur at visible 0
+  \if\pgf at nfold@cur at visible0
     % first, last and moveto are invisible
     \if\pgf at nfold@cur at type m
-      % We don't need to do anything for a moveto: If a visible segment follows, it will move to
-      % its starting location by itself. However, we might need to draw the arrow tip extension 
+      % We don't need to do anything for a moveto; if a visible segment follows, it will move to
+      % its starting location by itself. However, we might need to draw the arrow tip extension
       % at the start (if present).
+      % Draw a tip extension only if all of the following conditions are met:
+      % 1. There is an Implies tip at the start of this path
+      % 2. We are currently on the last connected sub-path of this path
+      % 3. The next segment is visible
+      % 4. This moveto is the first segment on this path
       \if\pgf at nfold@start at arrowcode1
-        \if\pgf at nfold@prev at type f
-          \if\pgf at nfold@next at visible1
-            \edef\pgf at nfold@macrotoadd{%
-              \noexpand\pgf at nfold@extendtotip{s}{\pgf at nfold@cur at last}{\pgf at nfold@next at angle@i}
-            }%
-            \pgf at nfold@addmacro\pgf at parsed@cur at conn@seg%
-            % hack: We make the next segment believe that this segment was a lineto
-            % so the path does not get interrupted
-            \let\pgf at nfold@cur at type l
-            \let\pgf at nfold@cur at visible 1
-            \let\pgf at nfold@cur at angle@ii\pgf at nfold@next at angle@i
-            \let\pgf at nfold@cur at tang@ii\pgf at nfold@next at tang@i
-          \fi
-        \fi%
+        \ifpgf at nfold@lastconnsubpath
+          \if\pgf at nfold@prev at type f
+            \if\pgf at nfold@next at visible1
+              \edef\pgf at nfold@macrotoadd{%
+                \noexpand\pgf at nfold@extendtotip{s}{\pgf at nfold@cur at last}{\pgf at nfold@next at angle@i}
+              }%
+              \pgf at nfold@addmacro\pgf at parsed@cur at conn@seg%
+              % hack: We make the next segment believe that this segment was a lineto
+              % so the path does not get interrupted
+              \let\pgf at nfold@cur at type l
+              \let\pgf at nfold@cur at visible1
+              \let\pgf at nfold@cur at angle@ii\pgf at nfold@next at angle@i
+              \let\pgf at nfold@cur at tang@ii\pgf at nfold@next at tang@i
+              \def\pgf at nfold@deltaphi at end{0}
+              \pgf at nfold@angletoosharpfalse
+            \fi
+          \fi%
+        \fi
       \fi
     \fi%
   \else%
@@ -311,25 +322,20 @@
     \def\pgf at nfold@shortenstartjoin{0}
     \def\pgf at nfold@shortenendjoin{0}
     \pgf at nfold@closejoinsedgecasefalse
-    \pgf at nfold@angletoosharpfalse
     % Step 1.1: Make room for the join at the start if needed
-    \if\pgf at nfold@prev at visible1
+    \if\pgf at nfold@prev at visible0
+      \pgf at nfold@continuesegmentfalse
+    \else
       \pgf at nfold@continuesegmenttrue
-      % TODO can we just use deltaphi at end from the previous round?
-      % Compute the angle difference at the start (between -180 and +180 degrees)
-      % using \pgfmathsubtract@ is more readable and no less efficient than computing this manually
-      \pgfmathsubtract@{\pgf at nfold@cur at angle@i}{\pgf at nfold@prev at angle@ii}
-      \pgf at nfold@clampangle
-      \edef\pgf at nfold@deltaphi at start{\pgfmathresult}
+      % deltaphi at start can be recycled from deltaphi at end;
+      % \ifpgf at nfold@angletoosharp is also still set
+      \let\pgf at nfold@deltaphi at start\pgf at nfold@deltaphi at end
+      % set \pgf at xb := abs(deltaphi at start)
       \pgf at xb=\pgf at nfold@deltaphi at start pt\relax
       \ifdim\pgf at xb<0pt\relax
         \pgf at xb=-\pgf at xb
       \fi
-      \ifdim\pgf at xb>178pt\relax
-        % we go full backwards, don't relocate the start and disable the join to avoid division by zero
-        % don't need an error message here, it has already been displayed in the previous segment
-        \pgf at nfold@angletoosharptrue
-      \else
+      \ifpgf at nfold@angletoosharp\else
         \ifdim\pgf at xb>0.5pt\relax
           % make room for the start join if the angle is nonzero;
           % shortenstartjoin := hwidth*tan(.5*abs(deltaphi at start))
@@ -352,8 +358,7 @@
               \pgfmathveclen@{\pgfmathresult}{\pgf at sys@tonumber\pgf at yb}
               \pgfextract at process\pgf at nfold@cur at supporta{\pgfpointadd%
                 {\pgf at nfold@cur at first}%
-                % TODO migrate to tangent
-                {\pgfqpointpolar{\pgf at nfold@cur at angle@i}{\pgfmathresult pt}}}%
+                {\pgfqpointscale{\pgfmathresult}{\pgf at nfold@cur at tang@i}}}%
             \else
               % special treatment for singular curves (supporta = first) to avoid rounding error glitches.
               % In this special case, a slight corner at the end of the join is unavoidable unless we
@@ -363,15 +368,15 @@
           \fi
         \fi
       \fi
-    \else
-      \pgf at nfold@continuesegmentfalse
     \fi
     % Step 1.2: Make room for the join at the end if needed
     \if\pgf at nfold@next at visible1
-      % Compute the angle difference at the start (between -180 and +180 degrees)
+      % Compute the angle difference at the end (between -180 and +180 degrees)
       % using \pgfmathsubtract@ is more readable and no less efficient than computing this manually
       \pgfmathsubtract@{\pgf at nfold@next at angle@i}{\pgf at nfold@cur at angle@ii}
       \pgf at nfold@clampangle
+      % Edge case handling: If the next segment is a closepath and has length zero, deltaphi is set
+      % to zero to prevent glitches (a zero length segment has no well-defined angle anyway)
       \edef\pgf at nfold@deltaphi at end{\pgfmathresult}
       \pgf at xb=\pgf at nfold@deltaphi at end pt\relax
       \ifdim\pgf at xb<0pt\relax
@@ -381,6 +386,7 @@
         \pgfutil at packagewarning{tikz-nfold}{Angle too sharp, expect visual errors}
         \pgf at nfold@angletoosharptrue
       \else
+        \pgf at nfold@angletoosharpfalse
         \ifdim\pgf at xb>0.5pt\relax
            % make room for the start join if the angle is nonzero
           % shortenendjoin := hwidth*tan(.5*abs(deltaphi at end))
@@ -403,11 +409,10 @@
             \pgfmathveclen@{\pgf at sys@tonumber\pgf at x}{\pgf at sys@tonumber\pgf at y}
             \ifdim\pgfmathresult pt>0.1pt\relax
               \pgfmathveclen@{\pgfmathresult}{\pgf at sys@tonumber\pgf at yb}
-              % can use qpoint and minus because \pgfmathresult is guaranteed to be positive
               \pgfextract at process\pgf at nfold@cur at supportb{\pgfpointadd%
                 {\pgf at nfold@cur at last}%
-                % TODO migrate to tangent
-                {\pgfqpointpolar{\pgf at nfold@cur at angle@ii}{-\pgfmathresult pt}}}%
+                % can use qpointscale and a minus because \pgfmathresult is guaranteed to be positive
+                {\pgfqpointscale{-\pgfmathresult}{\pgf at nfold@cur at tang@ii}}}%
             \else
               \let\pgf at nfold@cur at supportb\pgf at nfold@cur at movedlast
             \fi
@@ -416,7 +421,7 @@
       \fi
       % Step 1.3: Detect an edge case
       % This edge case appears whenever the current segment is such a short line that we would
-      % have to reduce its length to less than zero to make space for the joins. In such cases,
+      % have to reduce its length to less than zero to make room for the joins. In such cases,
       % the line is not drawn at all, and slight modifications must be made to the joins to ensure
       % a correct output (i.e. one join is immediately followed by the next without a segment in between).
       %
@@ -441,7 +446,7 @@
         % If the previous segment is a moveto and the current segment is a "close joins" edge case,
         % nothing needs to be drawn here (the relevant draw call will be made at the join of the subsequent
         % segment). We must therefore make sure that we move to the correct end point of this segment.
-        % Counterintuitively, this is given by the offset of \pgf at nfold@cur at movedfirst since the start and end
+        % Counterintuitively, this is given by the offset of \pgf at nfold@cur at movedFIRST since the start and end
         % are reversed in the edge case.
         \edef\pgf at nfold@macrotoadd{%
           \noexpand\pgf at nfold@token at edgecase@movetostart{\pgf at nfold@cur at movedfirst}{\pgf at nfold@cur at angle@i}%
@@ -451,18 +456,27 @@
     \else
       % If we draw the join when the start angle is close to 180 degrees, we get a division by zero
       \ifpgf at nfold@angletoosharp\else
-        \pgf at nfold@parser at handlejoin
+        \if\pgf at nfold@cur at type z\else
+          \pgf at nfold@parser at handlejoin
+        \fi
       \fi
     \fi
-    % Step 2.2: Store where the current (non-offset) end point was relocated
+    % Step 2.2: Store information that may be needed later
+    % Step 2.2.1: Store where the current (non-offset) end point was relocated
     % in order to make space for the end join. This may be used if the next
     % segment begins with a join
     \let\pgf at nfold@prev at segment@end\pgf at nfold@cur at movedlast
+    % Step 2.2.2: Store the tangent of the first proper segment of closed path.
+    % This is needed in case the \pgfpathclose-segment has length zero,
+    % since in that case its tangent cannot be computed.
+    \if\pgf at nfold@cur at type i
+      \let\pgf at nfold@connsubpath at tang@i\pgf at nfold@next at tang@i%
+      \let\pgf at nfold@connsubpath at angle@i\pgf at nfold@next at angle@i%
+    \fi
     %
     % Step 3: Draw the new segment.
     %
     % The value of \ifpgf at nfold@continuesegment decides whether we start with a moveto.
-    % curveto
     \if\pgf at nfold@cur at type l
       % In the edge case, one join is followed immediately by the next. The line segment
       % thus has a negative length and will be skipped.
@@ -481,6 +495,11 @@
       \def\pgf at nfold@macrotoadd{\pgf at nfold@token at closepath}%
       \pgf at nfold@addmacro\pgf at parsed@cur at conn@seg%
     \fi
+    \if\pgf at nfold@cur at type z
+      % zero and non-zero closepath's differ in the join handling, but are identical in rendering
+      \def\pgf at nfold@macrotoadd{\pgf at nfold@token at closepath}%
+      \pgf at nfold@addmacro\pgf at parsed@cur at conn@seg%
+    \fi
     \if\pgf at nfold@cur at type c
       \ifpgf at nfold@continuesegment
         \pgf at subdividecurve{\pgf at nfold@cur at movedfirst}{\pgf at nfold@cur at supporta}{\pgf at nfold@cur at supportb}{\pgf at nfold@cur at movedlast}{\pgf at offset@max at recursion}{0}{\pgf at nfold@addcurvesegment at callback@continue}
@@ -779,22 +798,22 @@
 %
 % In order to correctly implement \pgfpathclose we already need to know about
 % the \pgfpathclose (and the penultimate point) at the beginning of this
-% connected segment as these data affect the first/last join.
-% We therefore parse one connected segment of the softpath and store it in a modified
-% form in \pgf at cur@conn at segment. When reaching the end of the connected segment we call
-% the proper parser to turn \pgf at cur@conn at segment into a parsed path. We do this for
-% all connected segments and concatenate all the parsed paths.
+% connected sub-path as these data affect the first/last join.
+% We therefore parse one connected sub-path of the softpath and store it in a modified
+% form in \pgf at cur@conn at subpath. When reaching the end of the connected sub-path we call
+% the proper parser to turn \pgf at cur@conn at subpath into a parsed path. We do this for
+% all connected sub-paths and concatenate all the parsed paths.
 %
 
 
 \def\pgf at nfold@parsesoftpath#1#2{%
-  \let\pgf at cur@conn at segment\pgfutil at empty%
-  \let\pgf at all@parsed at segments\pgfutil at empty%
+  \let\pgf at cur@conn at subpath\pgfutil at empty%
+  \let\pgf at all@parsed at subpaths\pgfutil at empty%
   \edef\pgf at nfold@parser at last@moveto{{\the\pgf at path@lastx}{\the\pgf at path@lasty}}%
   \let\pgf at nfold@last at closepath@from\pgfutil at empty%
   \pgf at nfold@parse at setupfirst%
   \expandafter\pgf at nfold@@parsesoftpath#1\pgf at stop{}{}%
-  \let#2\pgf at all@parsed at segments%
+  \let#2\pgf at all@parsed at subpaths%
 }%
 
 \def\pgf at nfold@@parsesoftpath#1#2#3{%
@@ -801,33 +820,37 @@
   \let\pgf at next\pgf at nfold@@parsesoftpath%
   \ifx#1\pgf at stop%
     \def\pgf at nfold@macrotoadd{\pgf at nfold@parselast}%
-    \pgf at nfold@addmacro\pgf at cur@conn at segment%
-    \pgf at nfold@process at conn@segment%
+    \pgf at nfold@addmacro\pgf at cur@conn at subpath%
+    \pgf at nfold@lastconnsubpathtrue%
+    \pgf at nfold@process at conn@subpath%
     \let\pgf at next\relax%
   \else%
     \ifx#1\pgfsyssoftpath at movetotoken%
-      \ifx\pgf at cur@conn at segment\pgfutil at empty%
+      \ifx\pgf at cur@conn at subpath\pgfutil at empty%
         % This case happens for the very first segment or for double movetos.
         % We need special treatment here, as otherwise the arrow tip extension
         % does not work correctly. The \pgf at nfold@parsemoveto will be called
-				% in \pgf at nfold@process at conn@segment.
+        % in \pgf at nfold@process at conn@subpath.
         \def\pgf at nfold@parser at last@moveto{{#2}{#3}}%
-        % Make sure \pgf at cur@conn at segment is no longer empty so double movetos are not
+        % Make sure \pgf at cur@conn at subpath is no longer empty so double movetos are not
         % treated the same as single movetos. This is also relevant to arrow tip extensions
-        \def\pgf at cur@conn at segment{\relax}%
+        \def\pgf at cur@conn at subpath{\relax}%
       \else%
         \def\pgf at nfold@macrotoadd{\pgf at nfold@parsemoveto{#2}{#3}}%
-        \pgf at nfold@addmacro\pgf at cur@conn at segment%
-        % A moveto marks the beginning/end of one connected segment
-        \pgf at nfold@process at conn@segment%
+        \pgf at nfold@addmacro\pgf at cur@conn at subpath%
+        \pgf at nfold@lastconnsubpathfalse%
+        % A moveto marks the beginning/end of one connected sub-path
+        \pgf at nfold@process at conn@subpath%
         \let\pgf at nfold@last at closepath@from\pgfutil at empty%
-        \let\pgf at cur@conn at segment\pgfutil at empty%
+        \let\pgf at cur@conn at subpath\pgfutil at empty%
+        % set up "first" again which may be needed for the arrow tip extension
+        \pgf at nfold@parse at setupfirst%
         \def\pgf at nfold@parser at last@moveto{{#2}{#3}}%
       \fi
     \else%
       \ifx#1\pgfsyssoftpath at linetotoken%
         \def\pgf at nfold@macrotoadd{\pgf at nfold@parselineto{#2}{#3}}%
-        \pgf at nfold@addmacro\pgf at cur@conn at segment%
+        \pgf at nfold@addmacro\pgf at cur@conn at subpath%
       \else%
         \ifx#1\pgfsyssoftpath at curvetosupportatoken%
           \def\pgf at nfold@parse at supporta{{#2}{#3}}%
@@ -837,12 +860,12 @@
           \else%
             \ifx#1\pgfsyssoftpath at curvetotoken%
               \edef\pgf at nfold@macrotoadd{\noexpand\pgf at nfold@parsecurveto\pgf at nfold@parse at supporta\pgf at nfold@parse at supportb{#2}{#3}}%
-              \pgf at nfold@addmacro\pgf at cur@conn at segment%
+              \pgf at nfold@addmacro\pgf at cur@conn at subpath%
             \else%
               \ifx#1\pgfsyssoftpath at closepathtoken%
                 \let\pgf at nfold@last at closepath@from\pgf at nfold@parser at previous@pt%
                 \def\pgf at nfold@macrotoadd{\pgf at nfold@parseclosepath{#2}{#3}}%
-                \pgf at nfold@addmacro\pgf at cur@conn at segment%
+                \pgf at nfold@addmacro\pgf at cur@conn at subpath%
               \else%
                 \ifx#1\pgfsyssoftpath at rectcornertoken%
                   \def\pgf at nfold@parse at rectcorner{{#2}{#3}}%
@@ -849,7 +872,7 @@
                 \else%
                   \ifx#1\pgfsyssoftpath at rectsizetoken%
                     \edef\pgf at nfold@macrotoadd{\noexpand\pgf at nfold@parserect\pgf at nfold@parse at rectcorner{#2}{#3}}%
-                    \pgf at nfold@addmacro\pgf at cur@conn at segment%
+                    \pgf at nfold@addmacro\pgf at cur@conn at subpath%
                   \else%
                     \pgfutil at packageerror{tikz-nfold}{Unrecognised soft path token `#1'}{}%
                   \fi%
@@ -862,27 +885,30 @@
     \fi%
   \fi%
   \def\pgf at nfold@parser at previous@pt{{#2}{#3}}%
+  % store the last two segments, as they might be needed for zero-length \pgfpathclose-segments
+  \let\pgf at nfold@sectolast at segment\pgf at nfold@last at segment%
+  \let\pgf at nfold@last at segment\pgf at nfold@macrotoadd%
   \pgf at next}%
 
-\def\pgf at nfold@process at conn@segment{%
+\def\pgf at nfold@process at conn@subpath{%
   \let\pgf at parsed@cur at conn@seg\pgfutil at empty%
   \ifx\pgf at nfold@last at closepath@from\pgfutil at empty%
     \expandafter\pgf at nfold@parsemoveto\pgf at nfold@parser at last@moveto%
   \else%
-    % This connected segment ends on a closepath. In order to get
-    % the join right, we prepend the current segment with an invisible line
-    % identical to the line of the \pgfpathclose. This way, 
+    % This connected sub-path ends on a closepath. In order to get
+    % the join right, we prepend the current sub-path with an invisible line
+    % identical to the line of the \pgfpathclose.
     \expandafter\pgf at nfold@parsemoveto\pgf at nfold@last at closepath@from%
     \expandafter\pgf at nfold@parseinvisibleline\pgf at nfold@parser at last@moveto%
   \fi%
-  \pgf at cur@conn at segment%
+  \pgf at cur@conn at subpath%
   \let\pgf at nfold@macrotoadd\pgf at parsed@cur at conn@seg%
-  \pgf at nfold@addmacro\pgf at all@parsed at segments%
+  \pgf at nfold@addmacro\pgf at all@parsed at subpaths%
 }
 
 %
 % Values for \pgf at nfold@next at type:
-% f=first, m=moveto, c=curveto, l=lineto, r=rect, o=closepath, t=last, i=invisibleline
+% f=first, m=moveto, c=curveto, l=lineto, r=rect, o=closepath, z=zero length closepath, t=last, i=invisibleline
 %
 
 \def\pgf at nfold@parsemoveto#1#2{%
@@ -939,15 +965,57 @@
 \def\pgf at nfold@parseclosepath#1#2{%
   \pgf at process{\pgfpointdiff{\pgf at nfold@next at last}{\pgf at x#1\pgf at y#2}}%
   % closepath segments should always be processed even if they have zero length
-  \pgf at nfold@parse at line@common{#1}{#2}{o}%
+  \pgfpointtaxicabnorm\pgf at xa%
+  \ifdim\pgf at xa<0.1pt\relax%
+    \pgf at nfold@parse at closepath@zerolength{#1}{#2}%
+  \else%
+    \pgf at nfold@parse at line@common{#1}{#2}{o}%
+  \fi%
 }%
 
+\def\pgf at nfold@parse at closepath@zerolength#1#2{%
+  \pgf at nfold@parser at moveup%
+  \let\pgf at nfold@next at type=z%
+  \let\pgf at nfold@next at visible=1%
+  % Set the start and end tangent to the tangent of the first segment
+  \let\pgf at nfold@next at tang@i\pgf at nfold@connsubpath at tang@i
+  \let\pgf at nfold@next at tang@ii\pgf at nfold@connsubpath at tang@i
+  \let\pgf at nfold@next at angle@i\pgf at nfold@connsubpath at angle@i
+  \let\pgf at nfold@next at angle@ii\pgf at nfold@connsubpath at angle@i
+  \let\pgf at nfold@next at first\pgf at nfold@cur at last
+  % If problems arise, we need to put a fake point here (like \pgf at nfold@next at first + \pgf at nfold@next at tang@i)
+  \def\pgf at nfold@next at last{\pgf at x#1\pgf at y#2}%
+  \pgf at nfold@parser at handlesegment%
+}
+
 \def\pgf at nfold@parseinvisibleline#1#2{%
   \pgf at process{\pgfpointdiff{\pgf at nfold@next at last}{\pgf at x#1\pgf at y#2}}%
-  % invisibleline segments should always be processed even if they have zero length.
+  \pgfpointtaxicabnorm\pgf at xa%
+  % In order to correctly render the start/end join in a closed path,
+  % the \pgfpathclose segment is copied to the start of the path as an invisible line.
   % Counterintuitively, an "invisibleline" segment has next at visible=1 because
   % we want its end join to be rendered.
-  \pgf at nfold@parse at line@common{#1}{#2}{i}%
+  % In case the \pgfpathclose segment has non-zero length, we can just use a copy of
+  % this segment for the invisible line. Otherwise, the invisble line segment must will receive
+  % the same angle/tangent as the last finite-sized segment, which is the second-to-last
+  % segment overall (cached in \pgf at nfold@sectolast at segment).
+  \ifdim\pgf at xa>.1pt\relax%
+    \pgf at nfold@parse at line@common{#1}{#2}{i}%
+  \else%
+    \begingroup%
+      % find the tangent of the second-to-last segment
+      \let\pgf at nfold@parser at handlesegment\relax%
+      \pgf at nfold@sectolast at segment%
+      \global\let\pgf at nfold@tmp\pgf at nfold@next at tang@ii%
+    \endgroup%
+    % Construct an invisible line with length 1pt and the correct tangent.
+    % This step might not be needed since the join computations only require the tangent,
+    % but the invisibleline segment would be inconsistent otherwise, so better play it safe.
+    \pgfextract at process\pgf at nfold@next at first{\pgfpointdiff{\pgf at nfold@tmp}{\pgfqpoint{#1}{#2}}}%
+    % write the tangent into (\pgf at x, \pgf at y) where the next macro expects it to be
+    \pgf at nfold@tmp%
+    \pgf at nfold@parse at line@common{#1}{#2}{i}%
+  \fi%
 }%
 
 \def\pgf at nfold@parselast{%
@@ -1047,14 +1115,17 @@
   \let\pgf at nfold@next at visible=0%
   \edef\pgf at nfold@next at last{\pgf at x\the\pgf at path@lastx\pgf at y\the\pgf at path@lasty}%
   % the following only need to be set if visible=1
-  \let\pgf at nfold@next at tang@i=\pgfpointorigin%
-  \let\pgf at nfold@next at tang@ii=\pgfpointorigin%
-  \def\pgf at nfold@next at angle@i{0}%
-  \def\pgf at nfold@next at angle@ii{0}%
-  \let\pgf at nfold@next at first\pgfpointorigin%
+  % TODO these are disabled temporarily; an attempt to read them suggests that there
+  % is a bug, because their content has no meaning at this point. Consider reenabling
+  % if compile errors show up, but if they do, the root of the problem is likely to be elsewhere
+  %\let\pgf at nfold@next at tang@i=\pgfpointorigin%
+  %\let\pgf at nfold@next at tang@ii=\pgfpointorigin%
+  % \def\pgf at nfold@next at angle@i{0}%
+  % \def\pgf at nfold@next at angle@ii{0}%
+  % \let\pgf at nfold@next at first\pgfpointorigin%
   % the following only need to be set if type=c
-  \let\pgf at nfold@next at supporta\pgfpointorigin%
-  \let\pgf at nfold@next at supportb\pgfpointorigin%
+  % \let\pgf at nfold@next at supporta\pgfpointorigin%
+  % \let\pgf at nfold@next at supportb\pgfpointorigin%
 }
 
 \def\pgf at nfold@clampangle{



More information about the tex-live-commits mailing list.