| Flutter Impeller |

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