5 #include "gtest/gtest.h"
14 TEST(RectTest, RectEmptyDeclaration) {
17 EXPECT_EQ(rect.
GetLeft(), 0.0f);
18 EXPECT_EQ(rect.
GetTop(), 0.0f);
21 EXPECT_EQ(rect.
GetX(), 0.0f);
22 EXPECT_EQ(rect.
GetY(), 0.0f);
29 TEST(RectTest, IRectEmptyDeclaration) {
33 EXPECT_EQ(rect.
GetTop(), 0);
36 EXPECT_EQ(rect.
GetX(), 0);
37 EXPECT_EQ(rect.
GetY(), 0);
44 TEST(RectTest, RectDefaultConstructor) {
47 EXPECT_EQ(rect.
GetLeft(), 0.0f);
48 EXPECT_EQ(rect.
GetTop(), 0.0f);
51 EXPECT_EQ(rect.
GetX(), 0.0f);
52 EXPECT_EQ(rect.
GetY(), 0.0f);
59 TEST(RectTest, IRectDefaultConstructor) {
63 EXPECT_EQ(rect.
GetTop(), 0);
66 EXPECT_EQ(rect.
GetX(), 0);
67 EXPECT_EQ(rect.
GetY(), 0);
73 TEST(RectTest, RectSimpleLTRB) {
77 EXPECT_EQ(rect.
GetLeft(), 5.125f);
78 EXPECT_EQ(rect.
GetTop(), 10.25f);
81 EXPECT_EQ(rect.
GetX(), 5.125f);
82 EXPECT_EQ(rect.
GetY(), 10.25f);
89 TEST(RectTest, IRectSimpleLTRB) {
93 EXPECT_EQ(rect.
GetTop(), 10);
96 EXPECT_EQ(rect.
GetX(), 5);
97 EXPECT_EQ(rect.
GetY(), 10);
103 TEST(RectTest, RectSimpleXYWH) {
107 EXPECT_EQ(rect.
GetLeft(), 5.125f);
108 EXPECT_EQ(rect.
GetTop(), 10.25f);
109 EXPECT_EQ(rect.
GetRight(), 20.625f);
111 EXPECT_EQ(rect.
GetX(), 5.125f);
112 EXPECT_EQ(rect.
GetY(), 10.25f);
119 TEST(RectTest, IRectSimpleXYWH) {
123 EXPECT_EQ(rect.
GetTop(), 10);
126 EXPECT_EQ(rect.
GetX(), 5);
127 EXPECT_EQ(rect.
GetY(), 10);
133 TEST(RectTest, RectOverflowXYWH) {
134 auto min = std::numeric_limits<Scalar>::lowest();
135 auto max = std::numeric_limits<Scalar>::max();
136 auto inf = std::numeric_limits<Scalar>::infinity();
154 EXPECT_EQ(rect.
GetLeft(), 5.0f);
155 EXPECT_EQ(rect.
GetTop(), 10.0f);
158 EXPECT_EQ(rect.
GetX(), 5.0f);
159 EXPECT_EQ(rect.
GetY(), 10.0f);
169 EXPECT_EQ(rect.
GetLeft(), max);
170 EXPECT_EQ(rect.
GetTop(), 10.0f);
173 EXPECT_EQ(rect.
GetX(), max);
174 EXPECT_EQ(rect.
GetY(), 10.0f);
184 EXPECT_EQ(rect.
GetLeft(), 5.0f);
185 EXPECT_EQ(rect.
GetTop(), 10.0f);
188 EXPECT_EQ(rect.
GetX(), 5.0f);
189 EXPECT_EQ(rect.
GetY(), 10.0f);
199 EXPECT_EQ(rect.
GetLeft(), 5.0f);
200 EXPECT_EQ(rect.
GetTop(), max);
203 EXPECT_EQ(rect.
GetX(), 5.0f);
204 EXPECT_EQ(rect.
GetY(), max);
214 EXPECT_EQ(rect.
GetLeft(), 5.0f);
215 EXPECT_EQ(rect.
GetTop(), 10.0f);
218 EXPECT_EQ(rect.
GetX(), 5.0f);
219 EXPECT_EQ(rect.
GetY(), 10.0f);
229 EXPECT_EQ(rect.
GetLeft(), min);
230 EXPECT_EQ(rect.
GetTop(), 10.0f);
233 EXPECT_EQ(rect.
GetX(), min);
234 EXPECT_EQ(rect.
GetY(), 10.0f);
244 EXPECT_EQ(rect.
GetLeft(), 5.0f);
245 EXPECT_EQ(rect.
GetTop(), 10.0f);
248 EXPECT_EQ(rect.
GetX(), 5.0f);
249 EXPECT_EQ(rect.
GetY(), 10.0f);
259 EXPECT_EQ(rect.
GetLeft(), 5.0f);
260 EXPECT_EQ(rect.
GetTop(), min);
263 EXPECT_EQ(rect.
GetX(), 5.0f);
264 EXPECT_EQ(rect.
GetY(), min);
272 TEST(RectTest, IRectOverflowXYWH) {
273 auto min = std::numeric_limits<int64_t>::min();
274 auto max = std::numeric_limits<int64_t>::max();
285 EXPECT_EQ(rect.
GetLeft(), max - 5);
286 EXPECT_EQ(rect.
GetTop(), 10);
289 EXPECT_EQ(rect.
GetX(), max - 5);
290 EXPECT_EQ(rect.
GetY(), 10);
299 EXPECT_EQ(rect.
GetLeft(), min + 5);
300 EXPECT_EQ(rect.
GetTop(), 10);
303 EXPECT_EQ(rect.
GetX(), min + 5);
304 EXPECT_EQ(rect.
GetY(), 10);
314 EXPECT_EQ(rect.
GetTop(), max - 10);
317 EXPECT_EQ(rect.
GetX(), 5);
318 EXPECT_EQ(rect.
GetY(), max - 10);
328 EXPECT_EQ(rect.
GetTop(), min + 10);
331 EXPECT_EQ(rect.
GetX(), 5);
332 EXPECT_EQ(rect.
GetY(), min + 10);
339 TEST(RectTest, RectOverflowLTRB) {
340 auto min = std::numeric_limits<Scalar>::lowest();
341 auto max = std::numeric_limits<Scalar>::max();
342 auto inf = std::numeric_limits<Scalar>::infinity();
360 EXPECT_EQ(rect.
GetLeft(), -5.0f);
361 EXPECT_EQ(rect.
GetTop(), 10.0f);
364 EXPECT_EQ(rect.
GetX(), -5.0f);
365 EXPECT_EQ(rect.
GetY(), 10.0f);
375 EXPECT_EQ(rect.
GetLeft(), min + 5.0f);
376 EXPECT_EQ(rect.
GetTop(), 10.0f);
377 EXPECT_EQ(rect.
GetRight(), max - 5.0f);
379 EXPECT_EQ(rect.
GetX(), min + 5.0f);
380 EXPECT_EQ(rect.
GetY(), 10.0f);
390 EXPECT_EQ(rect.
GetLeft(), 5.0f);
391 EXPECT_EQ(rect.
GetTop(), -10.0f);
394 EXPECT_EQ(rect.
GetX(), 5.0f);
395 EXPECT_EQ(rect.
GetY(), -10.0f);
405 EXPECT_EQ(rect.
GetLeft(), 5.0f);
406 EXPECT_EQ(rect.
GetTop(), min + 10.0f);
408 EXPECT_EQ(rect.
GetBottom(), max - 15.0f);
409 EXPECT_EQ(rect.
GetX(), 5.0f);
410 EXPECT_EQ(rect.
GetY(), min + 10.0f);
420 EXPECT_EQ(rect.
GetLeft(), 5.0f);
421 EXPECT_EQ(rect.
GetTop(), 10.0f);
424 EXPECT_EQ(rect.
GetX(), 5.0f);
425 EXPECT_EQ(rect.
GetY(), 10.0f);
435 EXPECT_EQ(rect.
GetLeft(), max - 5.0f);
436 EXPECT_EQ(rect.
GetTop(), 10.0f);
437 EXPECT_EQ(rect.
GetRight(), min + 10.0f);
439 EXPECT_EQ(rect.
GetX(), max - 5.0f);
440 EXPECT_EQ(rect.
GetY(), 10.0f);
450 EXPECT_EQ(rect.
GetLeft(), 5.0f);
451 EXPECT_EQ(rect.
GetTop(), 10.0f);
454 EXPECT_EQ(rect.
GetX(), 5.0f);
455 EXPECT_EQ(rect.
GetY(), 10.0f);
465 EXPECT_EQ(rect.
GetLeft(), 5.0f);
466 EXPECT_EQ(rect.
GetTop(), max - 5.0f);
468 EXPECT_EQ(rect.
GetBottom(), min + 10.0f);
469 EXPECT_EQ(rect.
GetX(), 5.0f);
470 EXPECT_EQ(rect.
GetY(), max - 5.0f);
478 TEST(RectTest, IRectOverflowLTRB) {
479 auto min = std::numeric_limits<int64_t>::min();
480 auto max = std::numeric_limits<int64_t>::max();
491 EXPECT_EQ(rect.
GetLeft(), -10);
492 EXPECT_EQ(rect.
GetTop(), 10);
493 EXPECT_EQ(rect.
GetRight(), max - 5);
495 EXPECT_EQ(rect.
GetX(), -10);
496 EXPECT_EQ(rect.
GetY(), 10);
506 EXPECT_EQ(rect.
GetTop(), 10);
507 EXPECT_EQ(rect.
GetRight(), min + 5);
509 EXPECT_EQ(rect.
GetX(), 10);
510 EXPECT_EQ(rect.
GetY(), 10);
520 EXPECT_EQ(rect.
GetTop(), -10);
523 EXPECT_EQ(rect.
GetX(), 5);
524 EXPECT_EQ(rect.
GetY(), -10);
534 EXPECT_EQ(rect.
GetTop(), 10);
537 EXPECT_EQ(rect.
GetX(), 5);
538 EXPECT_EQ(rect.
GetY(), 10);
564 EXPECT_EQ(r, expected);
571 EXPECT_EQ(r, expected);
575 TEST(RectTest, RectMakeMaximum) {
577 auto inf = std::numeric_limits<Scalar>::infinity();
578 auto min = std::numeric_limits<Scalar>::lowest();
579 auto max = std::numeric_limits<Scalar>::max();
581 EXPECT_EQ(rect.
GetLeft(), min);
582 EXPECT_EQ(rect.
GetTop(), min);
585 EXPECT_EQ(rect.
GetX(), min);
586 EXPECT_EQ(rect.
GetY(), min);
593 TEST(RectTest, IRectMakeMaximum) {
595 auto min = std::numeric_limits<int64_t>::min();
596 auto max = std::numeric_limits<int64_t>::max();
598 EXPECT_EQ(rect.
GetLeft(), min);
599 EXPECT_EQ(rect.
GetTop(), min);
602 EXPECT_EQ(rect.
GetX(), min);
603 EXPECT_EQ(rect.
GetY(), min);
616 TEST(RectTest, IRectFromIRect) {
628 EXPECT_EQ(rect, copy);
629 EXPECT_EQ(copy.
GetLeft(), 5.125f);
630 EXPECT_EQ(copy.
GetTop(), 10.25f);
631 EXPECT_EQ(copy.
GetRight(), 20.625f);
633 EXPECT_EQ(copy.
GetX(), 5.125f);
634 EXPECT_EQ(copy.
GetY(), 10.25f);
645 EXPECT_EQ(rect, copy);
647 EXPECT_EQ(copy.
GetTop(), 10);
650 EXPECT_EQ(copy.
GetX(), 5);
651 EXPECT_EQ(copy.
GetY(), 10);
657 TEST(RectTest, RectOriginSizeXYWHGetters) {
662 EXPECT_EQ(r.
GetX(), 10);
663 EXPECT_EQ(r.
GetY(), 20);
666 auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
667 EXPECT_EQ(r.
GetXYWH(), expected_array);
674 EXPECT_EQ(r.
GetX(), 10);
675 EXPECT_EQ(r.
GetY(), 20);
678 auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
679 EXPECT_EQ(r.
GetXYWH(), expected_array);
683 TEST(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);
709 TEST(RectTest, RectRoundOutEmpty) {
717 TEST(RectTest, RectRoundOutSimple) {
725 TEST(RectTest, RectRoundOutToIRectHuge) {
726 auto test = [](
int corners) {
727 EXPECT_TRUE(corners >= 0 && corners <= 0xf);
729 int64_t il, it, ir, ib;
734 if ((corners & (1 << 0)) != 0) {
736 il = std::numeric_limits<int64_t>::min();
738 if ((corners & (1 << 1)) != 0) {
740 it = std::numeric_limits<int64_t>::min();
742 if ((corners & (1 << 2)) != 0) {
744 ir = std::numeric_limits<int64_t>::max();
746 if ((corners & (1 << 3)) != 0) {
748 ib = std::numeric_limits<int64_t>::max();
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++) {
764 TEST(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");
794 TEST(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");
824 TEST(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");
854 TEST(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");
892 << rect <<
" * " <<
scale;
894 << rect <<
" * " <<
scale;
896 << rect <<
" * " <<
scale;
898 << rect <<
" * " <<
scale;
903 rect.
GetY() * scale_y,
908 << rect <<
" * " << scale_x <<
", " << scale_y;
910 << rect <<
" * " << scale_x <<
", " << scale_y;
912 << rect <<
" * " << scale_x <<
", " << scale_y;
914 test1(rect, scale_x);
915 test1(rect, scale_y);
937 << rect <<
" * " <<
scale;
939 << rect <<
" * " <<
scale;
941 << rect <<
" * " <<
scale;
943 << rect <<
" * " <<
scale;
946 auto test2 = [&test1](
IRect rect, int64_t scale_x, int64_t scale_y) {
948 rect.
GetY() * 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;
959 test1(rect, scale_x);
960 test1(rect, scale_y);
989 TEST(RectTest, RectGetNormalizingTransform) {
995 EXPECT_EQ(r.GetNormalizingTransform(),
1004 auto m = r.GetNormalizingTransform();
1013 EXPECT_EQ(m *
Point(350, 600),
Point(0.5, 0.5));
1016 EXPECT_EQ(m *
Point(200, 300),
Point(-1, -1));
1017 EXPECT_EQ(m *
Point(500, 300),
Point(2, -1));
1019 EXPECT_EQ(m *
Point(200, 900),
Point(-1, 2));
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);
1077 TEST(RectTest, IRectGetNormalizingTransform) {
1083 EXPECT_EQ(r.GetNormalizingTransform(),
1092 auto m = r.GetNormalizingTransform();
1101 EXPECT_EQ(m *
Point(350, 600),
Point(0.5, 0.5));
1104 EXPECT_EQ(m *
Point(200, 300),
Point(-1, -1));
1105 EXPECT_EQ(m *
Point(500, 300),
Point(2, -1));
1107 EXPECT_EQ(m *
Point(200, 900),
Point(-1, 2));
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();
1168 TEST(RectTest, MakePointBoundsQuad) {
1176 EXPECT_TRUE(bounds.has_value());
1177 if (bounds.has_value()) {
1213 EXPECT_EQ(rect.Expand(10, 10),
Rect::MakeLTRB(90, 90, 210, 210));
1214 EXPECT_EQ(rect.Expand(10, -10),
Rect::MakeLTRB(90, 110, 210, 190));
1215 EXPECT_EQ(rect.Expand(-10, 10),
Rect::MakeLTRB(110, 90, 190, 210));
1216 EXPECT_EQ(rect.Expand(-10, -10),
Rect::MakeLTRB(110, 110, 190, 190));
1219 EXPECT_EQ(rect.Expand(10, 20, 30, 40),
Rect::MakeLTRB(90, 80, 230, 240));
1220 EXPECT_EQ(rect.Expand(-10, 20, 30, 40),
Rect::MakeLTRB(110, 80, 230, 240));
1221 EXPECT_EQ(rect.Expand(10, -20, 30, 40),
Rect::MakeLTRB(90, 120, 230, 240));
1222 EXPECT_EQ(rect.Expand(10, 20, -30, 40),
Rect::MakeLTRB(90, 80, 170, 240));
1223 EXPECT_EQ(rect.Expand(10, 20, 30, -40),
Rect::MakeLTRB(90, 80, 230, 160));
1249 EXPECT_EQ(rect.Expand(-10, -10),
IRect::MakeLTRB(110, 110, 190, 190));
1252 EXPECT_EQ(rect.Expand(10, 20, 30, 40),
IRect::MakeLTRB(90, 80, 230, 240));
1253 EXPECT_EQ(rect.Expand(-10, 20, 30, 40),
IRect::MakeLTRB(110, 80, 230, 240));
1254 EXPECT_EQ(rect.Expand(10, -20, 30, 40),
IRect::MakeLTRB(90, 120, 230, 240));
1255 EXPECT_EQ(rect.Expand(10, 20, -30, 40),
IRect::MakeLTRB(90, 80, 170, 240));
1256 EXPECT_EQ(rect.Expand(10, 20, 30, -40),
IRect::MakeLTRB(90, 80, 230, 160));
1271 TEST(RectTest, ContainsFloatingPoint) {
1273 Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
1275 EXPECT_TRUE(rect1.Contains(rect2));
1278 template <
typename R>
1280 return R::MakeLTRB(rect.GetRight(), rect.GetTop(),
1281 rect.GetLeft(), rect.GetBottom());
1284 template <
typename R>
1286 return R::MakeLTRB(rect.GetLeft(), rect.GetBottom(),
1287 rect.GetRight(), rect.GetTop());
1290 template <
typename R>
1296 Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1297 FML_DCHECK(index >= 0 && index <= 15);
1298 Scalar l = ((index & (1 << 0)) != 0) ? nan : rect.
GetLeft();
1299 Scalar t = ((index & (1 << 1)) != 0) ? nan : rect.
GetTop();
1306 Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1307 FML_DCHECK(index >= 0 && index <= 3);
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;
1319 for (
int i = 1; i < 16; i++) {
1321 EXPECT_EQ(
swap_nan(a, i).Union(
b),
b) << label <<
", index = " << 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) {
1343 EXPECT_EQ(
flip_lr(a).Union(
b),
b) << label;
1344 EXPECT_EQ(
flip_tb(a).Union(
b),
b) << label;
1353 auto test = [&check_nans, &check_empty_flips](
const Rect& a,
const Rect&
b,
1354 const Rect& result) {
1355 ASSERT_FALSE(a.IsEmpty()) << a;
1358 std::stringstream stream;
1359 stream << a <<
" union " <<
b;
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);
1372 test(a,
b, expected);
1379 test(a,
b, expected);
1386 test(a,
b, expected);
1393 test(a,
b, expected);
1400 test(a,
b, expected);
1410 EXPECT_FALSE(
Rect::Union(std::nullopt, std::nullopt).has_value());
1411 EXPECT_EQ(
Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1413 auto test1 = [](
const Rect& r) {
1415 EXPECT_TRUE(
Rect::Union(r, std::nullopt).has_value());
1416 EXPECT_EQ(
Rect::Union(r, std::nullopt).value(), r);
1419 EXPECT_TRUE(
Rect::Union(std::optional(r), std::nullopt).has_value());
1420 EXPECT_EQ(
Rect::Union(std::optional(r), std::nullopt).value(), r);
1423 EXPECT_TRUE(
Rect::Union(std::nullopt, r).has_value());
1424 EXPECT_EQ(
Rect::Union(std::nullopt, r).value(), r);
1427 EXPECT_TRUE(
Rect::Union(std::nullopt, std::optional(r)).has_value());
1428 EXPECT_EQ(
Rect::Union(std::nullopt, std::optional(r)).value(), r);
1435 auto test2 = [](
const Rect& a,
const Rect&
b,
const Rect& u) {
1436 ASSERT_EQ(a.
Union(
b), u);
1439 EXPECT_TRUE(
Rect::Union(a, std::optional(
b)).has_value());
1440 EXPECT_EQ(
Rect::Union(a, std::optional(
b)).value(), u);
1443 EXPECT_TRUE(
Rect::Union(std::optional(a),
b).has_value());
1444 EXPECT_EQ(
Rect::Union(std::optional(a),
b).value(), u);
1447 EXPECT_TRUE(
Rect::Union(std::optional(a), std::optional(
b)).has_value());
1448 EXPECT_EQ(
Rect::Union(std::optional(a), std::optional(
b)).value(), u);
1457 auto check_empty_flips = [](
const IRect& a,
const IRect&
b,
1458 const std::string& label) {
1468 EXPECT_EQ(
flip_lr(a).Union(
b),
b) << label;
1469 EXPECT_EQ(
flip_tb(a).Union(
b),
b) << label;
1478 auto test = [&check_empty_flips](
const IRect& a,
const IRect&
b,
1479 const IRect& result) {
1480 ASSERT_FALSE(a.
IsEmpty()) << a;
1483 std::stringstream stream;
1484 stream << a <<
" union " <<
b;
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);
1496 test(a,
b, expected);
1503 test(a,
b, expected);
1510 test(a,
b, expected);
1517 test(a,
b, expected);
1524 test(a,
b, expected);
1534 EXPECT_FALSE(
IRect::Union(std::nullopt, std::nullopt).has_value());
1535 EXPECT_EQ(
IRect::Union(std::nullopt, std::nullopt), std::nullopt);
1537 auto test1 = [](
const IRect& r) {
1539 EXPECT_TRUE(
IRect::Union(r, std::nullopt).has_value());
1543 EXPECT_TRUE(
IRect::Union(std::optional(r), std::nullopt).has_value());
1544 EXPECT_EQ(
IRect::Union(std::optional(r), std::nullopt).value(), r);
1547 EXPECT_TRUE(
IRect::Union(std::nullopt, r).has_value());
1551 EXPECT_TRUE(
IRect::Union(std::nullopt, std::optional(r)).has_value());
1552 EXPECT_EQ(
IRect::Union(std::nullopt, std::optional(r)).value(), r);
1560 ASSERT_EQ(a.
Union(
b), u);
1571 EXPECT_TRUE(
IRect::Union(std::optional(a), std::optional(
b)).has_value());
1572 EXPECT_EQ(
IRect::Union(std::optional(a), std::optional(
b)).value(), 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;
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) {
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;
1616 EXPECT_FALSE(
flip_lr(a).Intersection(
flip_lr(
b)).has_value()) << label;
1617 EXPECT_FALSE(
flip_tb(a).Intersection(
flip_tb(
b)).has_value()) << label;
1621 auto test_non_empty = [&check_nans, &check_empty_flips](
1623 ASSERT_FALSE(a.IsEmpty()) << a;
1626 std::stringstream stream;
1627 stream << a <<
" union " <<
b;
1628 auto label = stream.str();
1630 EXPECT_TRUE(a.Intersection(
b).has_value()) << label;
1631 EXPECT_TRUE(
b.Intersection(a).has_value()) << label;
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);
1638 auto test_empty = [&check_nans, &check_empty_flips](
const Rect& a,
1640 ASSERT_FALSE(a.IsEmpty()) << a;
1643 std::stringstream stream;
1644 stream << a <<
" union " <<
b;
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);
1697 TEST(RectTest, OptRectIntersection) {
1706 auto test1 = [](
const Rect& r) {
1728 auto test2 = [](
const Rect& a,
const Rect&
b,
const Rect& i) {
1751 TEST(RectTest, IRectIntersection) {
1752 auto check_empty_flips = [](
const IRect& a,
const IRect&
b,
1753 const std::string& 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;
1768 EXPECT_FALSE(
flip_lr(a).Intersection(
flip_lr(
b)).has_value()) << label;
1769 EXPECT_FALSE(
flip_tb(a).Intersection(
flip_tb(
b)).has_value()) << label;
1773 auto test_non_empty = [&check_empty_flips](
const IRect& a,
const IRect&
b,
1774 const IRect& result) {
1775 ASSERT_FALSE(a.
IsEmpty()) << a;
1778 std::stringstream stream;
1779 stream << a <<
" union " <<
b;
1780 auto label = stream.str();
1783 EXPECT_TRUE(
b.Intersection(a).has_value()) << label;
1785 EXPECT_EQ(
b.Intersection(a), result) << label;
1786 check_empty_flips(a,
b, label);
1789 auto test_empty = [&check_empty_flips](
const IRect& a,
const IRect&
b) {
1790 ASSERT_FALSE(a.
IsEmpty()) << a;
1793 std::stringstream stream;
1794 stream << a <<
" union " <<
b;
1795 auto label = stream.str();
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);
1846 TEST(RectTest, OptIRectIntersection) {
1855 auto test1 = [](
const IRect& r) {
1902 TEST(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;
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) {
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;
1949 stream << a <<
" union " <<
b;
1950 auto label = stream.str();
1952 EXPECT_TRUE(a.IntersectsWithRect(
b)) << label;
1953 EXPECT_TRUE(
b.IntersectsWithRect(a)) << label;
1954 check_empty_flips(a,
b, label);
1955 check_nans(a,
b, label);
1958 auto test_empty = [&check_nans, &check_empty_flips](
const Rect& a,
1960 ASSERT_FALSE(a.IsEmpty()) << a;
1963 std::stringstream stream;
1964 stream << a <<
" union " <<
b;
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);
2016 TEST(RectTest, IRectIntersectsWithRect) {
2017 auto check_empty_flips = [](
const IRect& a,
const IRect&
b,
2018 const std::string& 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;
2043 stream << a <<
" union " <<
b;
2044 auto label = stream.str();
2047 EXPECT_TRUE(
b.IntersectsWithRect(a)) << label;
2048 check_empty_flips(a,
b, label);
2051 auto test_empty = [&check_empty_flips](
const IRect& a,
const IRect&
b) {
2052 ASSERT_FALSE(a.
IsEmpty()) << a;
2055 std::stringstream stream;
2056 stream << a <<
" union " <<
b;
2057 auto label = stream.str();
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);
2107 TEST(RectTest, RectContainsPoint) {
2108 auto check_nans = [](
const Rect& rect,
const Point& point,
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++) {
2114 EXPECT_FALSE(
swap_nan(rect, i).Contains(point))
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) {
2127 EXPECT_FALSE(
flip_lr(rect).Contains(point)) << label;
2128 EXPECT_FALSE(
flip_tb(rect).Contains(point)) << label;
2129 EXPECT_FALSE(
flip_lrtb(rect).Contains(point)) << label;
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;
2137 stream << rect <<
" contains " << point;
2138 auto label = stream.str();
2140 EXPECT_TRUE(rect.Contains(point)) << label;
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;
2150 stream << rect <<
" contains " << point;
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);
2174 auto p =
Point(99, 99);
2180 auto p =
Point(199, 199);
2187 auto p =
Point(199, 199);
2193 TEST(RectTest, IRectContainsIPoint) {
2194 auto check_empty_flips = [](
const IRect& rect,
const IPoint& point,
2195 const std::string& label) {
2198 EXPECT_FALSE(
flip_lr(rect).Contains(point)) << label;
2199 EXPECT_FALSE(
flip_tb(rect).Contains(point)) << label;
2200 EXPECT_FALSE(
flip_lrtb(rect).Contains(point)) << label;
2203 auto test_inside = [&check_empty_flips](
const IRect& rect,
2205 ASSERT_FALSE(rect.
IsEmpty()) << rect;
2207 std::stringstream stream;
2208 stream << rect <<
" contains " << point;
2209 auto label = stream.str();
2211 EXPECT_TRUE(rect.
Contains(point)) << label;
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;
2220 stream << rect <<
" contains " << point;
2221 auto label = stream.str();
2223 EXPECT_FALSE(rect.
Contains(point)) << label;
2224 check_empty_flips(rect, point, label);
2230 auto p =
IPoint(100, 100);
2237 auto p =
IPoint(200, 200);
2249 auto p =
IPoint(199, 199);
2256 auto p =
IPoint(199, 199);
2263 auto check_nans = [](
const Rect& a,
const Rect&
b,
const std::string& label) {
2264 ASSERT_TRUE(a.
IsFinite()) << label;
2265 ASSERT_TRUE(
b.IsFinite()) << label;
2268 for (
int i = 1; i < 16; i++) {
2270 EXPECT_FALSE(
swap_nan(a, i).Contains(
b)) << label <<
", index = " << i;
2274 for (
int j = 1; j < 16; j++) {
2276 << label <<
", indices = " << i <<
", " << j;
2281 auto check_empty_flips = [](
const Rect& a,
const Rect&
b,
2282 const std::string& label) {
2285 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2293 EXPECT_FALSE(
flip_lr(a).Contains(
b)) << label;
2294 EXPECT_FALSE(
flip_tb(a).Contains(
b)) << label;
2295 EXPECT_FALSE(
flip_lrtb(a).Contains(
b)) << label;
2303 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& a,
2305 ASSERT_FALSE(a.IsEmpty()) << a;
2307 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2309 std::stringstream stream;
2310 stream << a <<
" contains " <<
b;
2311 auto label = stream.str();
2313 EXPECT_TRUE(a.Contains(
b)) << label;
2314 check_empty_flips(a,
b, label);
2315 check_nans(a,
b, label);
2318 auto test_not_inside = [&check_nans, &check_empty_flips](
const Rect& a,
2320 ASSERT_FALSE(a.IsEmpty()) << a;
2323 ASSERT_FALSE(
b.IsEmpty()) <<
b;
2325 std::stringstream stream;
2326 stream << a <<
" contains " <<
b;
2327 auto label = stream.str();
2329 EXPECT_FALSE(a.Contains(
b)) << label;
2330 check_empty_flips(a,
b, label);
2331 check_nans(a,
b, label);
2355 test_not_inside(a,
b);
2361 test_not_inside(a,
b);
2367 test_not_inside(a,
b);
2377 TEST(RectTest, IRectContainsIRect) {
2378 auto check_empty_flips = [](
const IRect& a,
const IRect&
b,
2379 const std::string& label) {
2382 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2390 EXPECT_FALSE(
flip_lr(a).Contains(
b)) << label;
2391 EXPECT_FALSE(
flip_tb(a).Contains(
b)) << label;
2392 EXPECT_FALSE(
flip_lrtb(a).Contains(
b)) << label;
2400 auto test_inside = [&check_empty_flips](
const IRect& a,
const IRect&
b) {
2401 ASSERT_FALSE(a.
IsEmpty()) << a;
2403 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2405 std::stringstream stream;
2406 stream << a <<
" contains " <<
b;
2407 auto label = stream.str();
2410 check_empty_flips(a,
b, label);
2413 auto test_not_inside = [&check_empty_flips](
const IRect& a,
const IRect&
b) {
2414 ASSERT_FALSE(a.
IsEmpty()) << a;
2417 ASSERT_FALSE(
b.IsEmpty()) <<
b;
2419 std::stringstream stream;
2420 stream << a <<
" contains " <<
b;
2421 auto label = stream.str();
2424 check_empty_flips(a,
b, label);
2448 test_not_inside(a,
b);
2454 test_not_inside(a,
b);
2460 test_not_inside(a,
b);
2473 auto check_nans = [&cull_rect](
const Rect& diff_rect,
2474 const std::string& label) {
2475 EXPECT_TRUE(cull_rect.
IsFinite()) << label;
2476 EXPECT_TRUE(diff_rect.
IsFinite()) << label;
2478 for (
int i = 1; i < 16; i++) {
2480 EXPECT_FALSE(
swap_nan(cull_rect, i).Cutout(diff_rect).has_value())
2481 << label <<
", index " << i;
2482 EXPECT_EQ(
swap_nan(cull_rect, i).CutoutOrEmpty(diff_rect),
Rect())
2483 << label <<
", index " << i;
2486 EXPECT_TRUE(cull_rect.
Cutout(
swap_nan(diff_rect, i)).has_value())
2487 << label <<
", index " << i;
2489 << label <<
", index " << i;
2491 for (
int j = 1; j < 16; j++) {
2495 << label <<
", indices " << i <<
", " << j;
2498 << label <<
", indices " << i <<
", " << j;
2503 auto check_empty_flips = [&cull_rect](
const Rect& diff_rect,
2504 const std::string& label) {
2505 EXPECT_FALSE(cull_rect.
IsEmpty()) << label;
2506 EXPECT_FALSE(diff_rect.
IsEmpty()) << label;
2510 EXPECT_TRUE(cull_rect.
Cutout(
flip_lr(diff_rect)).has_value()) << label;
2511 EXPECT_EQ(cull_rect.
Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2512 EXPECT_TRUE(cull_rect.
Cutout(
flip_tb(diff_rect)).has_value()) << label;
2513 EXPECT_EQ(cull_rect.
Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2514 EXPECT_TRUE(cull_rect.
Cutout(
flip_lrtb(diff_rect)).has_value()) << label;
2515 EXPECT_EQ(cull_rect.
Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2519 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2520 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2521 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2522 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2523 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2524 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2528 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
2532 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
2542 auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2543 const Rect& diff_rect,
const std::string& label) {
2544 EXPECT_EQ(cull_rect.
Cutout(diff_rect), cull_rect) << label;
2545 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), cull_rect) << label;
2546 check_empty_flips(diff_rect, label);
2547 check_nans(diff_rect, label);
2550 auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2551 const Rect& diff_rect,
const Rect& result_rect,
2552 const std::string& label) {
2553 EXPECT_TRUE(!result_rect.IsEmpty());
2554 EXPECT_EQ(cull_rect.
Cutout(diff_rect), result_rect) << label;
2555 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), result_rect) << label;
2556 check_empty_flips(diff_rect, label);
2557 check_nans(diff_rect, label);
2560 auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2561 const Rect& diff_rect,
const std::string& label) {
2562 EXPECT_FALSE(cull_rect.
Cutout(diff_rect).has_value()) << label;
2564 check_empty_flips(diff_rect, label);
2565 check_nans(diff_rect, label);
2569 non_reducing(
Rect::MakeLTRB(10, 10, 20, 20),
"outside UL corner");
2571 non_reducing(
Rect::MakeLTRB(40, 10, 50, 20),
"outside UR corner");
2573 non_reducing(
Rect::MakeLTRB(40, 40, 50, 50),
"outside LR corner");
2575 non_reducing(
Rect::MakeLTRB(10, 40, 20, 50),
"outside LR corner");
2579 non_reducing(
Rect::MakeLTRB(15, 15, 25, 25),
"covering UL corner");
2580 non_reducing(
Rect::MakeLTRB(35, 15, 45, 25),
"covering UR corner");
2581 non_reducing(
Rect::MakeLTRB(35, 35, 45, 45),
"covering LR corner");
2582 non_reducing(
Rect::MakeLTRB(15, 35, 25, 45),
"covering LL corner");
2585 non_reducing(
Rect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
2586 non_reducing(
Rect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
2587 non_reducing(
Rect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
2588 non_reducing(
Rect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
2589 non_reducing(
Rect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
2590 non_reducing(
Rect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
2591 non_reducing(
Rect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
2592 non_reducing(
Rect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
2595 non_reducing(
Rect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
2596 non_reducing(
Rect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
2607 "Slice off bottom");
2613 non_reducing(
Rect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
2616 emptying(cull_rect,
"Perfectly covering");
2625 auto check_empty_flips = [&cull_rect](
const IRect& diff_rect,
2626 const std::string& label) {
2627 EXPECT_FALSE(diff_rect.
IsEmpty());
2628 EXPECT_FALSE(cull_rect.
IsEmpty());
2632 EXPECT_TRUE(cull_rect.
Cutout(
flip_lr(diff_rect)).has_value()) << label;
2633 EXPECT_EQ(cull_rect.
Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2634 EXPECT_TRUE(cull_rect.
Cutout(
flip_tb(diff_rect)).has_value()) << label;
2635 EXPECT_EQ(cull_rect.
Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2636 EXPECT_TRUE(cull_rect.
Cutout(
flip_lrtb(diff_rect)).has_value()) << label;
2637 EXPECT_EQ(cull_rect.
Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2641 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2642 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2643 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2644 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2645 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2646 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2650 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
2654 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
2664 auto non_reducing = [&cull_rect, &check_empty_flips](
2665 const IRect& diff_rect,
const std::string& label) {
2666 EXPECT_EQ(cull_rect.
Cutout(diff_rect), cull_rect) << label;
2667 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), cull_rect) << label;
2668 check_empty_flips(diff_rect, label);
2671 auto reducing = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
2672 const IRect& result_rect,
2673 const std::string& label) {
2674 EXPECT_TRUE(!result_rect.IsEmpty());
2675 EXPECT_EQ(cull_rect.
Cutout(diff_rect), result_rect) << label;
2676 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), result_rect) << label;
2677 check_empty_flips(diff_rect, label);
2680 auto emptying = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
2681 const std::string& label) {
2682 EXPECT_FALSE(cull_rect.
Cutout(diff_rect).has_value()) << label;
2684 check_empty_flips(diff_rect, label);
2704 non_reducing(
IRect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
2705 non_reducing(
IRect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
2706 non_reducing(
IRect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
2707 non_reducing(
IRect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
2708 non_reducing(
IRect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
2709 non_reducing(
IRect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
2710 non_reducing(
IRect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
2711 non_reducing(
IRect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
2714 non_reducing(
IRect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
2715 non_reducing(
IRect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
2726 "Slice off bottom");
2732 non_reducing(
IRect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
2735 emptying(cull_rect,
"Perfectly covering");
2754 EXPECT_EQ(points[0],
Point(std::numeric_limits<float>::lowest(),
2755 std::numeric_limits<float>::lowest()));
2756 EXPECT_EQ(points[1],
Point(std::numeric_limits<float>::max(),
2757 std::numeric_limits<float>::lowest()));
2758 EXPECT_EQ(points[2],
Point(std::numeric_limits<float>::lowest(),
2759 std::numeric_limits<float>::max()));
2760 EXPECT_EQ(points[3],
Point(std::numeric_limits<float>::max(),
2761 std::numeric_limits<float>::max()));
2772 TEST(RectTest, RectGetTransformedPoints) {
2781 TEST(RectTest, RectMakePointBounds) {
2783 std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
2786 EXPECT_TRUE(r.has_value());
2787 if (r.has_value()) {
2792 std::vector<Point> points;
2794 EXPECT_FALSE(r.has_value());
2815 EXPECT_EQ(r.GetLeft(), 1);
2816 EXPECT_EQ(r.GetTop(), 2);
2817 EXPECT_EQ(r.GetRight(), 3);
2818 EXPECT_EQ(r.GetBottom(), 4);
2829 auto actual = r.Project(r);