5#include "gtest/gtest.h"
7#include "flutter/impeller/geometry/rect.h"
9#include "flutter/impeller/geometry/geometry_asserts.h"
14TEST(RectTest, RectEmptyDeclaration) {
17 EXPECT_EQ(
rect.GetLeft(), 0.0f);
18 EXPECT_EQ(
rect.GetTop(), 0.0f);
19 EXPECT_EQ(
rect.GetRight(), 0.0f);
20 EXPECT_EQ(
rect.GetBottom(), 0.0f);
21 EXPECT_EQ(
rect.GetX(), 0.0f);
22 EXPECT_EQ(
rect.GetY(), 0.0f);
23 EXPECT_EQ(
rect.GetWidth(), 0.0f);
24 EXPECT_EQ(
rect.GetHeight(), 0.0f);
29TEST(RectTest, IRectEmptyDeclaration) {
32 EXPECT_EQ(
rect.GetLeft(), 0);
33 EXPECT_EQ(
rect.GetTop(), 0);
34 EXPECT_EQ(
rect.GetRight(), 0);
35 EXPECT_EQ(
rect.GetBottom(), 0);
36 EXPECT_EQ(
rect.GetX(), 0);
37 EXPECT_EQ(
rect.GetY(), 0);
38 EXPECT_EQ(
rect.GetWidth(), 0);
39 EXPECT_EQ(
rect.GetHeight(), 0);
44TEST(RectTest, RectDefaultConstructor) {
47 EXPECT_EQ(
rect.GetLeft(), 0.0f);
48 EXPECT_EQ(
rect.GetTop(), 0.0f);
49 EXPECT_EQ(
rect.GetRight(), 0.0f);
50 EXPECT_EQ(
rect.GetBottom(), 0.0f);
51 EXPECT_EQ(
rect.GetX(), 0.0f);
52 EXPECT_EQ(
rect.GetY(), 0.0f);
53 EXPECT_EQ(
rect.GetWidth(), 0.0f);
54 EXPECT_EQ(
rect.GetHeight(), 0.0f);
59TEST(RectTest, IRectDefaultConstructor) {
62 EXPECT_EQ(
rect.GetLeft(), 0);
63 EXPECT_EQ(
rect.GetTop(), 0);
64 EXPECT_EQ(
rect.GetRight(), 0);
65 EXPECT_EQ(
rect.GetBottom(), 0);
66 EXPECT_EQ(
rect.GetX(), 0);
67 EXPECT_EQ(
rect.GetY(), 0);
68 EXPECT_EQ(
rect.GetWidth(), 0);
69 EXPECT_EQ(
rect.GetHeight(), 0);
73TEST(RectTest, RectSimpleLTRB) {
77 EXPECT_EQ(
rect.GetLeft(), 5.125f);
78 EXPECT_EQ(
rect.GetTop(), 10.25f);
79 EXPECT_EQ(
rect.GetRight(), 20.625f);
80 EXPECT_EQ(
rect.GetBottom(), 25.375f);
81 EXPECT_EQ(
rect.GetX(), 5.125f);
82 EXPECT_EQ(
rect.GetY(), 10.25f);
83 EXPECT_EQ(
rect.GetWidth(), 15.5f);
84 EXPECT_EQ(
rect.GetHeight(), 15.125f);
85 EXPECT_FALSE(
rect.IsEmpty());
89TEST(RectTest, IRectSimpleLTRB) {
92 EXPECT_EQ(
rect.GetLeft(), 5);
93 EXPECT_EQ(
rect.GetTop(), 10);
94 EXPECT_EQ(
rect.GetRight(), 20);
95 EXPECT_EQ(
rect.GetBottom(), 25);
96 EXPECT_EQ(
rect.GetX(), 5);
97 EXPECT_EQ(
rect.GetY(), 10);
98 EXPECT_EQ(
rect.GetWidth(), 15);
99 EXPECT_EQ(
rect.GetHeight(), 15);
100 EXPECT_FALSE(
rect.IsEmpty());
103TEST(RectTest, RectSimpleXYWH) {
107 EXPECT_EQ(
rect.GetLeft(), 5.125f);
108 EXPECT_EQ(
rect.GetTop(), 10.25f);
109 EXPECT_EQ(
rect.GetRight(), 20.625f);
110 EXPECT_EQ(
rect.GetBottom(), 25.375f);
111 EXPECT_EQ(
rect.GetX(), 5.125f);
112 EXPECT_EQ(
rect.GetY(), 10.25f);
113 EXPECT_EQ(
rect.GetWidth(), 15.5f);
114 EXPECT_EQ(
rect.GetHeight(), 15.125f);
115 EXPECT_FALSE(
rect.IsEmpty());
119TEST(RectTest, IRectSimpleXYWH) {
122 EXPECT_EQ(
rect.GetLeft(), 5);
123 EXPECT_EQ(
rect.GetTop(), 10);
124 EXPECT_EQ(
rect.GetRight(), 20);
125 EXPECT_EQ(
rect.GetBottom(), 26);
126 EXPECT_EQ(
rect.GetX(), 5);
127 EXPECT_EQ(
rect.GetY(), 10);
128 EXPECT_EQ(
rect.GetWidth(), 15);
129 EXPECT_EQ(
rect.GetHeight(), 16);
130 EXPECT_FALSE(
rect.IsEmpty());
133TEST(RectTest, RectOverflowXYWH) {
134 auto min = std::numeric_limits<Scalar>::lowest();
136 auto inf = std::numeric_limits<Scalar>::infinity();
154 EXPECT_EQ(
rect.GetLeft(), 5.0f);
155 EXPECT_EQ(
rect.GetTop(), 10.0f);
156 EXPECT_EQ(
rect.GetRight(),
max);
157 EXPECT_EQ(
rect.GetBottom(), 25.0f);
158 EXPECT_EQ(
rect.GetX(), 5.0f);
159 EXPECT_EQ(
rect.GetY(), 10.0f);
160 EXPECT_EQ(
rect.GetWidth(),
max);
161 EXPECT_EQ(
rect.GetHeight(), 15.0f);
162 EXPECT_FALSE(
rect.IsEmpty());
169 EXPECT_EQ(
rect.GetLeft(),
max);
170 EXPECT_EQ(
rect.GetTop(), 10.0f);
171 EXPECT_EQ(
rect.GetRight(), inf);
172 EXPECT_EQ(
rect.GetBottom(), 25.0f);
174 EXPECT_EQ(
rect.GetY(), 10.0f);
175 EXPECT_EQ(
rect.GetWidth(), inf);
176 EXPECT_EQ(
rect.GetHeight(), 15.0f);
177 EXPECT_FALSE(
rect.IsEmpty());
178 EXPECT_FALSE(
rect.IsFinite());
184 EXPECT_EQ(
rect.GetLeft(), 5.0f);
185 EXPECT_EQ(
rect.GetTop(), 10.0f);
186 EXPECT_EQ(
rect.GetRight(), 25.0f);
187 EXPECT_EQ(
rect.GetBottom(),
max);
188 EXPECT_EQ(
rect.GetX(), 5.0f);
189 EXPECT_EQ(
rect.GetY(), 10.0f);
190 EXPECT_EQ(
rect.GetWidth(), 20.0f);
191 EXPECT_EQ(
rect.GetHeight(),
max);
192 EXPECT_FALSE(
rect.IsEmpty());
199 EXPECT_EQ(
rect.GetLeft(), 5.0f);
201 EXPECT_EQ(
rect.GetRight(), 25.0f);
202 EXPECT_EQ(
rect.GetBottom(), inf);
203 EXPECT_EQ(
rect.GetX(), 5.0f);
205 EXPECT_EQ(
rect.GetWidth(), 20.0f);
206 EXPECT_EQ(
rect.GetHeight(), inf);
207 EXPECT_FALSE(
rect.IsEmpty());
208 EXPECT_FALSE(
rect.IsFinite());
214 EXPECT_EQ(
rect.GetLeft(), 5.0f);
215 EXPECT_EQ(
rect.GetTop(), 10.0f);
216 EXPECT_EQ(
rect.GetRight(),
min);
217 EXPECT_EQ(
rect.GetBottom(), 25.0f);
218 EXPECT_EQ(
rect.GetX(), 5.0f);
219 EXPECT_EQ(
rect.GetY(), 10.0f);
220 EXPECT_EQ(
rect.GetWidth(),
min);
221 EXPECT_EQ(
rect.GetHeight(), 15.0f);
229 EXPECT_EQ(
rect.GetLeft(),
min);
230 EXPECT_EQ(
rect.GetTop(), 10.0f);
231 EXPECT_EQ(
rect.GetRight(), -inf);
232 EXPECT_EQ(
rect.GetBottom(), 25.0f);
234 EXPECT_EQ(
rect.GetY(), 10.0f);
235 EXPECT_EQ(
rect.GetWidth(), -inf);
236 EXPECT_EQ(
rect.GetHeight(), 15.0f);
238 EXPECT_FALSE(
rect.IsFinite());
244 EXPECT_EQ(
rect.GetLeft(), 5.0f);
245 EXPECT_EQ(
rect.GetTop(), 10.0f);
246 EXPECT_EQ(
rect.GetRight(), 25.0f);
247 EXPECT_EQ(
rect.GetBottom(),
min);
248 EXPECT_EQ(
rect.GetX(), 5.0f);
249 EXPECT_EQ(
rect.GetY(), 10.0f);
250 EXPECT_EQ(
rect.GetWidth(), 20.0f);
251 EXPECT_EQ(
rect.GetHeight(),
min);
259 EXPECT_EQ(
rect.GetLeft(), 5.0f);
261 EXPECT_EQ(
rect.GetRight(), 25.0f);
262 EXPECT_EQ(
rect.GetBottom(), -inf);
263 EXPECT_EQ(
rect.GetX(), 5.0f);
265 EXPECT_EQ(
rect.GetWidth(), 20.0f);
266 EXPECT_EQ(
rect.GetHeight(), -inf);
268 EXPECT_FALSE(
rect.IsFinite());
272TEST(RectTest, IRectOverflowXYWH) {
285 EXPECT_EQ(
rect.GetLeft(),
max - 5);
286 EXPECT_EQ(
rect.GetTop(), 10);
287 EXPECT_EQ(
rect.GetRight(),
max);
288 EXPECT_EQ(
rect.GetBottom(), 26);
289 EXPECT_EQ(
rect.GetX(),
max - 5);
290 EXPECT_EQ(
rect.GetY(), 10);
291 EXPECT_EQ(
rect.GetWidth(), 5);
292 EXPECT_EQ(
rect.GetHeight(), 16);
293 EXPECT_FALSE(
rect.IsEmpty());
299 EXPECT_EQ(
rect.GetLeft(),
min + 5);
300 EXPECT_EQ(
rect.GetTop(), 10);
301 EXPECT_EQ(
rect.GetRight(),
min);
302 EXPECT_EQ(
rect.GetBottom(), 26);
303 EXPECT_EQ(
rect.GetX(),
min + 5);
304 EXPECT_EQ(
rect.GetY(), 10);
305 EXPECT_EQ(
rect.GetWidth(), -5);
306 EXPECT_EQ(
rect.GetHeight(), 16);
313 EXPECT_EQ(
rect.GetLeft(), 5);
314 EXPECT_EQ(
rect.GetTop(),
max - 10);
315 EXPECT_EQ(
rect.GetRight(), 15);
316 EXPECT_EQ(
rect.GetBottom(),
max);
317 EXPECT_EQ(
rect.GetX(), 5);
318 EXPECT_EQ(
rect.GetY(),
max - 10);
319 EXPECT_EQ(
rect.GetWidth(), 10);
320 EXPECT_EQ(
rect.GetHeight(), 10);
321 EXPECT_FALSE(
rect.IsEmpty());
327 EXPECT_EQ(
rect.GetLeft(), 5);
328 EXPECT_EQ(
rect.GetTop(),
min + 10);
329 EXPECT_EQ(
rect.GetRight(), 15);
330 EXPECT_EQ(
rect.GetBottom(),
min);
331 EXPECT_EQ(
rect.GetX(), 5);
332 EXPECT_EQ(
rect.GetY(),
min + 10);
333 EXPECT_EQ(
rect.GetWidth(), 10);
334 EXPECT_EQ(
rect.GetHeight(), -10);
339TEST(RectTest, RectOverflowLTRB) {
340 auto min = std::numeric_limits<Scalar>::lowest();
342 auto inf = std::numeric_limits<Scalar>::infinity();
360 EXPECT_EQ(
rect.GetLeft(), -5.0f);
361 EXPECT_EQ(
rect.GetTop(), 10.0f);
362 EXPECT_EQ(
rect.GetRight(),
max);
363 EXPECT_EQ(
rect.GetBottom(), 25.0f);
364 EXPECT_EQ(
rect.GetX(), -5.0f);
365 EXPECT_EQ(
rect.GetY(), 10.0f);
366 EXPECT_EQ(
rect.GetWidth(),
max);
367 EXPECT_EQ(
rect.GetHeight(), 15.0f);
368 EXPECT_FALSE(
rect.IsEmpty());
375 EXPECT_EQ(
rect.GetLeft(),
min + 5.0f);
376 EXPECT_EQ(
rect.GetTop(), 10.0f);
377 EXPECT_EQ(
rect.GetRight(),
max - 5.0f);
378 EXPECT_EQ(
rect.GetBottom(), 25.0f);
379 EXPECT_EQ(
rect.GetX(),
min + 5.0f);
380 EXPECT_EQ(
rect.GetY(), 10.0f);
381 EXPECT_EQ(
rect.GetWidth(), inf);
382 EXPECT_EQ(
rect.GetHeight(), 15.0f);
383 EXPECT_FALSE(
rect.IsEmpty());
390 EXPECT_EQ(
rect.GetLeft(), 5.0f);
391 EXPECT_EQ(
rect.GetTop(), -10.0f);
392 EXPECT_EQ(
rect.GetRight(), 20.0f);
393 EXPECT_EQ(
rect.GetBottom(),
max);
394 EXPECT_EQ(
rect.GetX(), 5.0f);
395 EXPECT_EQ(
rect.GetY(), -10.0f);
396 EXPECT_EQ(
rect.GetWidth(), 15.0f);
397 EXPECT_EQ(
rect.GetHeight(),
max);
398 EXPECT_FALSE(
rect.IsEmpty());
405 EXPECT_EQ(
rect.GetLeft(), 5.0f);
406 EXPECT_EQ(
rect.GetTop(),
min + 10.0f);
407 EXPECT_EQ(
rect.GetRight(), 20.0f);
408 EXPECT_EQ(
rect.GetBottom(),
max - 15.0f);
409 EXPECT_EQ(
rect.GetX(), 5.0f);
410 EXPECT_EQ(
rect.GetY(),
min + 10.0f);
411 EXPECT_EQ(
rect.GetWidth(), 15.0f);
412 EXPECT_EQ(
rect.GetHeight(), inf);
413 EXPECT_FALSE(
rect.IsEmpty());
420 EXPECT_EQ(
rect.GetLeft(), 5.0f);
421 EXPECT_EQ(
rect.GetTop(), 10.0f);
422 EXPECT_EQ(
rect.GetRight(),
min);
423 EXPECT_EQ(
rect.GetBottom(), 25.0f);
424 EXPECT_EQ(
rect.GetX(), 5.0f);
425 EXPECT_EQ(
rect.GetY(), 10.0f);
426 EXPECT_EQ(
rect.GetWidth(),
min);
427 EXPECT_EQ(
rect.GetHeight(), 15.0f);
435 EXPECT_EQ(
rect.GetLeft(),
max - 5.0f);
436 EXPECT_EQ(
rect.GetTop(), 10.0f);
437 EXPECT_EQ(
rect.GetRight(),
min + 10.0f);
438 EXPECT_EQ(
rect.GetBottom(), 25.0f);
439 EXPECT_EQ(
rect.GetX(),
max - 5.0f);
440 EXPECT_EQ(
rect.GetY(), 10.0f);
441 EXPECT_EQ(
rect.GetWidth(), -inf);
442 EXPECT_EQ(
rect.GetHeight(), 15.0f);
450 EXPECT_EQ(
rect.GetLeft(), 5.0f);
451 EXPECT_EQ(
rect.GetTop(), 10.0f);
452 EXPECT_EQ(
rect.GetRight(), 20.0f);
453 EXPECT_EQ(
rect.GetBottom(),
min);
454 EXPECT_EQ(
rect.GetX(), 5.0f);
455 EXPECT_EQ(
rect.GetY(), 10.0f);
456 EXPECT_EQ(
rect.GetWidth(), 15.0f);
457 EXPECT_EQ(
rect.GetHeight(),
min);
465 EXPECT_EQ(
rect.GetLeft(), 5.0f);
466 EXPECT_EQ(
rect.GetTop(),
max - 5.0f);
467 EXPECT_EQ(
rect.GetRight(), 20.0f);
468 EXPECT_EQ(
rect.GetBottom(),
min + 10.0f);
469 EXPECT_EQ(
rect.GetX(), 5.0f);
470 EXPECT_EQ(
rect.GetY(),
max - 5.0f);
471 EXPECT_EQ(
rect.GetWidth(), 15.0f);
472 EXPECT_EQ(
rect.GetHeight(), -inf);
478TEST(RectTest, IRectOverflowLTRB) {
491 EXPECT_EQ(
rect.GetLeft(), -10);
492 EXPECT_EQ(
rect.GetTop(), 10);
493 EXPECT_EQ(
rect.GetRight(),
max - 5);
494 EXPECT_EQ(
rect.GetBottom(), 26);
495 EXPECT_EQ(
rect.GetX(), -10);
496 EXPECT_EQ(
rect.GetY(), 10);
497 EXPECT_EQ(
rect.GetWidth(),
max);
498 EXPECT_EQ(
rect.GetHeight(), 16);
499 EXPECT_FALSE(
rect.IsEmpty());
505 EXPECT_EQ(
rect.GetLeft(), 10);
506 EXPECT_EQ(
rect.GetTop(), 10);
507 EXPECT_EQ(
rect.GetRight(),
min + 5);
508 EXPECT_EQ(
rect.GetBottom(), 26);
509 EXPECT_EQ(
rect.GetX(), 10);
510 EXPECT_EQ(
rect.GetY(), 10);
511 EXPECT_EQ(
rect.GetWidth(),
min);
512 EXPECT_EQ(
rect.GetHeight(), 16);
519 EXPECT_EQ(
rect.GetLeft(), 5);
520 EXPECT_EQ(
rect.GetTop(), -10);
521 EXPECT_EQ(
rect.GetRight(), 15);
522 EXPECT_EQ(
rect.GetBottom(),
max - 5);
523 EXPECT_EQ(
rect.GetX(), 5);
524 EXPECT_EQ(
rect.GetY(), -10);
525 EXPECT_EQ(
rect.GetWidth(), 10);
526 EXPECT_EQ(
rect.GetHeight(),
max);
527 EXPECT_FALSE(
rect.IsEmpty());
533 EXPECT_EQ(
rect.GetLeft(), 5);
534 EXPECT_EQ(
rect.GetTop(), 10);
535 EXPECT_EQ(
rect.GetRight(), 15);
536 EXPECT_EQ(
rect.GetBottom(),
min + 5);
537 EXPECT_EQ(
rect.GetX(), 5);
538 EXPECT_EQ(
rect.GetY(), 10);
539 EXPECT_EQ(
rect.GetWidth(), 10);
540 EXPECT_EQ(
rect.GetHeight(),
min);
564 EXPECT_EQ(r, expected);
571 EXPECT_EQ(r, expected);
575TEST(RectTest, RectMakeMaximum) {
577 auto inf = std::numeric_limits<Scalar>::infinity();
578 auto min = std::numeric_limits<Scalar>::lowest();
581 EXPECT_EQ(
rect.GetLeft(),
min);
583 EXPECT_EQ(
rect.GetRight(),
max);
584 EXPECT_EQ(
rect.GetBottom(),
max);
587 EXPECT_EQ(
rect.GetWidth(), inf);
588 EXPECT_EQ(
rect.GetHeight(), inf);
589 EXPECT_FALSE(
rect.IsEmpty());
593TEST(RectTest, IRectMakeMaximum) {
598 EXPECT_EQ(
rect.GetLeft(),
min);
600 EXPECT_EQ(
rect.GetRight(),
max);
601 EXPECT_EQ(
rect.GetBottom(),
max);
604 EXPECT_EQ(
rect.GetWidth(),
max);
605 EXPECT_EQ(
rect.GetHeight(),
max);
606 EXPECT_FALSE(
rect.IsEmpty());
616TEST(RectTest, IRectFromIRect) {
629 EXPECT_EQ(
copy.GetLeft(), 5.125f);
630 EXPECT_EQ(
copy.GetTop(), 10.25f);
631 EXPECT_EQ(
copy.GetRight(), 20.625f);
632 EXPECT_EQ(
copy.GetBottom(), 25.375f);
633 EXPECT_EQ(
copy.GetX(), 5.125f);
634 EXPECT_EQ(
copy.GetY(), 10.25f);
635 EXPECT_EQ(
copy.GetWidth(), 15.5f);
636 EXPECT_EQ(
copy.GetHeight(), 15.125f);
637 EXPECT_FALSE(
copy.IsEmpty());
646 EXPECT_EQ(
copy.GetLeft(), 5);
647 EXPECT_EQ(
copy.GetTop(), 10);
648 EXPECT_EQ(
copy.GetRight(), 20);
649 EXPECT_EQ(
copy.GetBottom(), 25);
650 EXPECT_EQ(
copy.GetX(), 5);
651 EXPECT_EQ(
copy.GetY(), 10);
652 EXPECT_EQ(
copy.GetWidth(), 15);
653 EXPECT_EQ(
copy.GetHeight(), 15);
654 EXPECT_FALSE(
copy.IsEmpty());
657TEST(RectTest, RectOriginSizeXYWHGetters) {
660 EXPECT_EQ(r.GetOrigin(),
Point(10, 20));
661 EXPECT_EQ(r.GetSize(),
Size(50, 40));
662 EXPECT_EQ(r.GetX(), 10);
663 EXPECT_EQ(r.GetY(), 20);
664 EXPECT_EQ(r.GetWidth(), 50);
665 EXPECT_EQ(r.GetHeight(), 40);
666 auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
667 EXPECT_EQ(r.GetXYWH(), expected_array);
672 EXPECT_EQ(r.GetOrigin(),
Point(10, 20));
673 EXPECT_EQ(r.GetSize(),
Size(40, 20));
674 EXPECT_EQ(r.GetX(), 10);
675 EXPECT_EQ(r.GetY(), 20);
676 EXPECT_EQ(r.GetWidth(), 40);
677 EXPECT_EQ(r.GetHeight(), 20);
678 auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
679 EXPECT_EQ(r.GetXYWH(), expected_array);
683TEST(RectTest, IRectOriginSizeXYWHGetters) {
688 EXPECT_EQ(r.
GetX(), 10);
689 EXPECT_EQ(r.
GetY(), 20);
692 auto expected_array = std::array<int64_t, 4>{10, 20, 50, 40};
693 EXPECT_EQ(r.
GetXYWH(), expected_array);
700 EXPECT_EQ(r.
GetX(), 10);
701 EXPECT_EQ(r.
GetY(), 20);
704 auto expected_array = std::array<int64_t, 4>{10, 20, 40, 20};
705 EXPECT_EQ(r.
GetXYWH(), expected_array);
709TEST(RectTest, RectRoundOutEmpty) {
717TEST(RectTest, RectRoundOutSimple) {
725TEST(RectTest, RectRoundOutToIRectHuge) {
726 auto test = [](
int corners) {
729 int64_t il, it, ir, ib;
734 if ((corners & (1 << 0)) != 0) {
738 if ((corners & (1 << 1)) != 0) {
742 if ((corners & (1 << 2)) != 0) {
746 if ((corners & (1 << 3)) != 0) {
753 EXPECT_EQ(irect.
GetLeft(), il) << corners;
754 EXPECT_EQ(irect.
GetTop(), it) << corners;
755 EXPECT_EQ(irect.
GetRight(), ir) << corners;
756 EXPECT_EQ(irect.
GetBottom(), ib) << corners;
759 for (
int corners = 0; corners <= 15; corners++) {
764TEST(RectTest, RectDoesNotIntersectEmpty) {
768 const std::string& label) {
770 << label <<
" with Top/Bottom swapped";
772 << label <<
" with Left/Right swapped";
774 << label <<
" with all sides swapped";
777 test(20, 20, 30, 30,
"Above and Left");
778 test(70, 20, 80, 30,
"Above");
779 test(120, 20, 130, 30,
"Above and Right");
780 test(120, 70, 130, 80,
"Right");
781 test(120, 120, 130, 130,
"Below and Right");
782 test(70, 120, 80, 130,
"Below");
783 test(20, 120, 30, 130,
"Below and Left");
784 test(20, 70, 30, 80,
"Left");
786 test(70, 70, 80, 80,
"Inside");
788 test(40, 70, 60, 80,
"Straddling Left");
789 test(70, 40, 80, 60,
"Straddling Top");
790 test(90, 70, 110, 80,
"Straddling Right");
791 test(70, 90, 80, 110,
"Straddling Bottom");
794TEST(RectTest, IRectDoesNotIntersectEmpty) {
797 auto test = [&
rect](int64_t l, int64_t t, int64_t r, int64_t
b,
798 const std::string& label) {
800 << label <<
" with Top/Bottom swapped";
802 << label <<
" with Left/Right swapped";
804 << label <<
" with all sides swapped";
807 test(20, 20, 30, 30,
"Above and Left");
808 test(70, 20, 80, 30,
"Above");
809 test(120, 20, 130, 30,
"Above and Right");
810 test(120, 70, 130, 80,
"Right");
811 test(120, 120, 130, 130,
"Below and Right");
812 test(70, 120, 80, 130,
"Below");
813 test(20, 120, 30, 130,
"Below and Left");
814 test(20, 70, 30, 80,
"Left");
816 test(70, 70, 80, 80,
"Inside");
818 test(40, 70, 60, 80,
"Straddling Left");
819 test(70, 40, 80, 60,
"Straddling Top");
820 test(90, 70, 110, 80,
"Straddling Right");
821 test(70, 90, 80, 110,
"Straddling Bottom");
824TEST(RectTest, EmptyRectDoesNotIntersect) {
828 const std::string& label) {
830 << label <<
" with Top/Bottom swapped";
832 << label <<
" with Left/Right swapped";
834 << label <<
" with all sides swapped";
837 test(20, 20, 30, 30,
"Above and Left");
838 test(70, 20, 80, 30,
"Above");
839 test(120, 20, 130, 30,
"Above and Right");
840 test(120, 70, 130, 80,
"Right");
841 test(120, 120, 130, 130,
"Below and Right");
842 test(70, 120, 80, 130,
"Below");
843 test(20, 120, 30, 130,
"Below and Left");
844 test(20, 70, 30, 80,
"Left");
846 test(70, 70, 80, 80,
"Inside");
848 test(40, 70, 60, 80,
"Straddling Left");
849 test(70, 40, 80, 60,
"Straddling Top");
850 test(90, 70, 110, 80,
"Straddling Right");
851 test(70, 90, 80, 110,
"Straddling Bottom");
854TEST(RectTest, EmptyIRectDoesNotIntersect) {
857 auto test = [&
rect](int64_t l, int64_t t, int64_t r, int64_t
b,
858 const std::string& label) {
860 << label <<
" with Top/Bottom swapped";
862 << label <<
" with Left/Right swapped";
864 << label <<
" with all sides swapped";
867 test(20, 20, 30, 30,
"Above and Left");
868 test(70, 20, 80, 30,
"Above");
869 test(120, 20, 130, 30,
"Above and Right");
870 test(120, 70, 130, 80,
"Right");
871 test(120, 120, 130, 130,
"Below and Right");
872 test(70, 120, 80, 130,
"Below");
873 test(20, 120, 30, 130,
"Below and Left");
874 test(20, 70, 30, 80,
"Left");
876 test(70, 70, 80, 80,
"Inside");
878 test(40, 70, 60, 80,
"Straddling Left");
879 test(70, 40, 80, 60,
"Straddling Top");
880 test(90, 70, 110, 80,
"Straddling Right");
881 test(70, 90, 80, 110,
"Straddling Bottom");
903 rect.GetY() * scale_y,
904 rect.GetWidth() * scale_x,
905 rect.GetHeight() * scale_y);
908 <<
rect <<
" * " << scale_x <<
", " << scale_y;
910 <<
rect <<
" * " << scale_x <<
", " << scale_y;
912 <<
rect <<
" * " << scale_x <<
", " << scale_y;
946 auto test2 = [&
test1](
IRect rect, int64_t scale_x, int64_t scale_y) {
948 rect.GetY() * scale_y,
949 rect.GetWidth() * scale_x,
950 rect.GetHeight() * scale_y);
952 EXPECT_EQ(
rect.Scale(scale_x, scale_y), expected)
953 <<
rect <<
" * " << scale_x <<
", " << scale_y;
954 EXPECT_EQ(
rect.Scale(
IPoint(scale_x, scale_y)), expected)
955 <<
rect <<
" * " << scale_x <<
", " << scale_y;
956 EXPECT_EQ(
rect.Scale(
ISize(scale_x, scale_y)), expected)
957 <<
rect <<
" * " << scale_x <<
", " << scale_y;
989TEST(RectTest, RectGetNormalizingTransform) {
995 EXPECT_EQ(r.GetNormalizingTransform(),
1004 auto m = r.GetNormalizingTransform();
1028 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1029 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1030 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1033 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1034 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1035 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1042 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1043 auto inf = std::numeric_limits<Scalar>::infinity();
1046 EXPECT_EQ(
Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1047 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1048 EXPECT_EQ(
Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1051 EXPECT_EQ(
Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1052 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1053 EXPECT_EQ(
Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1056 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1057 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1058 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1061 EXPECT_EQ(
Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1062 EXPECT_EQ(
Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1063 EXPECT_EQ(
Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1066 EXPECT_EQ(
Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1067 EXPECT_EQ(
Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1068 EXPECT_EQ(
Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1071 EXPECT_EQ(
Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1072 EXPECT_EQ(
Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1073 EXPECT_EQ(
Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1077TEST(RectTest, IRectGetNormalizingTransform) {
1083 EXPECT_EQ(r.GetNormalizingTransform(),
1092 auto m = r.GetNormalizingTransform();
1116 EXPECT_EQ(
IRect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1117 EXPECT_EQ(
IRect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1118 EXPECT_EQ(
IRect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1121 EXPECT_EQ(
IRect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1122 EXPECT_EQ(
IRect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1123 EXPECT_EQ(
IRect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1128 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1168TEST(RectTest, MakePointBoundsQuad) {
1177 if (
bounds.has_value()) {
1271TEST(RectTest, ContainsFloatingPoint) {
1273 Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
1278template <
typename R>
1280 return R::MakeLTRB(
rect.GetRight(),
rect.GetTop(),
1284template <
typename R>
1286 return R::MakeLTRB(
rect.GetLeft(),
rect.GetBottom(),
1290template <
typename R>
1296 Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1298 Scalar l = ((index & (1 << 0)) != 0) ? nan :
rect.GetLeft();
1299 Scalar t = ((index & (1 << 1)) != 0) ? nan :
rect.GetTop();
1300 Scalar r = ((index & (1 << 2)) != 0) ? nan :
rect.GetRight();
1301 Scalar b = ((index & (1 << 3)) != 0) ? nan :
rect.GetBottom();
1306 Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1308 Scalar x = ((index & (1 << 0)) != 0) ? nan : point.
x;
1309 Scalar y = ((index & (1 << 1)) != 0) ? nan : point.
y;
1314 auto check_nans = [](
const Rect&
a,
const Rect&
b,
const std::string& label) {
1315 ASSERT_TRUE(
a.IsFinite()) << label;
1316 ASSERT_TRUE(
b.IsFinite()) << label;
1317 ASSERT_FALSE(
a.Union(
b).IsEmpty());
1319 for (
int i = 1;
i < 16;
i++) {
1323 EXPECT_EQ(
a.Union(
swap_nan(
b,
i)),
a) << label <<
", index = " <<
i;
1325 for (
int j = 1; j < 16; j++) {
1327 << label <<
", indices = " <<
i <<
", " << j;
1332 auto check_empty_flips = [](
const Rect&
a,
const Rect&
b,
1333 const std::string& label) {
1334 ASSERT_FALSE(
a.IsEmpty());
1353 auto test = [&check_nans, &check_empty_flips](
const Rect&
a,
const Rect&
b,
1355 ASSERT_FALSE(
a.IsEmpty()) <<
a;
1358 std::stringstream
stream;
1360 auto label =
stream.str();
1362 EXPECT_EQ(
a.Union(
b),
result) << label;
1363 EXPECT_EQ(
b.Union(
a),
result) << label;
1364 check_empty_flips(
a,
b, label);
1365 check_nans(
a,
b, label);
1410 EXPECT_FALSE(
Rect::Union(std::nullopt, std::nullopt).has_value());
1411 EXPECT_EQ(
Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1436 ASSERT_EQ(
a.Union(
b), u);
1457 auto check_empty_flips = [](
const IRect&
a,
const IRect&
b,
1458 const std::string& label) {
1459 ASSERT_FALSE(
a.IsEmpty());
1480 ASSERT_FALSE(
a.IsEmpty()) <<
a;
1483 std::stringstream
stream;
1485 auto label =
stream.str();
1487 EXPECT_EQ(
a.Union(
b),
result) << label;
1488 EXPECT_EQ(
b.Union(
a),
result) << label;
1489 check_empty_flips(
a,
b, label);
1534 EXPECT_FALSE(
IRect::Union(std::nullopt, std::nullopt).has_value());
1535 EXPECT_EQ(
IRect::Union(std::nullopt, std::nullopt), std::nullopt);
1560 ASSERT_EQ(
a.Union(
b), u);
1581 auto check_nans = [](
const Rect&
a,
const Rect&
b,
const std::string& label) {
1582 ASSERT_TRUE(
a.IsFinite()) << label;
1583 ASSERT_TRUE(
b.IsFinite()) << label;
1585 for (
int i = 1;
i < 16;
i++) {
1587 EXPECT_FALSE(
swap_nan(
a,
i).Intersection(
b).has_value())
1588 << label <<
", index = " <<
i;
1590 EXPECT_FALSE(
a.Intersection(
swap_nan(
b,
i)).has_value())
1591 << label <<
", index = " <<
i;
1593 for (
int j = 1; j < 16; j++) {
1595 << label <<
", indices = " <<
i <<
", " << j;
1600 auto check_empty_flips = [](
const Rect&
a,
const Rect&
b,
1601 const std::string& label) {
1602 ASSERT_FALSE(
a.IsEmpty());
1606 EXPECT_FALSE(
a.Intersection(
flip_lr(
b)).has_value()) << label;
1607 EXPECT_FALSE(
a.Intersection(
flip_tb(
b)).has_value()) << label;
1608 EXPECT_FALSE(
a.Intersection(
flip_lrtb(
b)).has_value()) << label;
1611 EXPECT_FALSE(
flip_lr(
a).Intersection(
b).has_value()) << label;
1612 EXPECT_FALSE(
flip_tb(
a).Intersection(
b).has_value()) << label;
1613 EXPECT_FALSE(
flip_lrtb(
a).Intersection(
b).has_value()) << label;
1621 auto test_non_empty = [&check_nans, &check_empty_flips](
1623 ASSERT_FALSE(
a.IsEmpty()) <<
a;
1626 std::stringstream
stream;
1628 auto label =
stream.str();
1632 EXPECT_EQ(
a.Intersection(
b),
result) << label;
1633 EXPECT_EQ(
b.Intersection(
a),
result) << label;
1634 check_empty_flips(
a,
b, label);
1635 check_nans(
a,
b, label);
1640 ASSERT_FALSE(
a.IsEmpty()) <<
a;
1643 std::stringstream
stream;
1645 auto label =
stream.str();
1647 EXPECT_FALSE(
a.Intersection(
b).has_value()) << label;
1648 EXPECT_FALSE(
b.Intersection(
a).has_value()) << label;
1649 check_empty_flips(
a,
b, label);
1650 check_nans(
a,
b, label);
1672 test_non_empty(
a,
b, expected);
1686 test_non_empty(
a,
b,
b);
1697TEST(RectTest, OptRectIntersection) {
1729 ASSERT_EQ(
a.Intersection(
b),
i);
1752 auto check_empty_flips = [](
const IRect&
a,
const IRect&
b,
1753 const std::string& label) {
1754 ASSERT_FALSE(
a.IsEmpty());
1758 EXPECT_FALSE(
a.Intersection(
flip_lr(
b)).has_value()) << label;
1759 EXPECT_FALSE(
a.Intersection(
flip_tb(
b)).has_value()) << label;
1760 EXPECT_FALSE(
a.Intersection(
flip_lrtb(
b)).has_value()) << label;
1763 EXPECT_FALSE(
flip_lr(
a).Intersection(
b).has_value()) << label;
1764 EXPECT_FALSE(
flip_tb(
a).Intersection(
b).has_value()) << label;
1765 EXPECT_FALSE(
flip_lrtb(
a).Intersection(
b).has_value()) << label;
1773 auto test_non_empty = [&check_empty_flips](
const IRect&
a,
const IRect&
b,
1775 ASSERT_FALSE(
a.IsEmpty()) <<
a;
1778 std::stringstream
stream;
1780 auto label =
stream.str();
1784 EXPECT_EQ(
a.Intersection(
b),
result) << label;
1785 EXPECT_EQ(
b.Intersection(
a),
result) << label;
1786 check_empty_flips(
a,
b, label);
1790 ASSERT_FALSE(
a.IsEmpty()) <<
a;
1793 std::stringstream
stream;
1795 auto label =
stream.str();
1797 EXPECT_FALSE(
a.Intersection(
b).has_value()) << label;
1798 EXPECT_FALSE(
b.Intersection(
a).has_value()) << label;
1799 check_empty_flips(
a,
b, label);
1821 test_non_empty(
a,
b, expected);
1835 test_non_empty(
a,
b,
b);
1846TEST(RectTest, OptIRectIntersection) {
1880 ASSERT_EQ(
a.Intersection(
b),
i);
1902TEST(RectTest, RectIntersectsWithRect) {
1903 auto check_nans = [](
const Rect&
a,
const Rect&
b,
const std::string& label) {
1904 ASSERT_TRUE(
a.IsFinite()) << label;
1905 ASSERT_TRUE(
b.IsFinite()) << label;
1907 for (
int i = 1;
i < 16;
i++) {
1909 EXPECT_FALSE(
swap_nan(
a,
i).IntersectsWithRect(
b))
1910 << label <<
", index = " <<
i;
1912 EXPECT_FALSE(
a.IntersectsWithRect(
swap_nan(
b,
i)))
1913 << label <<
", index = " <<
i;
1915 for (
int j = 1; j < 16; j++) {
1917 << label <<
", indices = " <<
i <<
", " << j;
1922 auto check_empty_flips = [](
const Rect&
a,
const Rect&
b,
1923 const std::string& label) {
1924 ASSERT_FALSE(
a.IsEmpty());
1928 EXPECT_FALSE(
a.IntersectsWithRect(
flip_lr(
b))) << label;
1929 EXPECT_FALSE(
a.IntersectsWithRect(
flip_tb(
b))) << label;
1930 EXPECT_FALSE(
a.IntersectsWithRect(
flip_lrtb(
b))) << label;
1933 EXPECT_FALSE(
flip_lr(
a).IntersectsWithRect(
b)) << label;
1934 EXPECT_FALSE(
flip_tb(
a).IntersectsWithRect(
b)) << label;
1935 EXPECT_FALSE(
flip_lrtb(
a).IntersectsWithRect(
b)) << label;
1943 auto test_non_empty = [&check_nans, &check_empty_flips](
const Rect&
a,
1945 ASSERT_FALSE(
a.IsEmpty()) <<
a;
1948 std::stringstream
stream;
1950 auto label =
stream.str();
1954 check_empty_flips(
a,
b, label);
1955 check_nans(
a,
b, label);
1960 ASSERT_FALSE(
a.IsEmpty()) <<
a;
1963 std::stringstream
stream;
1965 auto label =
stream.str();
1967 EXPECT_FALSE(
a.IntersectsWithRect(
b)) << label;
1968 EXPECT_FALSE(
b.IntersectsWithRect(
a)) << label;
1969 check_empty_flips(
a,
b, label);
1970 check_nans(
a,
b, label);
1991 test_non_empty(
a,
b);
2005 test_non_empty(
a,
b);
2012 test_non_empty(
a,
b);
2016TEST(RectTest, IRectIntersectsWithRect) {
2017 auto check_empty_flips = [](
const IRect&
a,
const IRect&
b,
2018 const std::string& label) {
2019 ASSERT_FALSE(
a.IsEmpty());
2023 EXPECT_FALSE(
a.IntersectsWithRect(
flip_lr(
b))) << label;
2024 EXPECT_FALSE(
a.IntersectsWithRect(
flip_tb(
b))) << label;
2025 EXPECT_FALSE(
a.IntersectsWithRect(
flip_lrtb(
b))) << label;
2028 EXPECT_FALSE(
flip_lr(
a).IntersectsWithRect(
b)) << label;
2029 EXPECT_FALSE(
flip_tb(
a).IntersectsWithRect(
b)) << label;
2030 EXPECT_FALSE(
flip_lrtb(
a).IntersectsWithRect(
b)) << label;
2038 auto test_non_empty = [&check_empty_flips](
const IRect&
a,
const IRect&
b) {
2039 ASSERT_FALSE(
a.IsEmpty()) <<
a;
2042 std::stringstream
stream;
2044 auto label =
stream.str();
2048 check_empty_flips(
a,
b, label);
2052 ASSERT_FALSE(
a.IsEmpty()) <<
a;
2055 std::stringstream
stream;
2057 auto label =
stream.str();
2059 EXPECT_FALSE(
a.IntersectsWithRect(
b)) << label;
2060 EXPECT_FALSE(
b.IntersectsWithRect(
a)) << label;
2061 check_empty_flips(
a,
b, label);
2082 test_non_empty(
a,
b);
2096 test_non_empty(
a,
b);
2103 test_non_empty(
a,
b);
2109 const std::string& label) {
2110 ASSERT_TRUE(
rect.IsFinite()) << label;
2111 ASSERT_TRUE(point.IsFinite()) << label;
2113 for (
int i = 1;
i < 16;
i++) {
2115 << label <<
", index = " <<
i;
2116 for (
int j = 1; j < 4; j++) {
2118 << label <<
", indices = " <<
i <<
", " << j;
2123 auto check_empty_flips = [](
const Rect&
rect,
const Point& point,
2124 const std::string& label) {
2125 ASSERT_FALSE(
rect.IsEmpty());
2132 auto test_inside = [&check_nans, &check_empty_flips](
const Rect&
rect,
2133 const Point& point) {
2134 ASSERT_FALSE(
rect.IsEmpty()) <<
rect;
2136 std::stringstream
stream;
2138 auto label =
stream.str();
2141 check_empty_flips(
rect, point, label);
2142 check_nans(
rect, point, label);
2145 auto test_outside = [&check_nans, &check_empty_flips](
const Rect&
rect,
2146 const Point& point) {
2147 ASSERT_FALSE(
rect.IsEmpty()) <<
rect;
2149 std::stringstream
stream;
2151 auto label =
stream.str();
2153 EXPECT_FALSE(
rect.Contains(point)) << label;
2154 check_empty_flips(
rect, point, label);
2155 check_nans(
rect, point, label);
2161 auto p =
Point(100, 100);
2168 auto p =
Point(200, 200);
2180 auto p =
Point(199, 199);
2187 auto p =
Point(199, 199);
2193TEST(RectTest, IRectContainsIPoint) {
2195 const std::string& label) {
2196 ASSERT_FALSE(
rect.IsEmpty());
2203 auto test_inside = [&check_empty_flips](
const IRect&
rect,
2205 ASSERT_FALSE(
rect.IsEmpty()) <<
rect;
2207 std::stringstream
stream;
2209 auto label =
stream.str();
2212 check_empty_flips(
rect, point, label);
2215 auto test_outside = [&check_empty_flips](
const IRect&
rect,
2217 ASSERT_FALSE(
rect.IsEmpty()) <<
rect;
2219 std::stringstream
stream;
2221 auto label =
stream.str();
2223 EXPECT_FALSE(
rect.Contains(point)) << label;
2224 check_empty_flips(
rect, point, label);
2262TEST(RectTest, RectContainsInclusivePoint) {
2264 const std::string& label) {
2265 ASSERT_TRUE(
rect.IsFinite()) << label;
2266 ASSERT_TRUE(point.IsFinite()) << label;
2268 for (
int i = 1;
i < 16;
i++) {
2270 << label <<
", index = " <<
i;
2271 for (
int j = 1; j < 4; j++) {
2273 << label <<
", indices = " <<
i <<
", " << j;
2278 auto check_empty_flips = [](
const Rect&
rect,
const Point& point,
2279 const std::string& label) {
2280 ASSERT_FALSE(
rect.IsEmpty());
2282 EXPECT_FALSE(
flip_lr(
rect).ContainsInclusive(point)) << label;
2283 EXPECT_FALSE(
flip_tb(
rect).ContainsInclusive(point)) << label;
2284 EXPECT_FALSE(
flip_lrtb(
rect).ContainsInclusive(point)) << label;
2287 auto test_inside = [&check_nans, &check_empty_flips](
const Rect&
rect,
2288 const Point& point) {
2289 ASSERT_FALSE(
rect.IsEmpty()) <<
rect;
2291 std::stringstream
stream;
2293 auto label =
stream.str();
2296 check_empty_flips(
rect, point, label);
2297 check_nans(
rect, point, label);
2300 auto test_outside = [&check_nans, &check_empty_flips](
const Rect&
rect,
2301 const Point& point) {
2302 ASSERT_FALSE(
rect.IsEmpty()) <<
rect;
2304 std::stringstream
stream;
2306 auto label =
stream.str();
2308 EXPECT_FALSE(
rect.ContainsInclusive(point)) << label;
2309 check_empty_flips(
rect, point, label);
2310 check_nans(
rect, point, label);
2316 auto p =
Point(100, 100);
2323 auto p =
Point(200, 200);
2342 auto p =
Point(199, 199);
2349 auto p =
Point(199, 199);
2355TEST(RectTest, IRectContainsInclusiveIPoint) {
2357 const std::string& label) {
2358 ASSERT_FALSE(
rect.IsEmpty());
2360 EXPECT_FALSE(
flip_lr(
rect).ContainsInclusive(point)) << label;
2361 EXPECT_FALSE(
flip_tb(
rect).ContainsInclusive(point)) << label;
2362 EXPECT_FALSE(
flip_lrtb(
rect).ContainsInclusive(point)) << label;
2365 auto test_inside = [&check_empty_flips](
const IRect&
rect,
2367 ASSERT_FALSE(
rect.IsEmpty()) <<
rect;
2369 std::stringstream
stream;
2371 auto label =
stream.str();
2374 check_empty_flips(
rect, point, label);
2377 auto test_outside = [&check_empty_flips](
const IRect&
rect,
2379 ASSERT_FALSE(
rect.IsEmpty()) <<
rect;
2381 std::stringstream
stream;
2383 auto label =
stream.str();
2385 EXPECT_FALSE(
rect.ContainsInclusive(point)) << label;
2386 check_empty_flips(
rect, point, label);
2432 auto check_nans = [](
const Rect&
a,
const Rect&
b,
const std::string& label) {
2433 ASSERT_TRUE(
a.IsFinite()) << label;
2434 ASSERT_TRUE(
b.IsFinite()) << label;
2435 ASSERT_FALSE(
a.IsEmpty());
2437 for (
int i = 1;
i < 16;
i++) {
2443 for (
int j = 1; j < 16; j++) {
2445 << label <<
", indices = " <<
i <<
", " << j;
2450 auto check_empty_flips = [](
const Rect&
a,
const Rect&
b,
2451 const std::string& label) {
2452 ASSERT_FALSE(
a.IsEmpty());
2454 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2472 auto test_inside = [&check_nans, &check_empty_flips](
const Rect&
a,
2474 ASSERT_FALSE(
a.IsEmpty()) <<
a;
2476 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2478 std::stringstream
stream;
2480 auto label =
stream.str();
2483 check_empty_flips(
a,
b, label);
2484 check_nans(
a,
b, label);
2487 auto test_not_inside = [&check_nans, &check_empty_flips](
const Rect&
a,
2489 ASSERT_FALSE(
a.IsEmpty()) <<
a;
2492 ASSERT_FALSE(
b.IsEmpty()) <<
b;
2494 std::stringstream
stream;
2496 auto label =
stream.str();
2498 EXPECT_FALSE(
a.Contains(
b)) << label;
2499 check_empty_flips(
a,
b, label);
2500 check_nans(
a,
b, label);
2524 test_not_inside(
a,
b);
2530 test_not_inside(
a,
b);
2536 test_not_inside(
a,
b);
2546TEST(RectTest, IRectContainsIRect) {
2547 auto check_empty_flips = [](
const IRect&
a,
const IRect&
b,
2548 const std::string& label) {
2549 ASSERT_FALSE(
a.IsEmpty());
2551 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2569 auto test_inside = [&check_empty_flips](
const IRect&
a,
const IRect&
b) {
2570 ASSERT_FALSE(
a.IsEmpty()) <<
a;
2572 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2574 std::stringstream
stream;
2576 auto label =
stream.str();
2579 check_empty_flips(
a,
b, label);
2582 auto test_not_inside = [&check_empty_flips](
const IRect&
a,
const IRect&
b) {
2583 ASSERT_FALSE(
a.IsEmpty()) <<
a;
2586 ASSERT_FALSE(
b.IsEmpty()) <<
b;
2588 std::stringstream
stream;
2590 auto label =
stream.str();
2592 EXPECT_FALSE(
a.Contains(
b)) << label;
2593 check_empty_flips(
a,
b, label);
2617 test_not_inside(
a,
b);
2623 test_not_inside(
a,
b);
2629 test_not_inside(
a,
b);
2642 auto check_nans = [&cull_rect](
const Rect& diff_rect,
2643 const std::string& label) {
2647 for (
int i = 1;
i < 16;
i++) {
2649 EXPECT_FALSE(
swap_nan(cull_rect,
i).Cutout(diff_rect).has_value())
2650 << label <<
", index " <<
i;
2651 EXPECT_EQ(
swap_nan(cull_rect,
i).CutoutOrEmpty(diff_rect),
Rect())
2652 << label <<
", index " <<
i;
2656 << label <<
", index " <<
i;
2657 EXPECT_EQ(cull_rect.CutoutOrEmpty(
swap_nan(diff_rect,
i)), cull_rect)
2658 << label <<
", index " <<
i;
2660 for (
int j = 1; j < 16; j++) {
2664 << label <<
", indices " <<
i <<
", " << j;
2667 << label <<
", indices " <<
i <<
", " << j;
2672 auto check_empty_flips = [&cull_rect](
const Rect& diff_rect,
2673 const std::string& label) {
2674 EXPECT_FALSE(cull_rect.IsEmpty()) << label;
2675 EXPECT_FALSE(diff_rect.IsEmpty()) << label;
2680 EXPECT_EQ(cull_rect.Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2682 EXPECT_EQ(cull_rect.Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2684 EXPECT_EQ(cull_rect.Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2688 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2689 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2690 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2691 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2692 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2693 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2697 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
2701 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
2711 auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2712 const Rect& diff_rect,
const std::string& label) {
2713 EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2714 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2715 check_empty_flips(diff_rect, label);
2716 check_nans(diff_rect, label);
2719 auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2720 const Rect& diff_rect,
const Rect& result_rect,
2721 const std::string& label) {
2723 EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2724 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2725 check_empty_flips(diff_rect, label);
2726 check_nans(diff_rect, label);
2729 auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2730 const Rect& diff_rect,
const std::string& label) {
2731 EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2732 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect),
Rect()) << label;
2733 check_empty_flips(diff_rect, label);
2734 check_nans(diff_rect, label);
2738 non_reducing(
Rect::MakeLTRB(10, 10, 20, 20),
"outside UL corner");
2740 non_reducing(
Rect::MakeLTRB(40, 10, 50, 20),
"outside UR corner");
2742 non_reducing(
Rect::MakeLTRB(40, 40, 50, 50),
"outside LR corner");
2744 non_reducing(
Rect::MakeLTRB(10, 40, 20, 50),
"outside LR corner");
2748 non_reducing(
Rect::MakeLTRB(15, 15, 25, 25),
"covering UL corner");
2749 non_reducing(
Rect::MakeLTRB(35, 15, 45, 25),
"covering UR corner");
2750 non_reducing(
Rect::MakeLTRB(35, 35, 45, 45),
"covering LR corner");
2751 non_reducing(
Rect::MakeLTRB(15, 35, 25, 45),
"covering LL corner");
2754 non_reducing(
Rect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
2755 non_reducing(
Rect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
2756 non_reducing(
Rect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
2757 non_reducing(
Rect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
2758 non_reducing(
Rect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
2759 non_reducing(
Rect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
2760 non_reducing(
Rect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
2761 non_reducing(
Rect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
2764 non_reducing(
Rect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
2765 non_reducing(
Rect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
2776 "Slice off bottom");
2782 non_reducing(
Rect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
2785 emptying(cull_rect,
"Perfectly covering");
2794 auto check_empty_flips = [&cull_rect](
const IRect& diff_rect,
2795 const std::string& label) {
2796 EXPECT_FALSE(diff_rect.
IsEmpty());
2797 EXPECT_FALSE(cull_rect.
IsEmpty());
2802 EXPECT_EQ(cull_rect.
Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2804 EXPECT_EQ(cull_rect.
Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2806 EXPECT_EQ(cull_rect.
Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2810 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2811 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2812 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2813 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2814 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2815 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2819 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
2823 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
2833 auto non_reducing = [&cull_rect, &check_empty_flips](
2834 const IRect& diff_rect,
const std::string& label) {
2835 EXPECT_EQ(cull_rect.
Cutout(diff_rect), cull_rect) << label;
2836 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), cull_rect) << label;
2837 check_empty_flips(diff_rect, label);
2840 auto reducing = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
2841 const IRect& result_rect,
2842 const std::string& label) {
2844 EXPECT_EQ(cull_rect.
Cutout(diff_rect), result_rect) << label;
2845 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), result_rect) << label;
2846 check_empty_flips(diff_rect, label);
2849 auto emptying = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
2850 const std::string& label) {
2851 EXPECT_FALSE(cull_rect.
Cutout(diff_rect).has_value()) << label;
2853 check_empty_flips(diff_rect, label);
2873 non_reducing(
IRect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
2874 non_reducing(
IRect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
2875 non_reducing(
IRect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
2876 non_reducing(
IRect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
2877 non_reducing(
IRect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
2878 non_reducing(
IRect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
2879 non_reducing(
IRect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
2880 non_reducing(
IRect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
2883 non_reducing(
IRect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
2884 non_reducing(
IRect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
2895 "Slice off bottom");
2901 non_reducing(
IRect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
2904 emptying(cull_rect,
"Perfectly covering");
2913 auto points = r.GetPoints();
2922 auto points = r.GetPoints();
2923 EXPECT_EQ(
points[0],
Point(std::numeric_limits<float>::lowest(),
2924 std::numeric_limits<float>::lowest()));
2926 std::numeric_limits<float>::lowest()));
2927 EXPECT_EQ(
points[2],
Point(std::numeric_limits<float>::lowest(),
2941TEST(RectTest, RectGetTransformedPoints) {
2950TEST(RectTest, RectMakePointBounds) {
2952 std::vector<Point>
points{{1, 5}, {4, -1}, {0, 6}};
2956 if (r.has_value()) {
2961 std::vector<Point>
points;
2963 EXPECT_FALSE(r.has_value());
2970 auto actual = r.GetPositive();
2975 auto actual = r.GetPositive();
2984 EXPECT_EQ(r.GetLeft(), 1);
2985 EXPECT_EQ(r.GetTop(), 2);
2986 EXPECT_EQ(r.GetRight(), 3);
2987 EXPECT_EQ(r.GetBottom(), 4);
2998 auto actual = r.Project(r);
3067TEST(RectTest, TransformAndClipBounds) {
3072 2.0f, 0.0f, 0.0f, 0.0f,
3073 0.0f, 4.0f, 0.0f, 0.0f,
3074 0.0f, 0.0f, 1.0f, 0.0f,
3075 0.0f, 0.0f, 0.0f, 8.0f
3080 EXPECT_EQ(
matrix.TransformHomogenous(
src.GetLeftTop()),
3081 Vector3(200.0f, 400.0f, 8.0f));
3082 EXPECT_EQ(
matrix.TransformHomogenous(
src.GetRightTop()),
3083 Vector3(400.0f, 400.0f, 8.0f));
3084 EXPECT_EQ(
matrix.TransformHomogenous(
src.GetLeftBottom()),
3085 Vector3(200.0f, 800.0f, 8.0f));
3086 EXPECT_EQ(
matrix.TransformHomogenous(
src.GetRightBottom()),
3087 Vector3(400.0f, 800.0f, 8.0f));
3090 EXPECT_FALSE(
src.TransformAndClipBounds(
matrix).IsEmpty());
3091 EXPECT_EQ(
src.TransformAndClipBounds(
matrix), expect);
3098 2.0f, 0.0f, 0.0f, -0.01f,
3099 0.0f, 2.0f, 0.0f, -0.006f,
3100 0.0f, 0.0f, 1.0f, 0.0f,
3101 0.0f, 0.0f, 0.0f, 3.0f
3107 Vector3(200.0f, 200.0f, 1.4f));
3109 Vector3(400.0f, 200.0f, 0.4f));
3111 Vector3(200.0f, 400.0f, 0.8f));
3113 Vector3(400.0f, 400.0f, -0.2f));
3116 EXPECT_FALSE(
src.TransformAndClipBounds(
matrix).IsEmpty());
3124 2.0f, 0.0f, 0.0f, -.015f,
3125 0.0f, 2.0f, 0.0f, -.006f,
3126 0.0f, 0.0f, 1.0f, 0.0f,
3127 0.0f, 0.0f, 0.0f, 3.0f
3133 Vector3(200.0f, 200.0f, 0.9f));
3135 Vector3(400.0f, 200.0f, -0.6f));
3137 Vector3(200.0f, 400.0f, 0.3f));
3139 Vector3(400.0f, 400.0f, -1.2f));
3142 EXPECT_FALSE(
src.TransformAndClipBounds(
matrix).IsEmpty());
3150 2.0f, 0.0f, 0.0f, -.02f,
3151 0.0f, 2.0f, 0.0f, -.006f,
3152 0.0f, 0.0f, 1.0f, 0.0f,
3153 0.0f, 0.0f, 0.0f, 3.0f
3159 Vector3(200.0f, 200.0f, 0.4f));
3161 Vector3(400.0f, 200.0f, -1.6f));
3163 Vector3(200.0f, 400.0f, -0.2f));
3165 Vector3(400.0f, 400.0f, -2.2f));
3168 EXPECT_FALSE(
src.TransformAndClipBounds(
matrix).IsEmpty());
3176 2.0f, 0.0f, 0.0f, -.025f,
3177 0.0f, 2.0f, 0.0f, -.006f,
3178 0.0f, 0.0f, 1.0f, 0.0f,
3179 0.0f, 0.0f, 0.0f, 3.0f
3185 Vector3(200.0f, 200.0f, -0.1f));
3187 Vector3(400.0f, 200.0f, -2.6f));
3189 Vector3(200.0f, 400.0f, -0.7f));
3191 Vector3(400.0f, 400.0f, -3.2f));
static void test_empty(skiatest::Reporter *reporter)
static const int points[]
static void Union(SkRegion *rgn, const SkIRect &rect)
static void test1(skiatest::Reporter *reporter, SkWriter32 *writer)
#define FML_DCHECK(condition)
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)
#define EXPECT_VECTOR3_NEAR(a, b)
#define EXPECT_RECT_NEAR(a, b)
#define EXPECT_POINT_NEAR(a, b)
static float max(float r, float g, float b)
static float min(float r, float g, float b)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
sk_sp< SkBlender > blender SkRect rect
bool Contains(const Container &container, const Value &value)
TEST(AiksCanvasTest, EmptyCullRect)
static constexpr R flip_tb(R rect)
static constexpr Rect swap_nan(const Rect &rect, int index)
static constexpr R flip_lrtb(R rect)
static constexpr R flip_lr(R rect)
constexpr float kEhCloseEnough
std::array< Point, 4 > Quad
bool EMSCRIPTEN_KEEPALIVE IsEmpty(const SkPath &path)
static constexpr Matrix MakeTranslation(const Vector3 &t)
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
static constexpr Matrix MakeScale(const Vector3 &s)
constexpr auto GetBottom() const
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
constexpr auto GetTop() const
constexpr std::optional< TRect > Intersection(const TRect &o) const
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
constexpr std::optional< TRect< T > > Cutout(const TRect &o) const
Returns the new boundary rectangle that would result from this rectangle being cut out by the specifi...
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
constexpr TRect Union(const TRect &o) const
constexpr auto GetLeft() const
constexpr TRect CutoutOrEmpty(const TRect &o) const
Round(const TRect< U > &r)
RoundOut(const TRect< U > &r)
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
static constexpr TRect MakeOriginSize(const TPoint< Type > &origin, const TSize< Type > &size)
constexpr auto GetRight() const
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
static constexpr TRect MakeSize(const TSize< U > &size)
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
static constexpr std::optional< TRect > MakePointBounds(const U &value)
static constexpr TRect MakeMaximum()
constexpr std::array< T, 4 > GetXYWH() const
Get the x, y coordinates of the origin and the width and height of the rectangle in an array.
constexpr TPoint< Type > GetOrigin() const
Returns the upper left corner of the rectangle as specified by the left/top or x/y values when it was...
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
#define EXPECT_TRUE(handle)