%% pgflibrarybezieroffset.code.tex
%% Copyright 2023 Jonathan Schulz
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
% http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008-05-04 or later.
%
% This work has the LPPL maintenance status 'maintained'.
%
% The Current Maintainer of this work is Jonathan Schulz.
%
% This work consists of the files
% pgflibrarybezieroffset.code.tex, pgflibrarynfold.code.tex, pgflibraryoffsetpath.code.tex, tikz-nfold-doc.tex, tikzlibrarynfold.code.tex, tikz-nfold-doc.tex, and tikz-nfold-doc.pdf.
%
%
% A commented version of this file can be found on https://github.com/jonschz/tikz-nfold .
%



\def\pgf@halfsplitbezier#1#2#3#4{%
  \pgfextract@process\pgf@splitbezier@ii@iv{#4}%
  \pgf@xc=\pgf@x%
  \pgf@yc=\pgf@y%
  \pgf@process{#3}%
  \pgf@xb=\pgf@x%
  \pgf@yb=\pgf@y%
  \pgf@process{#2}%
  \pgf@xa=\pgf@x%
  \pgf@ya=\pgf@y%
  \pgfextract@process\pgf@splitbezier@i@i{#1}%
  \pgf@x=.5\pgf@x\advance\pgf@x by.5\pgf@xa%
  \pgf@y=.5\pgf@y\advance\pgf@y by.5\pgf@ya%
  \edef\pgf@splitbezier@i@ii{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}%
  \pgf@xa=.5\pgf@xa\advance\pgf@xa by.5\pgf@xb%
  \pgf@ya=.5\pgf@ya\advance\pgf@ya by.5\pgf@yb%
  \pgf@xb=.5\pgf@xb\advance\pgf@xb by.5\pgf@xc%
  \pgf@yb=.5\pgf@yb\advance\pgf@yb by.5\pgf@yc%
  \edef\pgf@splitbezier@ii@iii{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb}%
  \pgf@x=.5\pgf@x\advance\pgf@x by.5\pgf@xa%
  \pgf@y=.5\pgf@y\advance\pgf@y by.5\pgf@ya%
  \edef\pgf@splitbezier@i@iii{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}%
  \pgf@xa=.5\pgf@xa\advance\pgf@xa by.5\pgf@xb%
  \pgf@ya=.5\pgf@ya\advance\pgf@ya by.5\pgf@yb%
  \edef\pgf@splitbezier@ii@ii{\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}%
  \pgf@x=.5\pgf@x\advance\pgf@x by.5\pgf@xa%
  \pgf@y=.5\pgf@y\advance\pgf@y by.5\pgf@ya%
  \edef\pgf@splitbezier@i@iv{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}%
  \let\pgf@splitbezier@ii@i\pgf@splitbezier@i@iv
}


\def\pgfmathcrossproduct#1#2{%
  \begingroup
    \pgf@process{#1}%
    \pgf@xa=\pgf@x%
    \pgf@ya=\pgf@y%
    \pgf@process{#2}%
    \pgf@y=\pgf@sys@tonumber\pgf@xa\pgf@y
    \advance\pgf@y by -\pgf@sys@tonumber\pgf@ya\pgf@x
  \pgfmath@returnone\pgf@y
  \endgroup
}

\def\pgfmathdotproduct#1#2{%
  \begingroup
    \pgf@process{#1}%
    \pgf@xa=\pgf@x%
    \pgf@ya=\pgf@y%
    \pgf@process{#2}%
    \pgf@x=\pgf@sys@tonumber\pgf@xa\pgf@x
    \advance\pgf@x by \pgf@sys@tonumber\pgf@ya\pgf@y
  \pgfmath@returnone\pgf@x
  \endgroup
}

\def\pgfmathcrossdot#1#2{%
  \begingroup
    \pgf@process{#1}%
    \pgf@xa=\pgf@x%
    \pgf@ya=\pgf@y%
    \pgf@process{#2}%
    \pgf@xb=\pgf@sys@tonumber\pgf@xa\pgf@x
    \pgf@yb=\pgf@sys@tonumber\pgf@xa\pgf@y
    \advance\pgf@xb by \pgf@sys@tonumber\pgf@ya\pgf@y
    \advance\pgf@yb by -\pgf@sys@tonumber\pgf@ya\pgf@x
    \edef\pgf@temp{%
      \edef\noexpand\pgf@tmp@dot{\pgf@sys@tonumber\pgf@xb}%
      \edef\noexpand\pgf@tmp@cross{\pgf@sys@tonumber\pgf@yb}%
    }%
  \expandafter
  \endgroup\pgf@temp
}

\def\pgfpointtaxicabnorm#1{%
  \ifdim\pgf@x<0pt
    #1=-\pgf@x
  \else
    #1=\pgf@x
  \fi
  \ifdim\pgf@y<0pt
    \advance#1 by -\pgf@y
  \else
    \advance#1 by \pgf@y
  \fi
}

\def\pgf@offset@compute@tangents#1#2#3#4{%
  \pgf@process{\pgfpointdiff{#1}{#2}}%
  \pgfpointtaxicabnorm\pgf@xa
  \ifdim\pgf@xa<0.1pt\relax
    \pgf@process{\pgfpointdiff{#1}{#3}}%
    \pgfpointtaxicabnorm\pgf@xa
    \ifdim\pgf@xa<0.1pt\relax
      \pgf@process{\pgfpointdiff{#1}{#4}}%
    \fi
  \fi
  \pgfextract@process\pgf@tmp@tang@i{%
    \pgfpointnormalised{}%
    \global\let\pgf@nfold@tmp\pgf@tmp%
  }%
  \let\pgf@tmp@angle@i\pgf@nfold@tmp%
  \pgf@process{\pgfpointdiff{#3}{#4}}%
  \pgfpointtaxicabnorm\pgf@xa
  \ifdim\pgf@xa<0.1pt\relax
    \pgf@process{\pgfpointdiff{#2}{#4}}%
    \pgfpointtaxicabnorm\pgf@xa
    \ifdim\pgf@xa<0.1pt\relax
      \pgf@process{\pgfpointdiff{#1}{#4}}%
    \fi
  \fi
  \pgfextract@process\pgf@tmp@tang@ii{\pgfpointnormalised{}\global\let\pgf@nfold@tmp\pgf@tmp}%
  \let\pgf@tmp@angle@ii\pgf@nfold@tmp%
}



\def\pgf@offset@bezier@segment#1#2#3#4#5{%
  \pgf@offset@compute@tangents{#1}{#2}{#3}{#4}%
  \pgf@offset@bezier@segment@{#1}{#2}{#3}{#4}{#5}%
}

\def\pgf@offset@bezier@segment@#1#2#3#4#5{%
  \pgf@tmp@tang@i
  \edef\pgf@tmp@normal@i{\noexpand\pgfqpoint{-\the\pgf@y}{\the\pgf@x}}%
  \pgfextract@process\pgf@bezier@offset@i
    {\pgfpointadd{\pgfpointscale{#5}{\pgf@tmp@normal@i}}{#1}}%
  \pgf@tmp@tang@ii
  \edef\pgf@tmp@normal@ii{\noexpand\pgfqpoint{-\the\pgf@y}{\the\pgf@x}}%
  \pgfextract@process\pgf@bezier@offset@iv
    {\pgfpointadd{\pgfpointscale{#5}{\pgf@tmp@normal@ii}}{#4}}%
  \pgf@process{\pgfpointdiff{#1}{#4}}%
  \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
  \let\pgf@tmp@secantlen\pgfmathresult
  \ifdim\pgf@tmp@secantlen pt<0.1pt\relax
    \pgfutil@packagewarning{tikz-nfold}{first and last point are too close, expect glitches}%
    \pgfextract@process\pgf@bezier@offset@ii
      {\pgfpointadd{\pgf@bezier@offset@i}{\pgfpointdiff{#1}{#2}}}%
    \pgfextract@process\pgf@bezier@offset@iii
      {\pgfpointadd{\pgf@bezier@offset@iv}{\pgfpointdiff{#4}{#3}}}%
  \else
    \pgfextract@process\pgf@tmp@secant{\pgfpointnormalised{}}%
    \pgfmathcrossdot{}{\pgf@tmp@tang@ii}%
     \ifdim\pgf@tmp@dot pt<.5pt\relax%
       \pgfutil@packagewarning{tikz-nfold}{cosine of \pgf@tmp@dot\space clamped to 0.5 in non-simple segment}%
       \def\pgf@tmp@dot{.5}%
    \fi%
    \pgfmathdivide@{\pgf@tmp@cross}{\pgf@tmp@dot}%
    \let\pgf@tmp@tanbeta\pgfmathresult
    \pgfmathcrossdot{\pgf@tmp@secant}{\pgfpointnormalised{\pgfpointdiff{#1}{#2}}}
    \pgfmath@offset@calculate@scale{\pgf@tmp@secantlen}{\pgf@tmp@cross}{\pgf@tmp@dot}{\pgf@tmp@tanbeta}{#5}%
    \pgfextract@process\pgf@bezier@offset@ii{%
      \pgfpointadd
        {\pgf@bezier@offset@i}
        {\pgfqpointscale{\pgfmathresult}{\pgfpointdiff{#1}{#2}}}%
    }%
    \pgfmathcrossdot{\pgf@tmp@secant}{\pgf@tmp@tang@i}%
    \ifdim\pgf@tmp@dot pt<.5pt\relax
      \pgfutil@packagewarning{tikz-nfold}{cosine of \pgf@tmp@dot\space clamped to 0.5 in non-simple segment}%
      \def\pgf@tmp@dot{.5}%
    \fi
    \pgfmathdivide@{\pgf@tmp@cross}{\pgf@tmp@dot}%
    \let\pgf@tmp@tanbeta\pgfmathresult
    \pgfmathcrossdot{\pgf@tmp@secant}{\pgfpointnormalised{\pgfpointdiff{#4}{#3}}}%
    \pgfmath@offset@calculate@scale{\pgf@tmp@secantlen}{\pgf@tmp@cross}{\pgf@tmp@dot}{\pgf@tmp@tanbeta}{#5}%
    \pgfextract@process\pgf@bezier@offset@iii{%
      \pgfpointadd
        {\pgf@bezier@offset@iv}
        {\pgfqpointscale{\pgfmathresult}{\pgfpointdiff{#4}{#3}}}%
    }%
  \fi
}

\def\pgfmath@offset@calculate@scale#1#2#3#4#5{%
  \begingroup
    \pgfmathmultiply@{#3}{#4}%
    \pgfmathsubtract@{#2}{\pgfmathresult}%
    \let\pgfmath@temp\pgfmathresult
    \pgfmathreciprocal@{#1}%
    \pgfmathmultiply@{\pgfmathresult}{\pgfmath@temp}%
    \pgfmathmultiply{\pgfmathresult}{#5}%
    \pgfmathadd@{\pgfmathresult}{1}%
    \pgfmath@smuggleone\pgfmathresult
  \endgroup
}


\newcount\pgf@offset@max@recursion
\pgf@offset@max@recursion=4


\def\pgfoffsetcurve#1#2#3#4#5{%
  \pgfoffsetcurvecallback{#1}{#2}{#3}{#4}{#5}{\pgf@nfold@callback@move}%
}
\def\pgfoffsetcurvenomove#1#2#3#4#5{%
  \pgfoffsetcurvecallback{#1}{#2}{#3}{#4}{#5}{\pgf@nfold@callback@nomove}%
}

\def\pgf@nfold@callback@move#1#2#3#4#5{%
  \if#50\pgfpathmoveto{#1}\fi%
  \pgfpathcurveto{#2}{#3}{#4}%
}
\def\pgf@nfold@callback@nomove#1#2#3#4#5{\pgfpathcurveto{#2}{#3}{#4}}

\def\pgfoffsetcurvecallback#1#2#3#4#5#6{%
  \edef\pgf@offset@tmp@callback##1##2##3##4##5{%
    \noexpand\pgf@offset@bezier@segment{##1}{##2}{##3}{##4}{#5}%
    \noexpand#6{\noexpand\pgf@bezier@offset@i}{\noexpand\pgf@bezier@offset@ii}{\noexpand\pgf@bezier@offset@iii}{\noexpand\pgf@bezier@offset@iv}{##5}%
  }
  \pgf@subdividecurve{#1}{#2}{#3}{#4}{\pgf@offset@max@recursion}{0}{\pgf@offset@tmp@callback}%
}


\newif\ifpgf@offset@subdivide
\def\pgf@subdividecurve#1#2#3#4#5#6#7{%
  \begingroup%
    \pgfextract@process\pgf@ctrl@i{#1}%
    \pgfextract@process\pgf@ctrl@ii{#2}%
    \pgfextract@process\pgf@ctrl@iii{#3}%
    \pgfextract@process\pgf@ctrl@iv{#4}%
    \pgf@offset@compute@tangents{\pgf@ctrl@i}{\pgf@ctrl@ii}{\pgf@ctrl@iii}{\pgf@ctrl@iv}%
    \pgf@subdividecurve@{#5}{#6}{#7}%
  \endgroup%
}

\def\pgf@subdividecurve@#1#2#3{%
  \pgf@offset@subdividefalse%
  \c@pgf@counta=#1\relax
  \advance\c@pgf@counta by -1
  \pgfextract@process\pgf@itoiv{\pgfpointdiff{\pgf@ctrl@i}{\pgf@ctrl@iv}}%
  \pgfmathcrossproduct{\pgf@itoiv}{\pgf@tmp@tang@i}%
  \let\firstcross\pgfmathresult
  \pgfmathcrossproduct{\pgf@itoiv}{\pgf@tmp@tang@ii}%
  \ifnum
    \ifdim   \firstcross pt<0pt -1\else\ifdim   \firstcross pt>0pt 1\else 2\fi\fi
   =\ifdim\pgfmathresult pt<0pt -1\else\ifdim\pgfmathresult pt>0pt 1\else 3\fi\fi
  \relax %
    \pgf@offset@subdividetrue%
  \else%
    \pgfmathdotproduct{\pgf@tmp@tang@i}{\pgf@tmp@tang@ii}%
    \ifdim\pgfmathresult pt<.5pt\relax%
      \pgf@offset@subdividetrue%
    \else
      \pgf@itoiv
      \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
      \pgf@xa=\pgfmathresult pt
      \pgf@process{\pgfpointdiff{\pgf@ctrl@i}{\pgf@ctrl@ii}}%
      \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
      \pgf@xb=\pgfmathresult pt
      \pgf@process{\pgfpointdiff{\pgf@ctrl@iii}{\pgf@ctrl@iv}}%
      \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
      \advance\pgf@xb by \pgfmathresult pt
      \ifdim\pgf@xa<\pgf@xb
        \pgf@offset@subdividetrue
      \fi
    \fi%
  \fi%
  \ifpgf@offset@subdivide%
    \ifnum\c@pgf@counta<0%
      \pgfutil@packagewarning{tikz-nfold}{Recursion limit reached, glitches may occur. %
        Consider increasing \string\pgf@offset@max@recursion}%
      #3{\pgf@ctrl@i}{\pgf@ctrl@ii}{\pgf@ctrl@iii}{\pgf@ctrl@iv}{#2}%
    \else
      \pgf@halfsplitbezier{\pgf@ctrl@i}{\pgf@ctrl@ii}{\pgf@ctrl@iii}{\pgf@ctrl@iv}%
      \pgfextract@process\pgf@middletangent{%
        \pgfpointnormalised{\pgfpointdiff{\pgf@splitbezier@i@iii}{\pgf@splitbezier@i@iv}}}%
      \begingroup%
        \let\pgf@tmp@tang@ii\pgf@middletangent%
        \let\pgf@ctrl@i\pgf@splitbezier@i@i%
        \let\pgf@ctrl@ii\pgf@splitbezier@i@ii%
        \let\pgf@ctrl@iii\pgf@splitbezier@i@iii%
        \let\pgf@ctrl@iv\pgf@splitbezier@i@iv%
        \pgf@subdividecurve@{\c@pgf@counta}{#2}{#3}%
      \endgroup%
      \begingroup%
        \let\pgf@tmp@tang@i\pgf@middletangent%
        \let\pgf@ctrl@i\pgf@splitbezier@ii@i%
        \let\pgf@ctrl@ii\pgf@splitbezier@ii@ii%
        \let\pgf@ctrl@iii\pgf@splitbezier@ii@iii%
        \let\pgf@ctrl@iv\pgf@splitbezier@ii@iv%
        \pgf@subdividecurve@{\c@pgf@counta}{1}{#3}%
      \endgroup%
    \fi%
  \else%
    #3{\pgf@ctrl@i}{\pgf@ctrl@ii}{\pgf@ctrl@iii}{\pgf@ctrl@iv}{#2}%
  \fi%
}


\def\pgfoffsetline#1#2#3{%
  \pgfmathparse{#3}%
  \pgfoffsetline@{#1}{#2}{\pgfmathresult}{\pgfpointnormalised{\pgfpointdiff{#1}{#2}}}%
}

\def\pgfoffsetline@#1#2#3#4{%
  \pgfqpointscale{#3}{#4}%
  \pgf@xc=-\pgf@y
  \pgf@yc=\pgf@x
  \pgfpathmoveto{\pgfpointadd{#1}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
  \pgfpathlineto{\pgfpointadd{#2}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
}

\def\pgfoffsetlinenomove#1#2#3{%
  \pgfoffsetlinenomove@{#1}{#2}{#3}{\pgfpointnormalised{\pgfpointdiff{#1}{#2}}}%
}

\def\pgfoffsetlinenomove@#1#2#3#4{%
  \pgfqpointscale{#3}{#4}%
  \pgf@xc=-\pgf@y
  \pgf@yc=\pgf@x
  \pgfpathlineto{\pgfpointadd{#2}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
}
