1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef mozilla_BezierUtils_h_
7 #define mozilla_BezierUtils_h_
8 
9 #include "mozilla/gfx/2D.h"
10 #include "gfxRect.h"
11 
12 namespace mozilla {
13 namespace gfx {
14 
15 // Control points for bezier curve
16 //
17 //                   mPoints[2]
18 //                    +-----___---+ mPoints[3]
19 //                      __--
20 //                   _--
21 //                  /
22 //                /
23 // mPoints[1] +  |
24 //            | |
25 //            ||
26 //            ||
27 //            |
28 //            |
29 //            |
30 //            |
31 // mPoints[0] +
32 struct Bezier {
33   Point mPoints[4];
34 };
35 
36 // Calculate a point or it's differential of a bezier curve formed by
37 // aBezier and parameter t.
38 //
39 //   GetBezierPoint = P(t)
40 //   GetBezierDifferential = P'(t)
41 //   GetBezierDifferential2 = P''(t)
42 //
43 //                   mPoints[2]
44 //                    +-----___---+ mPoints[3]
45 //                      __--     P(1)
46 //                   _--
47 //                  +
48 //                /  P(t)
49 // mPoints[1] +  |
50 //            | |
51 //            ||
52 //            ||
53 //            |
54 //            |
55 //            |
56 //            |
57 // mPoints[0] + P(0)
58 Point GetBezierPoint(const Bezier& aBezier, Float t);
59 Point GetBezierDifferential(const Bezier& aBezier, Float t);
60 Point GetBezierDifferential2(const Bezier& aBezier, Float t);
61 
62 // Calculate length of a simple bezier curve formed by aBezier and range [a, b].
63 Float GetBezierLength(const Bezier& aBezier, Float a, Float b);
64 
65 // Split bezier curve formed by aBezier into [0,t1], [t1,t2], [t2,1] parts, and
66 // stores control points for [t1,t2] to aSubBezier.
67 //
68 //                 ___---+
69 //             __+-     P(1)
70 //          _--   P(t2)
71 //         -
72 //       /  <-- aSubBezier
73 //      |
74 //     |
75 //    +
76 //    | P(t1)
77 //   |
78 //   |
79 //   |
80 //   |
81 //   + P(0)
82 void GetSubBezier(Bezier* aSubBezier, const Bezier& aBezier,
83                   Float t1, Float t2);
84 
85 // Find a nearest point on bezier curve formed by aBezier to a point aTarget.
86 // aInitialT is a hint to find the parameter t for the nearest point.
87 // If aT is non-null, parameter for the nearest point is stored to *aT.
88 // This function expects a bezier curve to be an approximation of elliptic arc.
89 // Otherwise it will return wrong point.
90 //
91 //  aTarget
92 //    +            ___---+
93 //             __--
94 //          _--
95 //         +
96 //       /  nearest point = P(t = *aT)
97 //      |
98 //     |
99 //    |
100 //    + P(aInitialT)
101 //   |
102 //   |
103 //   |
104 //   |
105 //   +
106 Point FindBezierNearestPoint(const Bezier& aBezier, const Point& aTarget,
107                              Float aInitialT, Float* aT=nullptr);
108 
109 // Calculate control points for a bezier curve that is an approximation of
110 // an elliptic arc.
111 //
112 //                                   aCornerSize.width
113 //                                 |<----------------->|
114 //                                 |                   |
115 //                     aCornerPoint|      mPoints[2]   |
116 //                    -------------+-------+-----___---+ mPoints[3]
117 //                    ^            |         __--
118 //                    |            |      _--
119 //                    |            |     -
120 //                    |            |   /
121 // aCornerSize.height | mPoints[1] +  |
122 //                    |            | |
123 //                    |            ||
124 //                    |            ||
125 //                    |            |
126 //                    |            |
127 //                    |            |
128 //                    v mPoints[0] |
129 //                    -------------+
130 void GetBezierPointsForCorner(Bezier* aBezier, mozilla::css::Corner aCorner,
131                               const Point& aCornerPoint,
132                               const Size& aCornerSize);
133 
134 // Calculate the approximate length of a quarter elliptic arc formed by radii
135 // (a, b).
136 //
137 //                a
138 //      |<----------------->|
139 //      |                   |
140 //   ---+-------------___---+
141 //   ^  |         __--
142 //   |  |      _--
143 //   |  |     -
144 //   |  |   /
145 // b |  |  |
146 //   |  | |
147 //   |  ||
148 //   |  ||
149 //   |  |
150 //   |  |
151 //   |  |
152 //   v  |
153 //   ---+
154 Float GetQuarterEllipticArcLength(Float a, Float b);
155 
156 // Calculate the distance between an elliptic arc formed by (origin, width,
157 // height), and a point P, along a line formed by |P + n * normal|.
158 // P should be outside of the ellipse, and the line should cross with the
159 // ellipse twice at n > 0 points.
160 //
161 //                            width
162 //                     |<----------------->|
163 //              origin |                   |
164 //          -----------+-------------___---+
165 //          ^  normal  |         __--
166 //          | P +->__  |      _--
167 //          |        --__    -
168 //          |          | --+
169 //   height |          |  |
170 //          |          | |
171 //          |          ||
172 //          |          ||
173 //          |          |
174 //          |          |
175 //          |          |
176 //          v          |
177 //          -----------+
178 Float CalculateDistanceToEllipticArc(const Point& P, const Point& normal,
179                                      const Point& origin,
180                                      Float width, Float height);
181 
182 } // namespace gfx
183 } // namespace mozilla
184 
185 #endif /* mozilla_BezierUtils_h_ */
186