summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarybbox.code.tex
blob: 38690faed1497b2a20473711030521fc66621a69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
% Copyright 2019 by an anonymous contributor
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU General Public License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.

\global\let\pgf@bbox@lt@curveto@normal\pgf@lt@curveto
\global\let\pgf@bbox@nlt@curveto@normal\pgf@nlt@curveto

\pgfqkeys{/pgf}{bezier bounding box/.is if=pgf@bbox@switch@}

\def\pgf@bbox@switch@false{%
  \let\pgf@lt@curveto \pgf@bbox@lt@curveto@normal
  \let\pgf@nlt@curveto\pgf@bbox@nlt@curveto@normal
}

\def\pgf@bbox@switch@true{%
  \let\pgf@lt@curveto \pgf@bbox@curveto
  \let\pgf@nlt@curveto\pgf@bbox@curveto
}

\def\pgf@bbox@curveto#1#2#3#4#5#6{%
  % extrema in x
  \pgfmathsetmacro{\pgf@temp@b}{abs(\pgf@path@lastx-#5-3*#1+3*#3)}%
  % ^^^ this is used for the denominator below, cannot become too small
  \pgfmathsetmacro{\pgf@temp@c}{max(1+\pgf@path@lastx,max(#1,max(#3,#5)))}%
  % ^^^ in order to avoid dimension too large errors from squaring lengths in pt
  \pgfmathparse{((#1/\pgf@temp@c)*(#1/\pgf@temp@c)-1*((#1/\pgf@temp@c)*(#3/\pgf@temp@c))+(#3/\pgf@temp@c)*(#3/\pgf@temp@c)-1*((#1/\pgf@temp@c)*(#5/\pgf@temp@c))+(-(#3/\pgf@temp@c)+(#5/\pgf@temp@c))*(\pgf@path@lastx/\pgf@temp@c))}%
  \pgfutil@tempdima=\pgfmathresult pt\relax%
  % ^^^ discriminant
  \ifdim\pgf@temp@b pt<0.01pt\relax%
   % approximately linear
   \pgfmathparse{abs(2*(#1)-2*(#3)+(#5))}%
   \pgfutil@tempdimb=\pgfmathresult pt\relax%
   \ifdim\pgfutil@tempdimb<0.1pt\relax%
        % if the denominator is very small, t is *likely* large but could be 0/0
   \else
        \pgfmathsetmacro{\pgf@temp@a}{(2*(#1)-3*(#3)+(#5))/(2*(#1)-2*(#3)+(#5))}%
        \pgfmathparse{\pgf@path@lastx*pow(1-\pgf@temp@a,3)+3*#1*pow(1-\pgf@temp@a,2)*\pgf@temp@a+3*#3*(1-\pgf@temp@a)*\pgf@temp@a*\pgf@temp@a+#5*pow(\pgf@temp@a,3)}%
        \pgfutil@tempdimb=\pgfmathresult pt\relax%
        \pgf@protocolsizes{\pgfutil@tempdimb}{#6}%
   \fi%
  \else
   \ifdim\pgfutil@tempdima<0pt\relax% negative discriminant -> no turning point
   \else
         \pgfmathsetmacro{\pgf@temp@a}{min(1,max(0,(\pgf@path@lastx-2*#1+#3-\pgf@temp@c*sqrt(\pgfutil@tempdima))/(\pgf@path@lastx-#5-3*#1+3*#3)))}%
         \pgfmathparse{\pgf@path@lastx*pow(1-\pgf@temp@a,3)+3*#1*pow(1-\pgf@temp@a,2)*\pgf@temp@a+3*#3*(1-\pgf@temp@a)*\pgf@temp@a*\pgf@temp@a+#5*pow(\pgf@temp@a,3)}%
           \pgfutil@tempdimb=\pgfmathresult pt\relax%
         \pgf@protocolsizes{\pgfutil@tempdimb}{#6}%
         \pgfmathsetmacro{\pgf@temp@a}{min(1,max(0,(\pgf@path@lastx-2*#1+#3+\pgf@temp@c*sqrt(\pgfutil@tempdima))/(\pgf@path@lastx-#5-3*#1+3*#3)))}%
         \pgfmathparse{\pgf@path@lastx*pow(1-\pgf@temp@a,3)+3*#1*pow(1-\pgf@temp@a,2)*\pgf@temp@a+3*#3*(1-\pgf@temp@a)*\pgf@temp@a*\pgf@temp@a+#5*pow(\pgf@temp@a,3)}%
         \pgfutil@tempdimb=\pgfmathresult pt\relax%
         \pgf@protocolsizes{\pgfutil@tempdimb}{#6}%
   \fi%
  \fi
  %%%%%%%%%%%%%%%%%%%%%%%%%%%
  % extrema in y (completely analogous to the above)
  \pgfmathsetmacro{\pgf@temp@b}{abs(\pgf@path@lasty-#6-3*#2+3*#4)}%
  \pgfmathsetmacro{\pgf@temp@c}{max(1+\pgf@path@lasty,max(#2,max(#4,#6)))}%
  \pgfmathparse{((#2/\pgf@temp@c)*(#2/\pgf@temp@c)-1*((#2/\pgf@temp@c)*(#4/\pgf@temp@c))+(#4/\pgf@temp@c)*(#4/\pgf@temp@c)-1*((#2/\pgf@temp@c)*(#6/\pgf@temp@c))+(-(#4/\pgf@temp@c)+(#6/\pgf@temp@c))*(\pgf@path@lasty/\pgf@temp@c))}%
  \pgfutil@tempdima=\pgfmathresult pt\relax%
  % ^^^ discriminant
  \ifdim\pgf@temp@b pt<0.01pt\relax%
   % approximately linear
   \pgfmathparse{abs(2*(#2)-2*(#4)+(#6))}%
   \pgfutil@tempdimb=\pgfmathresult pt\relax%
   \ifdim\pgfutil@tempdimb<0.1pt\relax%
        % if the denominator is very small, t is *likely* large but could be 0/0
   \else
        \pgfmathsetmacro{\pgf@temp@a}{(2*(#2)-3*(#4)+(#6))/(2*(#2)-2*(#4)+(#6))}%
        \pgfmathparse{\pgf@path@lasty*pow(1-\pgf@temp@a,3)+3*#2*pow(1-\pgf@temp@a,2)*\pgf@temp@a+3*#4*(1-\pgf@temp@a)*\pgf@temp@a*\pgf@temp@a+#6*pow(\pgf@temp@a,3)}%
        \pgfutil@tempdimb=\pgfmathresult pt\relax%
        \pgf@protocolsizes{#5}{\pgfutil@tempdimb}%
   \fi%
  \else
   \ifdim\pgfutil@tempdima<0pt\relax% negative discriminant -> no turning point
   \else
         \pgfmathsetmacro{\pgf@temp@a}{min(1,max(0,(\pgf@path@lasty-2*#2+#4-\pgf@temp@c*sqrt(\pgfutil@tempdima))/(\pgf@path@lasty-#6-3*#2+3*#4)))}%
         \pgfmathparse{\pgf@path@lasty*pow(1-\pgf@temp@a,3)+3*#2*pow(1-\pgf@temp@a,2)*\pgf@temp@a+3*#4*(1-\pgf@temp@a)*\pgf@temp@a*\pgf@temp@a+#6*pow(\pgf@temp@a,3)}%
           \pgfutil@tempdimb=\pgfmathresult pt\relax%
         \pgf@protocolsizes{#5}{\pgfutil@tempdimb}%
         \pgfmathsetmacro{\pgf@temp@a}{min(1,max(0,(\pgf@path@lasty-2*#2+#4+\pgf@temp@c*sqrt(\pgfutil@tempdima))/(\pgf@path@lasty-#6-3*#2+3*#4)))}%
         \pgfmathparse{\pgf@path@lasty*pow(1-\pgf@temp@a,3)+3*#2*pow(1-\pgf@temp@a,2)*\pgf@temp@a+3*#4*(1-\pgf@temp@a)*\pgf@temp@a*\pgf@temp@a+#6*pow(\pgf@temp@a,3)}%
         \pgfutil@tempdimb=\pgfmathresult pt\relax%
         \pgf@protocolsizes{#5}{\pgfutil@tempdimb}%
   \fi%
  \fi
  \pgf@protocolsizes{\pgf@path@lastx}{\pgf@path@lasty}%
  \pgf@protocolsizes{#5}{#6}%
  \pgfsyssoftpath@curveto{\the#1}{\the#2}{\the#3}{\the#4}{\the#5}{\the#6}%
}