Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
round_superellipse_unittests.cc File Reference

Go to the source code of this file.

Namespaces

namespace  impeller
 
namespace  impeller::testing
 

Macros

#define CHECK_POINT_WITH_OFFSET(rr, p, outward_offset)
 
#define CHECK_POINT_AND_MIRRORS(p)
 
#define CHECK_POINT_AND_MIRRORS(p)
 
#define CHECK_POINT_AND_MIRRORS(p)
 
#define CHECK_DIAGONAL_POINTS(p)
 

Macro Definition Documentation

◆ CHECK_DIAGONAL_POINTS

#define CHECK_DIAGONAL_POINTS (   p)
Value:
CHECK_POINT_WITH_OFFSET(rr, (p), Point(0.02, -0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, -1), Point(-0.02, 0.02));
#define CHECK_POINT_WITH_OFFSET(rr, p, outward_offset)

◆ CHECK_POINT_AND_MIRRORS [1/3]

#define CHECK_POINT_AND_MIRRORS (   p)
Value:
CHECK_POINT_WITH_OFFSET(rr, (p), Point(0.02, 0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p) * Point(1, -1), Point(0.02, -0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, 1), Point(-0.02, 0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, -1), Point(-0.02, -0.02));

◆ CHECK_POINT_AND_MIRRORS [2/3]

#define CHECK_POINT_AND_MIRRORS (   p)
Value:
CHECK_POINT_WITH_OFFSET(rr, (p), Point(0.02, 0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p) * Point(1, -1), Point(0.02, -0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, 1), Point(-0.02, 0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, -1), Point(-0.02, -0.02));

◆ CHECK_POINT_AND_MIRRORS [3/3]

#define CHECK_POINT_AND_MIRRORS (   p)
Value:
CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(1, 1) + center, \
Point(0.02, 0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(1, -1) + center, \
Point(0.02, -0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(-1, 1) + center, \
Point(-0.02, 0.02)); \
CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(-1, -1) + center, \
Point(-0.02, -0.02));

◆ CHECK_POINT_WITH_OFFSET

#define CHECK_POINT_WITH_OFFSET (   rr,
  p,
  outward_offset 
)
Value:
EXPECT_TRUE(rr.Contains(p)); \
EXPECT_FALSE(rr.Contains(p + outward_offset));

Definition at line 12 of file round_superellipse_unittests.cc.

15 {
16
17namespace {
18
19// A `PathReceiver` that allows setting callbacks for each kind of path
20// segments.
21class SpyPathReceiver : public PathReceiver {
22 public:
23 // For now not all segment types are defined since they're not all used.
24 using LineSegment = std::function<void(const Point&)>;
25 using CubicSegment =
26 std::function<void(const Point&, const Point&, const Point&)>;
27
28 using ConicSegment = std::function<void(const Point&, const Point&, Scalar)>;
29
30 void SpyLineTo(LineSegment line_to) { line_to_ = std::move(line_to); }
31
32 void SpyCubicTo(CubicSegment cubic_to) { cubic_to_ = std::move(cubic_to); }
33
34 void SpyConicTo(ConicSegment conic_to) { conic_to_ = std::move(conic_to); }
35
36 // |PathReceiver|
37 void MoveTo(const Point& p2, bool will_be_closed) override {}
38 // |PathReceiver|
39 void LineTo(const Point& p2) override {
40 if (line_to_) {
41 line_to_(p2);
42 }
43 }
44 // |PathReceiver|
45 void QuadTo(const Point& cp, const Point& p2) override {}
46 // |PathReceiver|
47 void CubicTo(const Point& cp1, const Point& cp2, const Point& p2) override {
48 if (cubic_to_) {
49 cubic_to_(cp1, cp2, p2);
50 }
51 }
52 bool ConicTo(const Point& cp, const Point& p2, Scalar weight) override {
53 if (conic_to_) {
54 conic_to_(cp, p2, weight);
55 return true;
56 }
57 return false;
58 }
59 // |PathReceiver|
60 void Close() override {}
61
62 private:
63 LineSegment line_to_;
64 CubicSegment cubic_to_;
65 ConicSegment conic_to_;
66};
67
68} // namespace
69
70namespace testing {
71
72TEST(RoundSuperellipseTest, EmptyDeclaration) {
73 RoundSuperellipse rse;
74
75 EXPECT_TRUE(rse.IsEmpty());
76 EXPECT_FALSE(rse.IsRect());
77 EXPECT_FALSE(rse.IsOval());
78 EXPECT_TRUE(rse.IsFinite());
79 EXPECT_TRUE(rse.GetBounds().IsEmpty());
80 EXPECT_EQ(rse.GetBounds(), Rect());
81 EXPECT_EQ(rse.GetBounds().GetLeft(), 0.0f);
82 EXPECT_EQ(rse.GetBounds().GetTop(), 0.0f);
83 EXPECT_EQ(rse.GetBounds().GetRight(), 0.0f);
84 EXPECT_EQ(rse.GetBounds().GetBottom(), 0.0f);
85 EXPECT_EQ(rse.GetRadii().top_left, Size());
86 EXPECT_EQ(rse.GetRadii().top_right, Size());
87 EXPECT_EQ(rse.GetRadii().bottom_left, Size());
88 EXPECT_EQ(rse.GetRadii().bottom_right, Size());
89 EXPECT_EQ(rse.GetRadii().top_left.width, 0.0f);
90 EXPECT_EQ(rse.GetRadii().top_left.height, 0.0f);
91 EXPECT_EQ(rse.GetRadii().top_right.width, 0.0f);
92 EXPECT_EQ(rse.GetRadii().top_right.height, 0.0f);
93 EXPECT_EQ(rse.GetRadii().bottom_left.width, 0.0f);
94 EXPECT_EQ(rse.GetRadii().bottom_left.height, 0.0f);
95 EXPECT_EQ(rse.GetRadii().bottom_right.width, 0.0f);
96 EXPECT_EQ(rse.GetRadii().bottom_right.height, 0.0f);
97}
98
99TEST(RoundSuperellipseTest, DefaultConstructor) {
100 RoundSuperellipse rse = RoundSuperellipse();
101
102 EXPECT_TRUE(rse.IsEmpty());
103 EXPECT_FALSE(rse.IsRect());
104 EXPECT_FALSE(rse.IsOval());
105 EXPECT_TRUE(rse.IsFinite());
106 EXPECT_TRUE(rse.GetBounds().IsEmpty());
107 EXPECT_EQ(rse.GetBounds(), Rect());
108 EXPECT_EQ(rse.GetRadii().top_left, Size());
109 EXPECT_EQ(rse.GetRadii().top_right, Size());
110 EXPECT_EQ(rse.GetRadii().bottom_left, Size());
111 EXPECT_EQ(rse.GetRadii().bottom_right, Size());
112}
113
114TEST(RoundSuperellipseTest, EmptyRectConstruction) {
115 RoundSuperellipse rse =
116 RoundSuperellipse::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
117
118 EXPECT_TRUE(rse.IsEmpty());
119 EXPECT_FALSE(rse.IsRect());
120 EXPECT_FALSE(rse.IsOval());
121 EXPECT_TRUE(rse.IsFinite());
122 EXPECT_TRUE(rse.GetBounds().IsEmpty());
123 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
124 EXPECT_EQ(rse.GetRadii().top_left, Size());
125 EXPECT_EQ(rse.GetRadii().top_right, Size());
126 EXPECT_EQ(rse.GetRadii().bottom_left, Size());
127 EXPECT_EQ(rse.GetRadii().bottom_right, Size());
128}
129
130TEST(RoundSuperellipseTest, RectConstructor) {
131 RoundSuperellipse rse =
132 RoundSuperellipse::MakeRect(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
133
134 EXPECT_FALSE(rse.IsEmpty());
135 EXPECT_TRUE(rse.IsRect());
136 EXPECT_FALSE(rse.IsOval());
137 EXPECT_TRUE(rse.IsFinite());
138 EXPECT_FALSE(rse.GetBounds().IsEmpty());
139 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
140 EXPECT_EQ(rse.GetRadii().top_left, Size());
141 EXPECT_EQ(rse.GetRadii().top_right, Size());
142 EXPECT_EQ(rse.GetRadii().bottom_left, Size());
143 EXPECT_EQ(rse.GetRadii().bottom_right, Size());
144}
145
146TEST(RoundSuperellipseTest, InvertedRectConstruction) {
147 RoundSuperellipse rse =
148 RoundSuperellipse::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f));
149
150 EXPECT_FALSE(rse.IsEmpty());
151 EXPECT_TRUE(rse.IsRect());
152 EXPECT_FALSE(rse.IsOval());
153 EXPECT_TRUE(rse.IsFinite());
154 EXPECT_FALSE(rse.GetBounds().IsEmpty());
155 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
156 EXPECT_EQ(rse.GetRadii().top_left, Size());
157 EXPECT_EQ(rse.GetRadii().top_right, Size());
158 EXPECT_EQ(rse.GetRadii().bottom_left, Size());
159 EXPECT_EQ(rse.GetRadii().bottom_right, Size());
160}
161
162TEST(RoundSuperellipseTest, EmptyOvalConstruction) {
163 RoundSuperellipse rse = RoundSuperellipse::MakeRectXY(
164 Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f), 10.0f, 10.0f);
165
166 EXPECT_TRUE(rse.IsEmpty());
167 EXPECT_FALSE(rse.IsRect());
168 EXPECT_FALSE(rse.IsOval());
169 EXPECT_TRUE(rse.IsFinite());
170 EXPECT_TRUE(rse.GetBounds().IsEmpty());
171 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
172 EXPECT_EQ(rse.GetRadii().top_left, Size());
173 EXPECT_EQ(rse.GetRadii().top_right, Size());
174 EXPECT_EQ(rse.GetRadii().bottom_left, Size());
175 EXPECT_EQ(rse.GetRadii().bottom_right, Size());
176}
177
178TEST(RoundSuperellipseTest, OvalConstructor) {
179 RoundSuperellipse rse =
180 RoundSuperellipse::MakeOval(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
181
182 EXPECT_FALSE(rse.IsEmpty());
183 EXPECT_FALSE(rse.IsRect());
184 EXPECT_TRUE(rse.IsOval());
185 EXPECT_TRUE(rse.IsFinite());
186 EXPECT_FALSE(rse.GetBounds().IsEmpty());
187 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
188 EXPECT_EQ(rse.GetRadii().top_left, Size(5.0f, 5.0f));
189 EXPECT_EQ(rse.GetRadii().top_right, Size(5.0f, 5.0f));
190 EXPECT_EQ(rse.GetRadii().bottom_left, Size(5.0f, 5.0f));
191 EXPECT_EQ(rse.GetRadii().bottom_right, Size(5.0f, 5.0f));
192}
193
194TEST(RoundSuperellipseTest, InvertedOvalConstruction) {
195 RoundSuperellipse rse = RoundSuperellipse::MakeRectXY(
196 Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f), 10.0f, 10.0f);
197
198 EXPECT_FALSE(rse.IsEmpty());
199 EXPECT_FALSE(rse.IsRect());
200 EXPECT_TRUE(rse.IsOval());
201 EXPECT_TRUE(rse.IsFinite());
202 EXPECT_FALSE(rse.GetBounds().IsEmpty());
203 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
204 EXPECT_EQ(rse.GetRadii().top_left, Size(5.0f, 5.0f));
205 EXPECT_EQ(rse.GetRadii().top_right, Size(5.0f, 5.0f));
206 EXPECT_EQ(rse.GetRadii().bottom_left, Size(5.0f, 5.0f));
207 EXPECT_EQ(rse.GetRadii().bottom_right, Size(5.0f, 5.0f));
208}
209
210TEST(RoundSuperellipseTest, RectRadiusConstructor) {
211 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadius(
212 Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), 2.0f);
213
214 EXPECT_FALSE(rse.IsEmpty());
215 EXPECT_FALSE(rse.IsRect());
216 EXPECT_FALSE(rse.IsOval());
217 EXPECT_TRUE(rse.IsFinite());
218 EXPECT_FALSE(rse.GetBounds().IsEmpty());
219 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
220 EXPECT_EQ(rse.GetRadii().top_left, Size(2.0f, 2.0f));
221 EXPECT_EQ(rse.GetRadii().top_right, Size(2.0f, 2.0f));
222 EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.0f, 2.0f));
223 EXPECT_EQ(rse.GetRadii().bottom_right, Size(2.0f, 2.0f));
224}
225
226TEST(RoundSuperellipseTest, RectXYConstructor) {
227 RoundSuperellipse rse = RoundSuperellipse::MakeRectXY(
228 Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), 2.0f, 3.0f);
229
230 EXPECT_FALSE(rse.IsEmpty());
231 EXPECT_FALSE(rse.IsRect());
232 EXPECT_FALSE(rse.IsOval());
233 EXPECT_TRUE(rse.IsFinite());
234 EXPECT_FALSE(rse.GetBounds().IsEmpty());
235 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
236 EXPECT_EQ(rse.GetRadii().top_left, Size(2.0f, 3.0f));
237 EXPECT_EQ(rse.GetRadii().top_right, Size(2.0f, 3.0f));
238 EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.0f, 3.0f));
239 EXPECT_EQ(rse.GetRadii().bottom_right, Size(2.0f, 3.0f));
240}
241
242TEST(RoundSuperellipseTest, RectSizeConstructor) {
243 RoundSuperellipse rse = RoundSuperellipse::MakeRectXY(
244 Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), Size(2.0f, 3.0f));
245
246 EXPECT_FALSE(rse.IsEmpty());
247 EXPECT_FALSE(rse.IsRect());
248 EXPECT_FALSE(rse.IsOval());
249 EXPECT_TRUE(rse.IsFinite());
250 EXPECT_FALSE(rse.GetBounds().IsEmpty());
251 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
252 EXPECT_EQ(rse.GetRadii().top_left, Size(2.0f, 3.0f));
253 EXPECT_EQ(rse.GetRadii().top_right, Size(2.0f, 3.0f));
254 EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.0f, 3.0f));
255 EXPECT_EQ(rse.GetRadii().bottom_right, Size(2.0f, 3.0f));
256}
257
258TEST(RoundSuperellipseTest, RectRadiiConstructor) {
259 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
260 Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f),
261 {
262 .top_left = Size(1.0, 1.5),
263 .top_right = Size(2.0, 2.5f),
264 .bottom_left = Size(3.0, 3.5f),
265 .bottom_right = Size(4.0, 4.5f),
266 });
267
268 EXPECT_FALSE(rse.IsEmpty());
269 EXPECT_FALSE(rse.IsRect());
270 EXPECT_FALSE(rse.IsOval());
271 EXPECT_TRUE(rse.IsFinite());
272 EXPECT_FALSE(rse.GetBounds().IsEmpty());
273 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
274 EXPECT_EQ(rse.GetRadii().top_left, Size(1.0f, 1.5f));
275 EXPECT_EQ(rse.GetRadii().top_right, Size(2.0f, 2.5f));
276 EXPECT_EQ(rse.GetRadii().bottom_left, Size(3.0f, 3.5f));
277 EXPECT_EQ(rse.GetRadii().bottom_right, Size(4.0f, 4.5f));
278}
279
280TEST(RoundSuperellipseTest, RectRadiiOverflowWidthConstructor) {
281 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
282 Rect::MakeXYWH(10.0f, 10.0f, 6.0f, 30.0f),
283 {
284 .top_left = Size(1.0f, 2.0f),
285 .top_right = Size(3.0f, 4.0f),
286 .bottom_left = Size(5.0f, 6.0f),
287 .bottom_right = Size(7.0f, 8.0f),
288 });
289 // Largest sum of paired radii widths is the bottom edge which sums to 12
290 // Rect is only 6 wide so all radii are scaled by half
291 // Rect is 30 tall so no scaling should happen due to radii heights
292
293 EXPECT_FALSE(rse.IsEmpty());
294 EXPECT_FALSE(rse.IsRect());
295 EXPECT_FALSE(rse.IsOval());
296 EXPECT_TRUE(rse.IsFinite());
297 EXPECT_FALSE(rse.GetBounds().IsEmpty());
298 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 16.0f, 40.0f));
299 EXPECT_EQ(rse.GetRadii().top_left, Size(0.5f, 1.0f));
300 EXPECT_EQ(rse.GetRadii().top_right, Size(1.5f, 2.0f));
301 EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.5f, 3.0f));
302 EXPECT_EQ(rse.GetRadii().bottom_right, Size(3.5f, 4.0f));
303}
304
305TEST(RoundSuperellipseTest, RectRadiiOverflowHeightConstructor) {
306 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
307 Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 6.0f),
308 {
309 .top_left = Size(1.0f, 2.0f),
310 .top_right = Size(3.0f, 4.0f),
311 .bottom_left = Size(5.0f, 6.0f),
312 .bottom_right = Size(7.0f, 8.0f),
313 });
314 // Largest sum of paired radii heights is the right edge which sums to 12
315 // Rect is only 6 tall so all radii are scaled by half
316 // Rect is 30 wide so no scaling should happen due to radii widths
317
318 EXPECT_FALSE(rse.IsEmpty());
319 EXPECT_FALSE(rse.IsRect());
320 EXPECT_FALSE(rse.IsOval());
321 EXPECT_TRUE(rse.IsFinite());
322 EXPECT_FALSE(rse.GetBounds().IsEmpty());
323 EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 40.0f, 16.0f));
324 EXPECT_EQ(rse.GetRadii().top_left, Size(0.5f, 1.0f));
325 EXPECT_EQ(rse.GetRadii().top_right, Size(1.5f, 2.0f));
326 EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.5f, 3.0f));
327 EXPECT_EQ(rse.GetRadii().bottom_right, Size(3.5f, 4.0f));
328}
329
330TEST(RoundSuperellipseTest, Shift) {
331 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
332 Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
333 {
334 .top_left = Size(1.0f, 2.0f),
335 .top_right = Size(3.0f, 4.0f),
336 .bottom_left = Size(5.0f, 6.0f),
337 .bottom_right = Size(7.0f, 8.0f),
338 });
339 RoundSuperellipse shifted = rse.Shift(5.0, 6.0);
340
341 EXPECT_FALSE(shifted.IsEmpty());
342 EXPECT_FALSE(shifted.IsRect());
343 EXPECT_FALSE(shifted.IsOval());
344 EXPECT_TRUE(shifted.IsFinite());
345 EXPECT_FALSE(shifted.GetBounds().IsEmpty());
346 EXPECT_EQ(shifted.GetBounds(), Rect::MakeLTRB(15.0f, 16.0f, 45.0f, 46.0f));
347 EXPECT_EQ(shifted.GetRadii().top_left, Size(1.0f, 2.0f));
348 EXPECT_EQ(shifted.GetRadii().top_right, Size(3.0f, 4.0f));
349 EXPECT_EQ(shifted.GetRadii().bottom_left, Size(5.0f, 6.0f));
350 EXPECT_EQ(shifted.GetRadii().bottom_right, Size(7.0f, 8.0f));
351
352 EXPECT_EQ(shifted, RoundSuperellipse::MakeRectRadii(
353 Rect::MakeXYWH(15.0f, 16.0f, 30.0f, 30.0f),
354 {
355 .top_left = Size(1.0f, 2.0f),
356 .top_right = Size(3.0f, 4.0f),
357 .bottom_left = Size(5.0f, 6.0f),
358 .bottom_right = Size(7.0f, 8.0f),
359 }));
360}
361
362TEST(RoundSuperellipseTest, ExpandScalar) {
363 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
364 Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
365 {
366 .top_left = Size(1.0f, 2.0f),
367 .top_right = Size(3.0f, 4.0f),
368 .bottom_left = Size(5.0f, 6.0f),
369 .bottom_right = Size(7.0f, 8.0f),
370 });
371 RoundSuperellipse expanded = rse.Expand(5.0);
372
373 EXPECT_FALSE(expanded.IsEmpty());
374 EXPECT_FALSE(expanded.IsRect());
375 EXPECT_FALSE(expanded.IsOval());
376 EXPECT_TRUE(expanded.IsFinite());
377 EXPECT_FALSE(expanded.GetBounds().IsEmpty());
378 EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 5.0f, 45.0f, 45.0f));
379 EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
380 EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
381 EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
382 EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
383
384 EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
385 Rect::MakeXYWH(5.0f, 5.0f, 40.0f, 40.0f),
386 {
387 .top_left = Size(1.0f, 2.0f),
388 .top_right = Size(3.0f, 4.0f),
389 .bottom_left = Size(5.0f, 6.0f),
390 .bottom_right = Size(7.0f, 8.0f),
391 }));
392}
393
394TEST(RoundSuperellipseTest, ExpandTwoScalars) {
395 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
396 Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
397 {
398 .top_left = Size(1.0f, 2.0f),
399 .top_right = Size(3.0f, 4.0f),
400 .bottom_left = Size(5.0f, 6.0f),
401 .bottom_right = Size(7.0f, 8.0f),
402 });
403 RoundSuperellipse expanded = rse.Expand(5.0, 6.0);
404
405 EXPECT_FALSE(expanded.IsEmpty());
406 EXPECT_FALSE(expanded.IsRect());
407 EXPECT_FALSE(expanded.IsOval());
408 EXPECT_TRUE(expanded.IsFinite());
409 EXPECT_FALSE(expanded.GetBounds().IsEmpty());
410 EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 4.0f, 45.0f, 46.0f));
411 EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
412 EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
413 EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
414 EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
415
416 EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
417 Rect::MakeXYWH(5.0f, 4.0f, 40.0f, 42.0f),
418 {
419 .top_left = Size(1.0f, 2.0f),
420 .top_right = Size(3.0f, 4.0f),
421 .bottom_left = Size(5.0f, 6.0f),
422 .bottom_right = Size(7.0f, 8.0f),
423 }));
424}
425
426TEST(RoundSuperellipseTest, ExpandFourScalars) {
427 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
428 Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
429 {
430 .top_left = Size(1.0f, 2.0f),
431 .top_right = Size(3.0f, 4.0f),
432 .bottom_left = Size(5.0f, 6.0f),
433 .bottom_right = Size(7.0f, 8.0f),
434 });
435 RoundSuperellipse expanded = rse.Expand(5.0, 6.0, 7.0, 8.0);
436
437 EXPECT_FALSE(expanded.IsEmpty());
438 EXPECT_FALSE(expanded.IsRect());
439 EXPECT_FALSE(expanded.IsOval());
440 EXPECT_TRUE(expanded.IsFinite());
441 EXPECT_FALSE(expanded.GetBounds().IsEmpty());
442 EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 4.0f, 47.0f, 48.0f));
443 EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
444 EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
445 EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
446 EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
447
448 EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
449 Rect::MakeXYWH(5.0f, 4.0f, 42.0f, 44.0f),
450 {
451 .top_left = Size(1.0f, 2.0f),
452 .top_right = Size(3.0f, 4.0f),
453 .bottom_left = Size(5.0f, 6.0f),
454 .bottom_right = Size(7.0f, 8.0f),
455 }));
456}
457
458TEST(RoundSuperellipseTest, ContractScalar) {
459 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
460 Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
461 {
462 .top_left = Size(1.0f, 2.0f),
463 .top_right = Size(3.0f, 4.0f),
464 .bottom_left = Size(5.0f, 6.0f),
465 .bottom_right = Size(7.0f, 8.0f),
466 });
467 RoundSuperellipse expanded = rse.Expand(-2.0);
468
469 EXPECT_FALSE(expanded.IsEmpty());
470 EXPECT_FALSE(expanded.IsRect());
471 EXPECT_FALSE(expanded.IsOval());
472 EXPECT_TRUE(expanded.IsFinite());
473 EXPECT_FALSE(expanded.GetBounds().IsEmpty());
474 EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(12.0f, 12.0f, 38.0f, 38.0f));
475 EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
476 EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
477 EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
478 EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
479
480 EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
481 Rect::MakeXYWH(12.0f, 12.0f, 26.0f, 26.0f),
482 {
483 .top_left = Size(1.0f, 2.0f),
484 .top_right = Size(3.0f, 4.0f),
485 .bottom_left = Size(5.0f, 6.0f),
486 .bottom_right = Size(7.0f, 8.0f),
487 }));
488}
489
490TEST(RoundSuperellipseTest, ContractTwoScalars) {
491 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
492 Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
493 {
494 .top_left = Size(1.0f, 2.0f),
495 .top_right = Size(3.0f, 4.0f),
496 .bottom_left = Size(5.0f, 6.0f),
497 .bottom_right = Size(7.0f, 8.0f),
498 });
499 RoundSuperellipse expanded = rse.Expand(-1.0, -2.0);
500
501 EXPECT_FALSE(expanded.IsEmpty());
502 EXPECT_FALSE(expanded.IsRect());
503 EXPECT_FALSE(expanded.IsOval());
504 EXPECT_TRUE(expanded.IsFinite());
505 EXPECT_FALSE(expanded.GetBounds().IsEmpty());
506 EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(11.0f, 12.0f, 39.0f, 38.0f));
507 EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
508 EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
509 EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
510 EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
511
512 EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
513 Rect::MakeXYWH(11.0f, 12.0f, 28.0f, 26.0f),
514 {
515 .top_left = Size(1.0f, 2.0f),
516 .top_right = Size(3.0f, 4.0f),
517 .bottom_left = Size(5.0f, 6.0f),
518 .bottom_right = Size(7.0f, 8.0f),
519 }));
520}
521
522TEST(RoundSuperellipseTest, ContractFourScalars) {
523 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
524 Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
525 {
526 .top_left = Size(1.0f, 2.0f),
527 .top_right = Size(3.0f, 4.0f),
528 .bottom_left = Size(5.0f, 6.0f),
529 .bottom_right = Size(7.0f, 8.0f),
530 });
531 RoundSuperellipse expanded = rse.Expand(-1.0, -1.5, -2.0, -2.5);
532
533 EXPECT_FALSE(expanded.IsEmpty());
534 EXPECT_FALSE(expanded.IsRect());
535 EXPECT_FALSE(expanded.IsOval());
536 EXPECT_TRUE(expanded.IsFinite());
537 EXPECT_FALSE(expanded.GetBounds().IsEmpty());
538 EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(11.0f, 11.5f, 38.0f, 37.5f));
539 EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
540 EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
541 EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
542 EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
543
544 EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
545 Rect::MakeXYWH(11.0f, 11.5f, 27.0f, 26.0f),
546 {
547 .top_left = Size(1.0f, 2.0f),
548 .top_right = Size(3.0f, 4.0f),
549 .bottom_left = Size(5.0f, 6.0f),
550 .bottom_right = Size(7.0f, 8.0f),
551 }));
552}
553
554TEST(RoundSuperellipseTest, ContractAndRequireRadiiAdjustment) {
555 RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
556 Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
557 {
558 .top_left = Size(1.0f, 2.0f),
559 .top_right = Size(3.0f, 4.0f),
560 .bottom_left = Size(5.0f, 6.0f),
561 .bottom_right = Size(7.0f, 8.0f),
562 });
563 RoundSuperellipse expanded = rse.Expand(-12.0);
564 // Largest sum of paired radii sizes are the bottom and right edges
565 // both of which sum to 12
566 // Rect was 30x30 reduced by 12 on all sides leaving only 6x6, so all
567 // radii are scaled by half to avoid overflowing the contracted rect
568
569 EXPECT_FALSE(expanded.IsEmpty());
570 EXPECT_FALSE(expanded.IsRect());
571 EXPECT_FALSE(expanded.IsOval());
572 EXPECT_TRUE(expanded.IsFinite());
573 EXPECT_FALSE(expanded.GetBounds().IsEmpty());
574 EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(22.0f, 22.0f, 28.0f, 28.0f));
575 EXPECT_EQ(expanded.GetRadii().top_left, Size(0.5f, 1.0f));
576 EXPECT_EQ(expanded.GetRadii().top_right, Size(1.5f, 2.0f));
577 EXPECT_EQ(expanded.GetRadii().bottom_left, Size(2.5f, 3.0f));
578 EXPECT_EQ(expanded.GetRadii().bottom_right, Size(3.5f, 4.0f));
579
580 // In this test, the MakeRectRadii constructor will make the same
581 // adjustment to the radii that the Expand method applied.
582 EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
583 Rect::MakeXYWH(22.0f, 22.0f, 6.0f, 6.0f),
584 {
585 .top_left = Size(1.0f, 2.0f),
586 .top_right = Size(3.0f, 4.0f),
587 .bottom_left = Size(5.0f, 6.0f),
588 .bottom_right = Size(7.0f, 8.0f),
589 }));
590
591 // In this test, the arguments to the constructor supply the correctly
592 // adjusted radii (though there is no real way to tell other than
593 // the result is the same).
594 EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
595 Rect::MakeXYWH(22.0f, 22.0f, 6.0f, 6.0f),
596 {
597 .top_left = Size(0.5f, 1.0f),
598 .top_right = Size(1.5f, 2.0f),
599 .bottom_left = Size(2.5f, 3.0f),
600 .bottom_right = Size(3.5f, 4.0f),
601 }));
602}
603
604TEST(RoundSuperellipseTest, NoCornerRoundSuperellipseContains) {
605 Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
606 // Rounded superellipses of bounds with no corners contains corners just
607 // barely.
608 auto no_corners = RoundSuperellipse::MakeRectRadii(
609 bounds, RoundingRadii::MakeRadii({0.0f, 0.0f}));
610
611 EXPECT_TRUE(no_corners.Contains({-50, -50}));
612 // Rectangles have half-in, half-out containment so we need
613 // to be careful about testing containment of right/bottom corners.
614 EXPECT_TRUE(no_corners.Contains({-50, 49.99}));
615 EXPECT_TRUE(no_corners.Contains({49.99, -50}));
616 EXPECT_TRUE(no_corners.Contains({49.99, 49.99}));
617 EXPECT_FALSE(no_corners.Contains({-50.01, -50}));
618 EXPECT_FALSE(no_corners.Contains({-50, -50.01}));
619 EXPECT_FALSE(no_corners.Contains({-50.01, 50}));
620 EXPECT_FALSE(no_corners.Contains({-50, 50.01}));
621 EXPECT_FALSE(no_corners.Contains({50.01, -50}));
622 EXPECT_FALSE(no_corners.Contains({50, -50.01}));
623 EXPECT_FALSE(no_corners.Contains({50.01, 50}));
624 EXPECT_FALSE(no_corners.Contains({50, 50.01}));
625}
626
627TEST(RoundSuperellipseTest, TinyCornerContains) {
628 Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
629 // Rounded superellipses of bounds with even the tiniest corners does not
630 // contain corners.
631 auto tiny_corners = RoundSuperellipse::MakeRectRadii(
632 bounds, RoundingRadii::MakeRadii({0.01f, 0.01f}));
633
634 EXPECT_FALSE(tiny_corners.Contains({-50, -50}));
635 EXPECT_FALSE(tiny_corners.Contains({-50, 50}));
636 EXPECT_FALSE(tiny_corners.Contains({50, -50}));
637 EXPECT_FALSE(tiny_corners.Contains({50, 50}));
638}
639
640TEST(RoundSuperellipseTest, UniformSquareContains) {
641 Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
642 auto rr = RoundSuperellipse::MakeRectRadii(
643 bounds, RoundingRadii::MakeRadii({5.0f, 5.0f}));
644
645#define CHECK_POINT_AND_MIRRORS(p) \
646 CHECK_POINT_WITH_OFFSET(rr, (p), Point(0.02, 0.02)); \
647 CHECK_POINT_WITH_OFFSET(rr, (p) * Point(1, -1), Point(0.02, -0.02)); \
648 CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, 1), Point(-0.02, 0.02)); \
649 CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, -1), Point(-0.02, -0.02));
650
651 CHECK_POINT_AND_MIRRORS(Point(0, 49.995)); // Top
652 CHECK_POINT_AND_MIRRORS(Point(44.245, 49.95)); // Top curve start
653 CHECK_POINT_AND_MIRRORS(Point(45.72, 49.87)); // Top joint
654 CHECK_POINT_AND_MIRRORS(Point(48.53, 48.53)); // Circular arc mid
655 CHECK_POINT_AND_MIRRORS(Point(49.87, 45.72)); // Right joint
656 CHECK_POINT_AND_MIRRORS(Point(49.95, 44.245)); // Right curve start
657 CHECK_POINT_AND_MIRRORS(Point(49.995, 0)); // Right
658#undef CHECK_POINT_AND_MIRRORS
659}
660
661TEST(RoundSuperellipseTest, UniformEllipticalContains) {
662 Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
663 auto rr = RoundSuperellipse::MakeRectRadii(
664 bounds, RoundingRadii::MakeRadii({5.0f, 10.0f}));
665
666#define CHECK_POINT_AND_MIRRORS(p) \
667 CHECK_POINT_WITH_OFFSET(rr, (p), Point(0.02, 0.02)); \
668 CHECK_POINT_WITH_OFFSET(rr, (p) * Point(1, -1), Point(0.02, -0.02)); \
669 CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, 1), Point(-0.02, 0.02)); \
670 CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, -1), Point(-0.02, -0.02));
671
672 CHECK_POINT_AND_MIRRORS(Point(0, 49.995)); // Top
673 CHECK_POINT_AND_MIRRORS(Point(44.245, 49.911)); // Top curve start
674 CHECK_POINT_AND_MIRRORS(Point(45.72, 49.75)); // Top joint
675 CHECK_POINT_AND_MIRRORS(Point(48.51, 47.07)); // Circular arc mid
676 CHECK_POINT_AND_MIRRORS(Point(49.87, 41.44)); // Right joint
677 CHECK_POINT_AND_MIRRORS(Point(49.95, 38.49)); // Right curve start
678 CHECK_POINT_AND_MIRRORS(Point(49.995, 0)); // Right
679#undef CHECK_POINT_AND_MIRRORS
680}
681
682TEST(RoundSuperellipseTest, UniformRectangularContains) {
683 // The bounds is not centered at the origin and has unequal height and width.
684 Rect bounds = Rect::MakeLTRB(0.0f, 0.0f, 50.0f, 100.0f);
685 auto rr = RoundSuperellipse::MakeRectRadii(
686 bounds, RoundingRadii::MakeRadii({23.0f, 30.0f}));
687
688 Point center = bounds.GetCenter();
689#define CHECK_POINT_AND_MIRRORS(p) \
690 CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(1, 1) + center, \
691 Point(0.02, 0.02)); \
692 CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(1, -1) + center, \
693 Point(0.02, -0.02)); \
694 CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(-1, 1) + center, \
695 Point(-0.02, 0.02)); \
696 CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(-1, -1) + center, \
697 Point(-0.02, -0.02));
698
699 CHECK_POINT_AND_MIRRORS(Point(24.99, 99.99)); // Bottom mid edge
700 CHECK_POINT_AND_MIRRORS(Point(29.99, 99.64));
701 CHECK_POINT_AND_MIRRORS(Point(34.99, 98.06));
702 CHECK_POINT_AND_MIRRORS(Point(39.99, 94.73));
703 CHECK_POINT_AND_MIRRORS(Point(44.13, 89.99));
704 CHECK_POINT_AND_MIRRORS(Point(48.46, 79.99));
705 CHECK_POINT_AND_MIRRORS(Point(49.70, 69.99));
706 CHECK_POINT_AND_MIRRORS(Point(49.97, 59.99));
707 CHECK_POINT_AND_MIRRORS(Point(49.99, 49.99)); // Right mid edge
708
709#undef CHECK_POINT_AND_MIRRORS
710}
711
712TEST(RoundSuperellipseTest, SlimDiagonalContains) {
713 // This shape has large radii on one diagonal and tiny radii on the other,
714 // resulting in a almond-like shape placed diagonally (NW to SE).
715 Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
716 auto rr = RoundSuperellipse::MakeRectRadii(
717 bounds, {
718 .top_left = Size(1.0, 1.0),
719 .top_right = Size(99.0, 99.0),
720 .bottom_left = Size(99.0, 99.0),
721 .bottom_right = Size(1.0, 1.0),
722 });
723
724 EXPECT_TRUE(rr.Contains(Point{0, 0}));
725 EXPECT_FALSE(rr.Contains(Point{-49.999, -49.999}));
726 EXPECT_FALSE(rr.Contains(Point{-49.999, 49.999}));
727 EXPECT_FALSE(rr.Contains(Point{49.999, 49.999}));
728 EXPECT_FALSE(rr.Contains(Point{49.999, -49.999}));
729
730 // The pointy ends at the NE and SW corners
731 CHECK_POINT_WITH_OFFSET(rr, Point(-49.70, -49.70), Point(-0.02, -0.02));
732 CHECK_POINT_WITH_OFFSET(rr, Point(49.70, 49.70), Point(0.02, 0.02));
733
734// Checks two points symmetrical to the origin.
735#define CHECK_DIAGONAL_POINTS(p) \
736 CHECK_POINT_WITH_OFFSET(rr, (p), Point(0.02, -0.02)); \
737 CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, -1), Point(-0.02, 0.02));
738
739 // A few other points along the edge
740 CHECK_DIAGONAL_POINTS(Point(-40.0, -49.59));
741 CHECK_DIAGONAL_POINTS(Point(-20.0, -45.64));
742 CHECK_DIAGONAL_POINTS(Point(0.0, -37.01));
743 CHECK_DIAGONAL_POINTS(Point(20.0, -21.96));
744 CHECK_DIAGONAL_POINTS(Point(21.05, -20.92));
745 CHECK_DIAGONAL_POINTS(Point(40.0, 5.68));
746#undef CHECK_POINT_AND_MIRRORS
747}
748
749TEST(RoundSuperellipseTest, PointsOutsideOfSharpCorner) {
750 Rect bounds = Rect::MakeLTRB(196.0f, 0.0f, 294.0f, 28.0f);
751 // Regression test for a case where RoundSuperellipseParam::Contains
752 // previously failed. Although the bounding rect filter of
753 // `RoundSuperellipse::Contains` would reject this point, this test ensures
754 // the internal logic of RoundSuperellipseParam::Contains is now correct.
755 auto rr = RoundSuperellipseParam::MakeBoundsRadii(
756 bounds, {
757 .top_left = Size(0.0, 0.0),
758 .top_right = Size(3.0, 3.0),
759 .bottom_left = Size(0.0, 0.0),
760 .bottom_right = Size(3.0, 3.0),
761 });
762
763 EXPECT_FALSE(rr.Contains(Point{147.0, 14.0}));
764}
765
766TEST(RoundSuperellipseTest,
767 PathForRectangularRseWithShapeCornersShouldBeWithinBounds) {
768 Rect bounds = Rect::MakeLTRB(34.0f, 242.0f, 766.0f, 358.0f);
769 // Regression test for https://github.com/flutter/flutter/issues/170593.
770 // The issue was caused by incorrect calculation when building paths for
771 // rounded superellipses with sharp corners and unequal width and height.
772 // Since the most obvious symptom of the issue is some points being
773 // incorrectly placed out of bounds, this test case simply verifies that all
774 // points are within the bounds.
775
776 auto rr = RoundSuperellipseParam::MakeBoundsRadii(
777 bounds, {
778 .top_left = Size(14.0, 14.0),
779 .top_right = Size(14.0, 14.0),
780 .bottom_left = Size(0.0, 0.0),
781 .bottom_right = Size(0.0, 0.0),
782 });
783 SpyPathReceiver receiver;
784 receiver.SpyLineTo(
785 [&](const Point& p2) { EXPECT_TRUE(bounds.ContainsInclusive(p2)); });
786 receiver.SpyCubicTo([&](const Point& cp1, const Point& cp2, const Point& p2) {
787 EXPECT_TRUE(bounds.ContainsInclusive(p2));
788 });
789
790 rr.Dispatch(receiver);
791}
792
793TEST(RoundSuperellipseTest, PathForLongRseShouldBeCorrect) {
794 Rect bounds = Rect::MakeLTRB(0, 0, 300, 100000);
795 // Regression test for https://github.com/flutter/flutter/issues/179875.
796
797 auto rr = RoundSuperellipseParam::MakeBoundsRadius(bounds, 100);
798 SpyPathReceiver receiver;
799 receiver.SpyLineTo(
800 [&](const Point& p2) { EXPECT_TRUE(bounds.ContainsInclusive(p2)); });
801 receiver.SpyCubicTo([&](const Point& cp1, const Point& cp2, const Point& p2) {
802 EXPECT_TRUE(bounds.ContainsInclusive(cp1));
803 EXPECT_TRUE(bounds.ContainsInclusive(cp2));
804 EXPECT_TRUE(bounds.ContainsInclusive(p2));
805 });
806 receiver.SpyConicTo([&](const Point& cp, const Point& p2, Scalar weight) {
807 EXPECT_TRUE(bounds.ContainsInclusive(cp));
808 EXPECT_TRUE(bounds.ContainsInclusive(p2));
809 });
810
811 rr.Dispatch(receiver);
812}
813
814} // namespace testing
815} // namespace impeller
TEST(AsciiTableTest, Simple)
TRect< Scalar > Rect
Definition rect.h:788
TPoint< Scalar > Point
Definition point.h:425
TSize< Scalar > Size
Definition size.h:159
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
void CubicTo(PathBuilder *builder, Scalar x1, Scalar y1, Scalar x2, Scalar y2, Scalar x3, Scalar y3)
void Close(PathBuilder *builder)
#define CHECK_DIAGONAL_POINTS(p)
#define CHECK_POINT_AND_MIRRORS(p)