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);
137 EXPECT_EQ(rect.
GetLeft(), 0.0f);
138 EXPECT_EQ(rect.
GetTop(), 0.0f);
141 EXPECT_EQ(rect.
GetX(), 0.0f);
142 EXPECT_EQ(rect.
GetY(), 0.0f);
149 TEST(RectTest, IRectSimpleWH) {
154 EXPECT_EQ(rect.
GetTop(), 0);
157 EXPECT_EQ(rect.
GetX(), 0);
158 EXPECT_EQ(rect.
GetY(), 0);
164 TEST(RectTest, RectOverflowXYWH) {
165 auto min = std::numeric_limits<Scalar>::lowest();
166 auto max = std::numeric_limits<Scalar>::max();
167 auto inf = std::numeric_limits<Scalar>::infinity();
185 EXPECT_EQ(rect.
GetLeft(), 5.0f);
186 EXPECT_EQ(rect.
GetTop(), 10.0f);
189 EXPECT_EQ(rect.
GetX(), 5.0f);
190 EXPECT_EQ(rect.
GetY(), 10.0f);
200 EXPECT_EQ(rect.
GetLeft(), max);
201 EXPECT_EQ(rect.
GetTop(), 10.0f);
204 EXPECT_EQ(rect.
GetX(), max);
205 EXPECT_EQ(rect.
GetY(), 10.0f);
215 EXPECT_EQ(rect.
GetLeft(), 5.0f);
216 EXPECT_EQ(rect.
GetTop(), 10.0f);
219 EXPECT_EQ(rect.
GetX(), 5.0f);
220 EXPECT_EQ(rect.
GetY(), 10.0f);
230 EXPECT_EQ(rect.
GetLeft(), 5.0f);
231 EXPECT_EQ(rect.
GetTop(), max);
234 EXPECT_EQ(rect.
GetX(), 5.0f);
235 EXPECT_EQ(rect.
GetY(), max);
245 EXPECT_EQ(rect.
GetLeft(), 5.0f);
246 EXPECT_EQ(rect.
GetTop(), 10.0f);
249 EXPECT_EQ(rect.
GetX(), 5.0f);
250 EXPECT_EQ(rect.
GetY(), 10.0f);
260 EXPECT_EQ(rect.
GetLeft(), min);
261 EXPECT_EQ(rect.
GetTop(), 10.0f);
264 EXPECT_EQ(rect.
GetX(), min);
265 EXPECT_EQ(rect.
GetY(), 10.0f);
275 EXPECT_EQ(rect.
GetLeft(), 5.0f);
276 EXPECT_EQ(rect.
GetTop(), 10.0f);
279 EXPECT_EQ(rect.
GetX(), 5.0f);
280 EXPECT_EQ(rect.
GetY(), 10.0f);
290 EXPECT_EQ(rect.
GetLeft(), 5.0f);
291 EXPECT_EQ(rect.
GetTop(), min);
294 EXPECT_EQ(rect.
GetX(), 5.0f);
295 EXPECT_EQ(rect.
GetY(), min);
303 TEST(RectTest, IRectOverflowXYWH) {
304 auto min = std::numeric_limits<int64_t>::min();
305 auto max = std::numeric_limits<int64_t>::max();
316 EXPECT_EQ(rect.
GetLeft(), max - 5);
317 EXPECT_EQ(rect.
GetTop(), 10);
320 EXPECT_EQ(rect.
GetX(), max - 5);
321 EXPECT_EQ(rect.
GetY(), 10);
330 EXPECT_EQ(rect.
GetLeft(), min + 5);
331 EXPECT_EQ(rect.
GetTop(), 10);
334 EXPECT_EQ(rect.
GetX(), min + 5);
335 EXPECT_EQ(rect.
GetY(), 10);
345 EXPECT_EQ(rect.
GetTop(), max - 10);
348 EXPECT_EQ(rect.
GetX(), 5);
349 EXPECT_EQ(rect.
GetY(), max - 10);
359 EXPECT_EQ(rect.
GetTop(), min + 10);
362 EXPECT_EQ(rect.
GetX(), 5);
363 EXPECT_EQ(rect.
GetY(), min + 10);
370 TEST(RectTest, RectOverflowLTRB) {
371 auto min = std::numeric_limits<Scalar>::lowest();
372 auto max = std::numeric_limits<Scalar>::max();
373 auto inf = std::numeric_limits<Scalar>::infinity();
391 EXPECT_EQ(rect.
GetLeft(), -5.0f);
392 EXPECT_EQ(rect.
GetTop(), 10.0f);
395 EXPECT_EQ(rect.
GetX(), -5.0f);
396 EXPECT_EQ(rect.
GetY(), 10.0f);
406 EXPECT_EQ(rect.
GetLeft(), min + 5.0f);
407 EXPECT_EQ(rect.
GetTop(), 10.0f);
408 EXPECT_EQ(rect.
GetRight(), max - 5.0f);
410 EXPECT_EQ(rect.
GetX(), min + 5.0f);
411 EXPECT_EQ(rect.
GetY(), 10.0f);
421 EXPECT_EQ(rect.
GetLeft(), 5.0f);
422 EXPECT_EQ(rect.
GetTop(), -10.0f);
425 EXPECT_EQ(rect.
GetX(), 5.0f);
426 EXPECT_EQ(rect.
GetY(), -10.0f);
436 EXPECT_EQ(rect.
GetLeft(), 5.0f);
437 EXPECT_EQ(rect.
GetTop(), min + 10.0f);
439 EXPECT_EQ(rect.
GetBottom(), max - 15.0f);
440 EXPECT_EQ(rect.
GetX(), 5.0f);
441 EXPECT_EQ(rect.
GetY(), min + 10.0f);
451 EXPECT_EQ(rect.
GetLeft(), 5.0f);
452 EXPECT_EQ(rect.
GetTop(), 10.0f);
455 EXPECT_EQ(rect.
GetX(), 5.0f);
456 EXPECT_EQ(rect.
GetY(), 10.0f);
466 EXPECT_EQ(rect.
GetLeft(), max - 5.0f);
467 EXPECT_EQ(rect.
GetTop(), 10.0f);
468 EXPECT_EQ(rect.
GetRight(), min + 10.0f);
470 EXPECT_EQ(rect.
GetX(), max - 5.0f);
471 EXPECT_EQ(rect.
GetY(), 10.0f);
481 EXPECT_EQ(rect.
GetLeft(), 5.0f);
482 EXPECT_EQ(rect.
GetTop(), 10.0f);
485 EXPECT_EQ(rect.
GetX(), 5.0f);
486 EXPECT_EQ(rect.
GetY(), 10.0f);
496 EXPECT_EQ(rect.
GetLeft(), 5.0f);
497 EXPECT_EQ(rect.
GetTop(), max - 5.0f);
499 EXPECT_EQ(rect.
GetBottom(), min + 10.0f);
500 EXPECT_EQ(rect.
GetX(), 5.0f);
501 EXPECT_EQ(rect.
GetY(), max - 5.0f);
509 TEST(RectTest, IRectOverflowLTRB) {
510 auto min = std::numeric_limits<int64_t>::min();
511 auto max = std::numeric_limits<int64_t>::max();
522 EXPECT_EQ(rect.
GetLeft(), -10);
523 EXPECT_EQ(rect.
GetTop(), 10);
524 EXPECT_EQ(rect.
GetRight(), max - 5);
526 EXPECT_EQ(rect.
GetX(), -10);
527 EXPECT_EQ(rect.
GetY(), 10);
537 EXPECT_EQ(rect.
GetTop(), 10);
538 EXPECT_EQ(rect.
GetRight(), min + 5);
540 EXPECT_EQ(rect.
GetX(), 10);
541 EXPECT_EQ(rect.
GetY(), 10);
551 EXPECT_EQ(rect.
GetTop(), -10);
554 EXPECT_EQ(rect.
GetX(), 5);
555 EXPECT_EQ(rect.
GetY(), -10);
565 EXPECT_EQ(rect.
GetTop(), 10);
568 EXPECT_EQ(rect.
GetX(), 5);
569 EXPECT_EQ(rect.
GetY(), 10);
595 EXPECT_EQ(r, expected);
602 EXPECT_EQ(r, expected);
606 TEST(RectTest, RectMakeMaximum) {
608 auto inf = std::numeric_limits<Scalar>::infinity();
609 auto min = std::numeric_limits<Scalar>::lowest();
610 auto max = std::numeric_limits<Scalar>::max();
612 EXPECT_EQ(rect.
GetLeft(), min);
613 EXPECT_EQ(rect.
GetTop(), min);
616 EXPECT_EQ(rect.
GetX(), min);
617 EXPECT_EQ(rect.
GetY(), min);
624 TEST(RectTest, IRectMakeMaximum) {
626 auto min = std::numeric_limits<int64_t>::min();
627 auto max = std::numeric_limits<int64_t>::max();
629 EXPECT_EQ(rect.
GetLeft(), min);
630 EXPECT_EQ(rect.
GetTop(), min);
633 EXPECT_EQ(rect.
GetX(), min);
634 EXPECT_EQ(rect.
GetY(), min);
647 TEST(RectTest, IRectFromIRect) {
659 EXPECT_EQ(rect, copy);
660 EXPECT_EQ(copy.
GetLeft(), 5.125f);
661 EXPECT_EQ(copy.
GetTop(), 10.25f);
662 EXPECT_EQ(copy.
GetRight(), 20.625f);
664 EXPECT_EQ(copy.
GetX(), 5.125f);
665 EXPECT_EQ(copy.
GetY(), 10.25f);
676 EXPECT_EQ(rect, copy);
678 EXPECT_EQ(copy.
GetTop(), 10);
681 EXPECT_EQ(copy.
GetX(), 5);
682 EXPECT_EQ(copy.
GetY(), 10);
688 TEST(RectTest, RectOriginSizeXYWHGetters) {
693 EXPECT_EQ(r.
GetX(), 10);
694 EXPECT_EQ(r.
GetY(), 20);
697 auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
698 EXPECT_EQ(r.
GetXYWH(), expected_array);
705 EXPECT_EQ(r.
GetX(), 10);
706 EXPECT_EQ(r.
GetY(), 20);
709 auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
710 EXPECT_EQ(r.
GetXYWH(), expected_array);
714 TEST(RectTest, IRectOriginSizeXYWHGetters) {
719 EXPECT_EQ(r.
GetX(), 10);
720 EXPECT_EQ(r.
GetY(), 20);
723 auto expected_array = std::array<int64_t, 4>{10, 20, 50, 40};
724 EXPECT_EQ(r.
GetXYWH(), expected_array);
731 EXPECT_EQ(r.
GetX(), 10);
732 EXPECT_EQ(r.
GetY(), 20);
735 auto expected_array = std::array<int64_t, 4>{10, 20, 40, 20};
736 EXPECT_EQ(r.
GetXYWH(), expected_array);
740 TEST(RectTest, RectRoundOutEmpty) {
748 TEST(RectTest, RectRoundOutSimple) {
756 TEST(RectTest, RectRoundOutToIRectHuge) {
757 auto test = [](
int corners) {
758 EXPECT_TRUE(corners >= 0 && corners <= 0xf);
760 int64_t il, it, ir, ib;
765 if ((corners & (1 << 0)) != 0) {
767 il = std::numeric_limits<int64_t>::min();
769 if ((corners & (1 << 1)) != 0) {
771 it = std::numeric_limits<int64_t>::min();
773 if ((corners & (1 << 2)) != 0) {
775 ir = std::numeric_limits<int64_t>::max();
777 if ((corners & (1 << 3)) != 0) {
779 ib = std::numeric_limits<int64_t>::max();
784 EXPECT_EQ(irect.
GetLeft(), il) << corners;
785 EXPECT_EQ(irect.
GetTop(), it) << corners;
786 EXPECT_EQ(irect.
GetRight(), ir) << corners;
787 EXPECT_EQ(irect.
GetBottom(), ib) << corners;
790 for (
int corners = 0; corners <= 15; corners++) {
795 TEST(RectTest, RectDoesNotIntersectEmpty) {
799 const std::string& label) {
801 << label <<
" with Top/Bottom swapped";
803 << label <<
" with Left/Right swapped";
805 << label <<
" with all sides swapped";
808 test(20, 20, 30, 30,
"Above and Left");
809 test(70, 20, 80, 30,
"Above");
810 test(120, 20, 130, 30,
"Above and Right");
811 test(120, 70, 130, 80,
"Right");
812 test(120, 120, 130, 130,
"Below and Right");
813 test(70, 120, 80, 130,
"Below");
814 test(20, 120, 30, 130,
"Below and Left");
815 test(20, 70, 30, 80,
"Left");
817 test(70, 70, 80, 80,
"Inside");
819 test(40, 70, 60, 80,
"Straddling Left");
820 test(70, 40, 80, 60,
"Straddling Top");
821 test(90, 70, 110, 80,
"Straddling Right");
822 test(70, 90, 80, 110,
"Straddling Bottom");
825 TEST(RectTest, IRectDoesNotIntersectEmpty) {
828 auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t
b,
829 const std::string& label) {
831 << label <<
" with Top/Bottom swapped";
833 << label <<
" with Left/Right swapped";
835 << label <<
" with all sides swapped";
838 test(20, 20, 30, 30,
"Above and Left");
839 test(70, 20, 80, 30,
"Above");
840 test(120, 20, 130, 30,
"Above and Right");
841 test(120, 70, 130, 80,
"Right");
842 test(120, 120, 130, 130,
"Below and Right");
843 test(70, 120, 80, 130,
"Below");
844 test(20, 120, 30, 130,
"Below and Left");
845 test(20, 70, 30, 80,
"Left");
847 test(70, 70, 80, 80,
"Inside");
849 test(40, 70, 60, 80,
"Straddling Left");
850 test(70, 40, 80, 60,
"Straddling Top");
851 test(90, 70, 110, 80,
"Straddling Right");
852 test(70, 90, 80, 110,
"Straddling Bottom");
855 TEST(RectTest, EmptyRectDoesNotIntersect) {
859 const std::string& label) {
861 << label <<
" with Top/Bottom swapped";
863 << label <<
" with Left/Right swapped";
865 << label <<
" with all sides swapped";
868 test(20, 20, 30, 30,
"Above and Left");
869 test(70, 20, 80, 30,
"Above");
870 test(120, 20, 130, 30,
"Above and Right");
871 test(120, 70, 130, 80,
"Right");
872 test(120, 120, 130, 130,
"Below and Right");
873 test(70, 120, 80, 130,
"Below");
874 test(20, 120, 30, 130,
"Below and Left");
875 test(20, 70, 30, 80,
"Left");
877 test(70, 70, 80, 80,
"Inside");
879 test(40, 70, 60, 80,
"Straddling Left");
880 test(70, 40, 80, 60,
"Straddling Top");
881 test(90, 70, 110, 80,
"Straddling Right");
882 test(70, 90, 80, 110,
"Straddling Bottom");
885 TEST(RectTest, EmptyIRectDoesNotIntersect) {
888 auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t
b,
889 const std::string& label) {
891 << label <<
" with Top/Bottom swapped";
893 << label <<
" with Left/Right swapped";
895 << label <<
" with all sides swapped";
898 test(20, 20, 30, 30,
"Above and Left");
899 test(70, 20, 80, 30,
"Above");
900 test(120, 20, 130, 30,
"Above and Right");
901 test(120, 70, 130, 80,
"Right");
902 test(120, 120, 130, 130,
"Below and Right");
903 test(70, 120, 80, 130,
"Below");
904 test(20, 120, 30, 130,
"Below and Left");
905 test(20, 70, 30, 80,
"Left");
907 test(70, 70, 80, 80,
"Inside");
909 test(40, 70, 60, 80,
"Straddling Left");
910 test(70, 40, 80, 60,
"Straddling Top");
911 test(90, 70, 110, 80,
"Straddling Right");
912 test(70, 90, 80, 110,
"Straddling Bottom");
923 << rect <<
" * " <<
scale;
925 << rect <<
" * " <<
scale;
927 << rect <<
" * " <<
scale;
929 << rect <<
" * " <<
scale;
934 rect.
GetY() * scale_y,
939 << rect <<
" * " << scale_x <<
", " << scale_y;
941 << rect <<
" * " << scale_x <<
", " << scale_y;
943 << rect <<
" * " << scale_x <<
", " << scale_y;
945 test1(rect, scale_x);
946 test1(rect, scale_y);
968 << rect <<
" * " <<
scale;
970 << rect <<
" * " <<
scale;
972 << rect <<
" * " <<
scale;
974 << rect <<
" * " <<
scale;
977 auto test2 = [&test1](
IRect rect, int64_t scale_x, int64_t scale_y) {
979 rect.
GetY() * scale_y,
983 EXPECT_EQ(rect.
Scale(scale_x, scale_y), expected)
984 << rect <<
" * " << scale_x <<
", " << scale_y;
985 EXPECT_EQ(rect.
Scale(
IPoint(scale_x, scale_y)), expected)
986 << rect <<
" * " << scale_x <<
", " << scale_y;
987 EXPECT_EQ(rect.
Scale(
ISize(scale_x, scale_y)), expected)
988 << rect <<
" * " << scale_x <<
", " << scale_y;
990 test1(rect, scale_x);
991 test1(rect, scale_y);
1020 TEST(RectTest, RectGetNormalizingTransform) {
1026 EXPECT_EQ(r.GetNormalizingTransform(),
1035 auto m = r.GetNormalizingTransform();
1044 EXPECT_EQ(m *
Point(350, 600),
Point(0.5, 0.5));
1047 EXPECT_EQ(m *
Point(200, 300),
Point(-1, -1));
1048 EXPECT_EQ(m *
Point(500, 300),
Point(2, -1));
1050 EXPECT_EQ(m *
Point(200, 900),
Point(-1, 2));
1059 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1060 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1061 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1064 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1065 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1066 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1073 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1074 auto inf = std::numeric_limits<Scalar>::infinity();
1077 EXPECT_EQ(
Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1078 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1079 EXPECT_EQ(
Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1082 EXPECT_EQ(
Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1083 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1084 EXPECT_EQ(
Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1087 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1088 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1089 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1092 EXPECT_EQ(
Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1093 EXPECT_EQ(
Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1094 EXPECT_EQ(
Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1097 EXPECT_EQ(
Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1098 EXPECT_EQ(
Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1099 EXPECT_EQ(
Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1102 EXPECT_EQ(
Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1103 EXPECT_EQ(
Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1104 EXPECT_EQ(
Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1108 TEST(RectTest, IRectGetNormalizingTransform) {
1114 EXPECT_EQ(r.GetNormalizingTransform(),
1123 auto m = r.GetNormalizingTransform();
1132 EXPECT_EQ(m *
Point(350, 600),
Point(0.5, 0.5));
1135 EXPECT_EQ(m *
Point(200, 300),
Point(-1, -1));
1136 EXPECT_EQ(m *
Point(500, 300),
Point(2, -1));
1138 EXPECT_EQ(m *
Point(200, 900),
Point(-1, 2));
1147 EXPECT_EQ(
IRect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1148 EXPECT_EQ(
IRect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1149 EXPECT_EQ(
IRect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1152 EXPECT_EQ(
IRect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1153 EXPECT_EQ(
IRect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1154 EXPECT_EQ(
IRect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1159 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1199 TEST(RectTest, MakePointBoundsQuad) {
1207 EXPECT_TRUE(bounds.has_value());
1208 if (bounds.has_value()) {
1244 EXPECT_EQ(rect.Expand(10, 10),
Rect::MakeLTRB(90, 90, 210, 210));
1245 EXPECT_EQ(rect.Expand(10, -10),
Rect::MakeLTRB(90, 110, 210, 190));
1246 EXPECT_EQ(rect.Expand(-10, 10),
Rect::MakeLTRB(110, 90, 190, 210));
1247 EXPECT_EQ(rect.Expand(-10, -10),
Rect::MakeLTRB(110, 110, 190, 190));
1250 EXPECT_EQ(rect.Expand(10, 20, 30, 40),
Rect::MakeLTRB(90, 80, 230, 240));
1251 EXPECT_EQ(rect.Expand(-10, 20, 30, 40),
Rect::MakeLTRB(110, 80, 230, 240));
1252 EXPECT_EQ(rect.Expand(10, -20, 30, 40),
Rect::MakeLTRB(90, 120, 230, 240));
1253 EXPECT_EQ(rect.Expand(10, 20, -30, 40),
Rect::MakeLTRB(90, 80, 170, 240));
1254 EXPECT_EQ(rect.Expand(10, 20, 30, -40),
Rect::MakeLTRB(90, 80, 230, 160));
1280 EXPECT_EQ(rect.Expand(-10, -10),
IRect::MakeLTRB(110, 110, 190, 190));
1283 EXPECT_EQ(rect.Expand(10, 20, 30, 40),
IRect::MakeLTRB(90, 80, 230, 240));
1284 EXPECT_EQ(rect.Expand(-10, 20, 30, 40),
IRect::MakeLTRB(110, 80, 230, 240));
1285 EXPECT_EQ(rect.Expand(10, -20, 30, 40),
IRect::MakeLTRB(90, 120, 230, 240));
1286 EXPECT_EQ(rect.Expand(10, 20, -30, 40),
IRect::MakeLTRB(90, 80, 170, 240));
1287 EXPECT_EQ(rect.Expand(10, 20, 30, -40),
IRect::MakeLTRB(90, 80, 230, 160));
1302 TEST(RectTest, ContainsFloatingPoint) {
1304 Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
1306 EXPECT_TRUE(rect1.Contains(rect2));
1309 template <
typename R>
1311 return R::MakeLTRB(rect.GetRight(), rect.GetTop(),
1312 rect.GetLeft(), rect.GetBottom());
1315 template <
typename R>
1317 return R::MakeLTRB(rect.GetLeft(), rect.GetBottom(),
1318 rect.GetRight(), rect.GetTop());
1321 template <
typename R>
1327 Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1328 FML_DCHECK(index >= 0 && index <= 15);
1329 Scalar l = ((index & (1 << 0)) != 0) ? nan : rect.
GetLeft();
1330 Scalar t = ((index & (1 << 1)) != 0) ? nan : rect.
GetTop();
1337 Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1338 FML_DCHECK(index >= 0 && index <= 3);
1339 Scalar x = ((index & (1 << 0)) != 0) ? nan : point.
x;
1340 Scalar y = ((index & (1 << 1)) != 0) ? nan : point.
y;
1345 auto check_nans = [](
const Rect& a,
const Rect&
b,
const std::string& label) {
1346 ASSERT_TRUE(a.
IsFinite()) << label;
1347 ASSERT_TRUE(
b.IsFinite()) << label;
1350 for (
int i = 1; i < 16; i++) {
1352 EXPECT_EQ(
swap_nan(a, i).Union(
b),
b) << label <<
", index = " << i;
1354 EXPECT_EQ(a.
Union(
swap_nan(
b, i)), a) << label <<
", index = " << i;
1356 for (
int j = 1; j < 16; j++) {
1358 << label <<
", indices = " << i <<
", " << j;
1363 auto check_empty_flips = [](
const Rect& a,
const Rect&
b,
1364 const std::string& label) {
1374 EXPECT_EQ(
flip_lr(a).Union(
b),
b) << label;
1375 EXPECT_EQ(
flip_tb(a).Union(
b),
b) << label;
1384 auto test = [&check_nans, &check_empty_flips](
const Rect& a,
const Rect&
b,
1385 const Rect& result) {
1386 ASSERT_FALSE(a.IsEmpty()) << a;
1389 std::stringstream stream;
1390 stream << a <<
" union " <<
b;
1391 auto label = stream.str();
1393 EXPECT_EQ(a.Union(
b), result) << label;
1394 EXPECT_EQ(
b.Union(a), result) << label;
1395 check_empty_flips(a,
b, label);
1396 check_nans(a,
b, label);
1403 test(a,
b, expected);
1410 test(a,
b, expected);
1417 test(a,
b, expected);
1424 test(a,
b, expected);
1431 test(a,
b, expected);
1441 EXPECT_FALSE(
Rect::Union(std::nullopt, std::nullopt).has_value());
1442 EXPECT_EQ(
Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1444 auto test1 = [](
const Rect& r) {
1446 EXPECT_TRUE(
Rect::Union(r, std::nullopt).has_value());
1447 EXPECT_EQ(
Rect::Union(r, std::nullopt).value(), r);
1450 EXPECT_TRUE(
Rect::Union(std::optional(r), std::nullopt).has_value());
1451 EXPECT_EQ(
Rect::Union(std::optional(r), std::nullopt).value(), r);
1454 EXPECT_TRUE(
Rect::Union(std::nullopt, r).has_value());
1455 EXPECT_EQ(
Rect::Union(std::nullopt, r).value(), r);
1458 EXPECT_TRUE(
Rect::Union(std::nullopt, std::optional(r)).has_value());
1459 EXPECT_EQ(
Rect::Union(std::nullopt, std::optional(r)).value(), r);
1466 auto test2 = [](
const Rect& a,
const Rect&
b,
const Rect& u) {
1467 ASSERT_EQ(a.
Union(
b), u);
1470 EXPECT_TRUE(
Rect::Union(a, std::optional(
b)).has_value());
1471 EXPECT_EQ(
Rect::Union(a, std::optional(
b)).value(), u);
1474 EXPECT_TRUE(
Rect::Union(std::optional(a),
b).has_value());
1475 EXPECT_EQ(
Rect::Union(std::optional(a),
b).value(), u);
1478 EXPECT_TRUE(
Rect::Union(std::optional(a), std::optional(
b)).has_value());
1479 EXPECT_EQ(
Rect::Union(std::optional(a), std::optional(
b)).value(), u);
1488 auto check_empty_flips = [](
const IRect& a,
const IRect&
b,
1489 const std::string& label) {
1499 EXPECT_EQ(
flip_lr(a).Union(
b),
b) << label;
1500 EXPECT_EQ(
flip_tb(a).Union(
b),
b) << label;
1509 auto test = [&check_empty_flips](
const IRect& a,
const IRect&
b,
1510 const IRect& result) {
1511 ASSERT_FALSE(a.
IsEmpty()) << a;
1514 std::stringstream stream;
1515 stream << a <<
" union " <<
b;
1516 auto label = stream.str();
1518 EXPECT_EQ(a.
Union(
b), result) << label;
1519 EXPECT_EQ(
b.Union(a), result) << label;
1520 check_empty_flips(a,
b, label);
1527 test(a,
b, expected);
1534 test(a,
b, expected);
1541 test(a,
b, expected);
1548 test(a,
b, expected);
1555 test(a,
b, expected);
1565 EXPECT_FALSE(
IRect::Union(std::nullopt, std::nullopt).has_value());
1566 EXPECT_EQ(
IRect::Union(std::nullopt, std::nullopt), std::nullopt);
1568 auto test1 = [](
const IRect& r) {
1570 EXPECT_TRUE(
IRect::Union(r, std::nullopt).has_value());
1574 EXPECT_TRUE(
IRect::Union(std::optional(r), std::nullopt).has_value());
1575 EXPECT_EQ(
IRect::Union(std::optional(r), std::nullopt).value(), r);
1578 EXPECT_TRUE(
IRect::Union(std::nullopt, r).has_value());
1582 EXPECT_TRUE(
IRect::Union(std::nullopt, std::optional(r)).has_value());
1583 EXPECT_EQ(
IRect::Union(std::nullopt, std::optional(r)).value(), r);
1591 ASSERT_EQ(a.
Union(
b), u);
1602 EXPECT_TRUE(
IRect::Union(std::optional(a), std::optional(
b)).has_value());
1603 EXPECT_EQ(
IRect::Union(std::optional(a), std::optional(
b)).value(), u);
1612 auto check_nans = [](
const Rect& a,
const Rect&
b,
const std::string& label) {
1613 ASSERT_TRUE(a.
IsFinite()) << label;
1614 ASSERT_TRUE(
b.IsFinite()) << label;
1616 for (
int i = 1; i < 16; i++) {
1618 EXPECT_FALSE(
swap_nan(a, i).Intersection(
b).has_value())
1619 << label <<
", index = " << i;
1622 << label <<
", index = " << i;
1624 for (
int j = 1; j < 16; j++) {
1626 << label <<
", indices = " << i <<
", " << j;
1631 auto check_empty_flips = [](
const Rect& a,
const Rect&
b,
1632 const std::string& label) {
1645 EXPECT_FALSE(
flip_lr(a).Intersection(
b).has_value()) << label;
1646 EXPECT_TRUE(
flip_lr(a).IntersectionOrEmpty(
b).IsEmpty()) << label;
1647 EXPECT_FALSE(
flip_tb(a).Intersection(
b).has_value()) << label;
1648 EXPECT_TRUE(
flip_tb(a).IntersectionOrEmpty(
b).IsEmpty()) << label;
1649 EXPECT_FALSE(
flip_lrtb(a).Intersection(
b).has_value()) << label;
1650 EXPECT_TRUE(
flip_lrtb(a).IntersectionOrEmpty(
b).IsEmpty()) << label;
1653 EXPECT_FALSE(
flip_lr(a).Intersection(
flip_lr(
b)).has_value()) << label;
1654 EXPECT_TRUE(
flip_lr(a).IntersectionOrEmpty(
flip_lr(
b)).IsEmpty()) << label;
1655 EXPECT_FALSE(
flip_tb(a).Intersection(
flip_tb(
b)).has_value()) << label;
1656 EXPECT_TRUE(
flip_tb(a).IntersectionOrEmpty(
flip_tb(
b)).IsEmpty()) << label;
1662 auto test_non_empty = [&check_nans, &check_empty_flips](
1664 ASSERT_FALSE(a.IsEmpty()) << a;
1667 std::stringstream stream;
1668 stream << a <<
" union " <<
b;
1669 auto label = stream.str();
1671 EXPECT_TRUE(a.Intersection(
b).has_value()) << label;
1672 EXPECT_TRUE(
b.Intersection(a).has_value()) << label;
1673 EXPECT_EQ(a.Intersection(
b), result) << label;
1674 EXPECT_EQ(
b.Intersection(a), result) << label;
1675 check_empty_flips(a,
b, label);
1676 check_nans(a,
b, label);
1679 auto test_empty = [&check_nans, &check_empty_flips](
const Rect& a,
1681 ASSERT_FALSE(a.IsEmpty()) << a;
1684 std::stringstream stream;
1685 stream << a <<
" union " <<
b;
1686 auto label = stream.str();
1688 EXPECT_FALSE(a.Intersection(
b).has_value()) << label;
1689 EXPECT_TRUE(a.IntersectionOrEmpty(
b).IsEmpty()) << label;
1690 EXPECT_FALSE(
b.Intersection(a).has_value()) << label;
1691 EXPECT_TRUE(
b.IntersectionOrEmpty(a).IsEmpty()) << label;
1692 check_empty_flips(a,
b, label);
1693 check_nans(a,
b, label);
1715 test_non_empty(a,
b, expected);
1729 test_non_empty(a,
b,
b);
1740 TEST(RectTest, OptRectIntersection) {
1749 auto test1 = [](
const Rect& r) {
1771 auto test2 = [](
const Rect& a,
const Rect&
b,
const Rect& i) {
1794 TEST(RectTest, IRectIntersection) {
1795 auto check_empty_flips = [](
const IRect& a,
const IRect&
b,
1796 const std::string& label) {
1806 EXPECT_FALSE(
flip_lr(a).Intersection(
b).has_value()) << label;
1807 EXPECT_FALSE(
flip_tb(a).Intersection(
b).has_value()) << label;
1808 EXPECT_FALSE(
flip_lrtb(a).Intersection(
b).has_value()) << label;
1811 EXPECT_FALSE(
flip_lr(a).Intersection(
flip_lr(
b)).has_value()) << label;
1812 EXPECT_FALSE(
flip_tb(a).Intersection(
flip_tb(
b)).has_value()) << label;
1816 auto test_non_empty = [&check_empty_flips](
const IRect& a,
const IRect&
b,
1817 const IRect& result) {
1818 ASSERT_FALSE(a.
IsEmpty()) << a;
1821 std::stringstream stream;
1822 stream << a <<
" union " <<
b;
1823 auto label = stream.str();
1826 EXPECT_TRUE(
b.Intersection(a).has_value()) << label;
1828 EXPECT_EQ(
b.Intersection(a), result) << label;
1829 check_empty_flips(a,
b, label);
1832 auto test_empty = [&check_empty_flips](
const IRect& a,
const IRect&
b) {
1833 ASSERT_FALSE(a.
IsEmpty()) << a;
1836 std::stringstream stream;
1837 stream << a <<
" union " <<
b;
1838 auto label = stream.str();
1841 EXPECT_FALSE(
b.Intersection(a).has_value()) << label;
1842 check_empty_flips(a,
b, label);
1864 test_non_empty(a,
b, expected);
1878 test_non_empty(a,
b,
b);
1889 TEST(RectTest, OptIRectIntersection) {
1898 auto test1 = [](
const IRect& r) {
1945 TEST(RectTest, RectIntersectsWithRect) {
1946 auto check_nans = [](
const Rect& a,
const Rect&
b,
const std::string& label) {
1947 ASSERT_TRUE(a.
IsFinite()) << label;
1948 ASSERT_TRUE(
b.IsFinite()) << label;
1950 for (
int i = 1; i < 16; i++) {
1952 EXPECT_FALSE(
swap_nan(a, i).IntersectsWithRect(
b))
1953 << label <<
", index = " << i;
1956 << label <<
", index = " << i;
1958 for (
int j = 1; j < 16; j++) {
1960 << label <<
", indices = " << i <<
", " << j;
1965 auto check_empty_flips = [](
const Rect& a,
const Rect&
b,
1966 const std::string& label) {
1976 EXPECT_FALSE(
flip_lr(a).IntersectsWithRect(
b)) << label;
1977 EXPECT_FALSE(
flip_tb(a).IntersectsWithRect(
b)) << label;
1978 EXPECT_FALSE(
flip_lrtb(a).IntersectsWithRect(
b)) << label;
1986 auto test_non_empty = [&check_nans, &check_empty_flips](
const Rect& a,
1988 ASSERT_FALSE(a.IsEmpty()) << a;
1991 std::stringstream stream;
1992 stream << a <<
" union " <<
b;
1993 auto label = stream.str();
1995 EXPECT_TRUE(a.IntersectsWithRect(
b)) << label;
1996 EXPECT_TRUE(
b.IntersectsWithRect(a)) << label;
1997 check_empty_flips(a,
b, label);
1998 check_nans(a,
b, label);
2001 auto test_empty = [&check_nans, &check_empty_flips](
const Rect& a,
2003 ASSERT_FALSE(a.IsEmpty()) << a;
2006 std::stringstream stream;
2007 stream << a <<
" union " <<
b;
2008 auto label = stream.str();
2010 EXPECT_FALSE(a.IntersectsWithRect(
b)) << label;
2011 EXPECT_FALSE(
b.IntersectsWithRect(a)) << label;
2012 check_empty_flips(a,
b, label);
2013 check_nans(a,
b, label);
2034 test_non_empty(a,
b);
2048 test_non_empty(a,
b);
2055 test_non_empty(a,
b);
2059 TEST(RectTest, IRectIntersectsWithRect) {
2060 auto check_empty_flips = [](
const IRect& a,
const IRect&
b,
2061 const std::string& label) {
2071 EXPECT_FALSE(
flip_lr(a).IntersectsWithRect(
b)) << label;
2072 EXPECT_FALSE(
flip_tb(a).IntersectsWithRect(
b)) << label;
2073 EXPECT_FALSE(
flip_lrtb(a).IntersectsWithRect(
b)) << label;
2081 auto test_non_empty = [&check_empty_flips](
const IRect& a,
const IRect&
b) {
2082 ASSERT_FALSE(a.
IsEmpty()) << a;
2085 std::stringstream stream;
2086 stream << a <<
" union " <<
b;
2087 auto label = stream.str();
2090 EXPECT_TRUE(
b.IntersectsWithRect(a)) << label;
2091 check_empty_flips(a,
b, label);
2094 auto test_empty = [&check_empty_flips](
const IRect& a,
const IRect&
b) {
2095 ASSERT_FALSE(a.
IsEmpty()) << a;
2098 std::stringstream stream;
2099 stream << a <<
" union " <<
b;
2100 auto label = stream.str();
2103 EXPECT_FALSE(
b.IntersectsWithRect(a)) << label;
2104 check_empty_flips(a,
b, label);
2125 test_non_empty(a,
b);
2139 test_non_empty(a,
b);
2146 test_non_empty(a,
b);
2150 TEST(RectTest, RectContainsPoint) {
2151 auto check_nans = [](
const Rect& rect,
const Point& point,
2152 const std::string& label) {
2153 ASSERT_TRUE(rect.
IsFinite()) << label;
2154 ASSERT_TRUE(point.IsFinite()) << label;
2156 for (
int i = 1; i < 16; i++) {
2157 EXPECT_FALSE(
swap_nan(rect, i).Contains(point))
2158 << label <<
", index = " << i;
2159 for (
int j = 1; j < 4; j++) {
2161 << label <<
", indices = " << i <<
", " << j;
2166 auto check_empty_flips = [](
const Rect& rect,
const Point& point,
2167 const std::string& label) {
2170 EXPECT_FALSE(
flip_lr(rect).Contains(point)) << label;
2171 EXPECT_FALSE(
flip_tb(rect).Contains(point)) << label;
2172 EXPECT_FALSE(
flip_lrtb(rect).Contains(point)) << label;
2175 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& rect,
2176 const Point& point) {
2177 ASSERT_FALSE(rect.IsEmpty()) << rect;
2179 std::stringstream stream;
2180 stream << rect <<
" contains " << point;
2181 auto label = stream.str();
2183 EXPECT_TRUE(rect.Contains(point)) << label;
2184 check_empty_flips(rect, point, label);
2185 check_nans(rect, point, label);
2188 auto test_outside = [&check_nans, &check_empty_flips](
const Rect& rect,
2189 const Point& point) {
2190 ASSERT_FALSE(rect.IsEmpty()) << rect;
2192 std::stringstream stream;
2193 stream << rect <<
" contains " << point;
2194 auto label = stream.str();
2196 EXPECT_FALSE(rect.Contains(point)) << label;
2197 check_empty_flips(rect, point, label);
2198 check_nans(rect, point, label);
2204 auto p =
Point(100, 100);
2211 auto p =
Point(200, 200);
2217 auto p =
Point(99, 99);
2223 auto p =
Point(199, 199);
2230 auto p =
Point(199, 199);
2236 TEST(RectTest, IRectContainsIPoint) {
2237 auto check_empty_flips = [](
const IRect& rect,
const IPoint& point,
2238 const std::string& label) {
2241 EXPECT_FALSE(
flip_lr(rect).Contains(point)) << label;
2242 EXPECT_FALSE(
flip_tb(rect).Contains(point)) << label;
2243 EXPECT_FALSE(
flip_lrtb(rect).Contains(point)) << label;
2246 auto test_inside = [&check_empty_flips](
const IRect& rect,
2248 ASSERT_FALSE(rect.
IsEmpty()) << rect;
2250 std::stringstream stream;
2251 stream << rect <<
" contains " << point;
2252 auto label = stream.str();
2254 EXPECT_TRUE(rect.
Contains(point)) << label;
2255 check_empty_flips(rect, point, label);
2258 auto test_outside = [&check_empty_flips](
const IRect& rect,
2260 ASSERT_FALSE(rect.
IsEmpty()) << rect;
2262 std::stringstream stream;
2263 stream << rect <<
" contains " << point;
2264 auto label = stream.str();
2266 EXPECT_FALSE(rect.
Contains(point)) << label;
2267 check_empty_flips(rect, point, label);
2273 auto p =
IPoint(100, 100);
2280 auto p =
IPoint(200, 200);
2292 auto p =
IPoint(199, 199);
2299 auto p =
IPoint(199, 199);
2305 TEST(RectTest, RectContainsInclusivePoint) {
2306 auto check_nans = [](
const Rect& rect,
const Point& point,
2307 const std::string& label) {
2308 ASSERT_TRUE(rect.
IsFinite()) << label;
2309 ASSERT_TRUE(point.IsFinite()) << label;
2311 for (
int i = 1; i < 16; i++) {
2312 EXPECT_FALSE(
swap_nan(rect, i).ContainsInclusive(point))
2313 << label <<
", index = " << i;
2314 for (
int j = 1; j < 4; j++) {
2316 << label <<
", indices = " << i <<
", " << j;
2321 auto check_empty_flips = [](
const Rect& rect,
const Point& point,
2322 const std::string& label) {
2325 EXPECT_FALSE(
flip_lr(rect).ContainsInclusive(point)) << label;
2326 EXPECT_FALSE(
flip_tb(rect).ContainsInclusive(point)) << label;
2327 EXPECT_FALSE(
flip_lrtb(rect).ContainsInclusive(point)) << label;
2330 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& rect,
2331 const Point& point) {
2332 ASSERT_FALSE(rect.IsEmpty()) << rect;
2334 std::stringstream stream;
2335 stream << rect <<
" contains " << point;
2336 auto label = stream.str();
2338 EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2339 check_empty_flips(rect, point, label);
2340 check_nans(rect, point, label);
2343 auto test_outside = [&check_nans, &check_empty_flips](
const Rect& rect,
2344 const Point& point) {
2345 ASSERT_FALSE(rect.IsEmpty()) << rect;
2347 std::stringstream stream;
2348 stream << rect <<
" contains " << point;
2349 auto label = stream.str();
2351 EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2352 check_empty_flips(rect, point, label);
2353 check_nans(rect, point, label);
2359 auto p =
Point(100, 100);
2366 auto p =
Point(200, 200);
2379 auto p =
Point(99, 99);
2385 auto p =
Point(199, 199);
2392 auto p =
Point(199, 199);
2398 TEST(RectTest, IRectContainsInclusiveIPoint) {
2399 auto check_empty_flips = [](
const IRect& rect,
const IPoint& point,
2400 const std::string& label) {
2403 EXPECT_FALSE(
flip_lr(rect).ContainsInclusive(point)) << label;
2404 EXPECT_FALSE(
flip_tb(rect).ContainsInclusive(point)) << label;
2405 EXPECT_FALSE(
flip_lrtb(rect).ContainsInclusive(point)) << label;
2408 auto test_inside = [&check_empty_flips](
const IRect& rect,
2410 ASSERT_FALSE(rect.
IsEmpty()) << rect;
2412 std::stringstream stream;
2413 stream << rect <<
" contains " << point;
2414 auto label = stream.str();
2417 check_empty_flips(rect, point, label);
2420 auto test_outside = [&check_empty_flips](
const IRect& rect,
2422 ASSERT_FALSE(rect.
IsEmpty()) << rect;
2424 std::stringstream stream;
2425 stream << rect <<
" contains " << point;
2426 auto label = stream.str();
2429 check_empty_flips(rect, point, label);
2435 auto p =
IPoint(100, 100);
2442 auto p =
IPoint(200, 200);
2449 auto p =
IPoint(201, 201);
2461 auto p =
IPoint(199, 199);
2468 auto p =
IPoint(199, 199);
2475 auto check_nans = [](
const Rect& a,
const Rect&
b,
const std::string& label) {
2476 ASSERT_TRUE(a.
IsFinite()) << label;
2477 ASSERT_TRUE(
b.IsFinite()) << label;
2480 for (
int i = 1; i < 16; i++) {
2482 EXPECT_FALSE(
swap_nan(a, i).Contains(
b)) << label <<
", index = " << i;
2486 for (
int j = 1; j < 16; j++) {
2488 << label <<
", indices = " << i <<
", " << j;
2493 auto check_empty_flips = [](
const Rect& a,
const Rect&
b,
2494 const std::string& label) {
2497 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2505 EXPECT_FALSE(
flip_lr(a).Contains(
b)) << label;
2506 EXPECT_FALSE(
flip_tb(a).Contains(
b)) << label;
2507 EXPECT_FALSE(
flip_lrtb(a).Contains(
b)) << label;
2515 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& a,
2517 ASSERT_FALSE(a.IsEmpty()) << a;
2519 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2521 std::stringstream stream;
2522 stream << a <<
" contains " <<
b;
2523 auto label = stream.str();
2525 EXPECT_TRUE(a.Contains(
b)) << label;
2526 check_empty_flips(a,
b, label);
2527 check_nans(a,
b, label);
2530 auto test_not_inside = [&check_nans, &check_empty_flips](
const Rect& a,
2532 ASSERT_FALSE(a.IsEmpty()) << a;
2535 ASSERT_FALSE(
b.IsEmpty()) <<
b;
2537 std::stringstream stream;
2538 stream << a <<
" contains " <<
b;
2539 auto label = stream.str();
2541 EXPECT_FALSE(a.Contains(
b)) << label;
2542 check_empty_flips(a,
b, label);
2543 check_nans(a,
b, label);
2567 test_not_inside(a,
b);
2573 test_not_inside(a,
b);
2579 test_not_inside(a,
b);
2589 TEST(RectTest, IRectContainsIRect) {
2590 auto check_empty_flips = [](
const IRect& a,
const IRect&
b,
2591 const std::string& label) {
2594 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2602 EXPECT_FALSE(
flip_lr(a).Contains(
b)) << label;
2603 EXPECT_FALSE(
flip_tb(a).Contains(
b)) << label;
2604 EXPECT_FALSE(
flip_lrtb(a).Contains(
b)) << label;
2612 auto test_inside = [&check_empty_flips](
const IRect& a,
const IRect&
b) {
2613 ASSERT_FALSE(a.
IsEmpty()) << a;
2615 ASSERT_FALSE(
b.GetLeft() >
b.GetRight() ||
b.GetTop() >
b.GetBottom());
2617 std::stringstream stream;
2618 stream << a <<
" contains " <<
b;
2619 auto label = stream.str();
2622 check_empty_flips(a,
b, label);
2625 auto test_not_inside = [&check_empty_flips](
const IRect& a,
const IRect&
b) {
2626 ASSERT_FALSE(a.
IsEmpty()) << a;
2629 ASSERT_FALSE(
b.IsEmpty()) <<
b;
2631 std::stringstream stream;
2632 stream << a <<
" contains " <<
b;
2633 auto label = stream.str();
2636 check_empty_flips(a,
b, label);
2660 test_not_inside(a,
b);
2666 test_not_inside(a,
b);
2672 test_not_inside(a,
b);
2685 auto check_nans = [&cull_rect](
const Rect& diff_rect,
2686 const std::string& label) {
2687 EXPECT_TRUE(cull_rect.
IsFinite()) << label;
2688 EXPECT_TRUE(diff_rect.
IsFinite()) << label;
2690 for (
int i = 1; i < 16; i++) {
2692 EXPECT_FALSE(
swap_nan(cull_rect, i).Cutout(diff_rect).has_value())
2693 << label <<
", index " << i;
2694 EXPECT_EQ(
swap_nan(cull_rect, i).CutoutOrEmpty(diff_rect),
Rect())
2695 << label <<
", index " << i;
2698 EXPECT_TRUE(cull_rect.
Cutout(
swap_nan(diff_rect, i)).has_value())
2699 << label <<
", index " << i;
2701 << label <<
", index " << i;
2703 for (
int j = 1; j < 16; j++) {
2707 << label <<
", indices " << i <<
", " << j;
2710 << label <<
", indices " << i <<
", " << j;
2715 auto check_empty_flips = [&cull_rect](
const Rect& diff_rect,
2716 const std::string& label) {
2717 EXPECT_FALSE(cull_rect.
IsEmpty()) << label;
2718 EXPECT_FALSE(diff_rect.
IsEmpty()) << label;
2722 EXPECT_TRUE(cull_rect.
Cutout(
flip_lr(diff_rect)).has_value()) << label;
2723 EXPECT_EQ(cull_rect.
Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2724 EXPECT_TRUE(cull_rect.
Cutout(
flip_tb(diff_rect)).has_value()) << label;
2725 EXPECT_EQ(cull_rect.
Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2726 EXPECT_TRUE(cull_rect.
Cutout(
flip_lrtb(diff_rect)).has_value()) << label;
2727 EXPECT_EQ(cull_rect.
Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2731 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2732 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2733 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2734 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2735 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2736 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2740 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
2744 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
2754 auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2755 const Rect& diff_rect,
const std::string& label) {
2756 EXPECT_EQ(cull_rect.
Cutout(diff_rect), cull_rect) << label;
2757 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), cull_rect) << label;
2758 check_empty_flips(diff_rect, label);
2759 check_nans(diff_rect, label);
2762 auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2763 const Rect& diff_rect,
const Rect& result_rect,
2764 const std::string& label) {
2765 EXPECT_TRUE(!result_rect.IsEmpty());
2766 EXPECT_EQ(cull_rect.
Cutout(diff_rect), result_rect) << label;
2767 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), result_rect) << label;
2768 check_empty_flips(diff_rect, label);
2769 check_nans(diff_rect, label);
2772 auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2773 const Rect& diff_rect,
const std::string& label) {
2774 EXPECT_FALSE(cull_rect.
Cutout(diff_rect).has_value()) << label;
2776 check_empty_flips(diff_rect, label);
2777 check_nans(diff_rect, label);
2781 non_reducing(
Rect::MakeLTRB(10, 10, 20, 20),
"outside UL corner");
2783 non_reducing(
Rect::MakeLTRB(40, 10, 50, 20),
"outside UR corner");
2785 non_reducing(
Rect::MakeLTRB(40, 40, 50, 50),
"outside LR corner");
2787 non_reducing(
Rect::MakeLTRB(10, 40, 20, 50),
"outside LR corner");
2791 non_reducing(
Rect::MakeLTRB(15, 15, 25, 25),
"covering UL corner");
2792 non_reducing(
Rect::MakeLTRB(35, 15, 45, 25),
"covering UR corner");
2793 non_reducing(
Rect::MakeLTRB(35, 35, 45, 45),
"covering LR corner");
2794 non_reducing(
Rect::MakeLTRB(15, 35, 25, 45),
"covering LL corner");
2797 non_reducing(
Rect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
2798 non_reducing(
Rect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
2799 non_reducing(
Rect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
2800 non_reducing(
Rect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
2801 non_reducing(
Rect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
2802 non_reducing(
Rect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
2803 non_reducing(
Rect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
2804 non_reducing(
Rect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
2807 non_reducing(
Rect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
2808 non_reducing(
Rect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
2819 "Slice off bottom");
2825 non_reducing(
Rect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
2828 emptying(cull_rect,
"Perfectly covering");
2837 auto check_empty_flips = [&cull_rect](
const IRect& diff_rect,
2838 const std::string& label) {
2839 EXPECT_FALSE(diff_rect.
IsEmpty());
2840 EXPECT_FALSE(cull_rect.
IsEmpty());
2844 EXPECT_TRUE(cull_rect.
Cutout(
flip_lr(diff_rect)).has_value()) << label;
2845 EXPECT_EQ(cull_rect.
Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2846 EXPECT_TRUE(cull_rect.
Cutout(
flip_tb(diff_rect)).has_value()) << label;
2847 EXPECT_EQ(cull_rect.
Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2848 EXPECT_TRUE(cull_rect.
Cutout(
flip_lrtb(diff_rect)).has_value()) << label;
2849 EXPECT_EQ(cull_rect.
Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2853 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2854 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2855 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2856 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2857 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2858 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2862 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
2866 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
2876 auto non_reducing = [&cull_rect, &check_empty_flips](
2877 const IRect& diff_rect,
const std::string& label) {
2878 EXPECT_EQ(cull_rect.
Cutout(diff_rect), cull_rect) << label;
2879 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), cull_rect) << label;
2880 check_empty_flips(diff_rect, label);
2883 auto reducing = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
2884 const IRect& result_rect,
2885 const std::string& label) {
2886 EXPECT_TRUE(!result_rect.IsEmpty());
2887 EXPECT_EQ(cull_rect.
Cutout(diff_rect), result_rect) << label;
2888 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), result_rect) << label;
2889 check_empty_flips(diff_rect, label);
2892 auto emptying = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
2893 const std::string& label) {
2894 EXPECT_FALSE(cull_rect.
Cutout(diff_rect).has_value()) << label;
2896 check_empty_flips(diff_rect, label);
2916 non_reducing(
IRect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
2917 non_reducing(
IRect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
2918 non_reducing(
IRect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
2919 non_reducing(
IRect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
2920 non_reducing(
IRect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
2921 non_reducing(
IRect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
2922 non_reducing(
IRect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
2923 non_reducing(
IRect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
2926 non_reducing(
IRect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
2927 non_reducing(
IRect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
2938 "Slice off bottom");
2944 non_reducing(
IRect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
2947 emptying(cull_rect,
"Perfectly covering");
2966 EXPECT_EQ(points[0],
Point(std::numeric_limits<float>::lowest(),
2967 std::numeric_limits<float>::lowest()));
2968 EXPECT_EQ(points[1],
Point(std::numeric_limits<float>::max(),
2969 std::numeric_limits<float>::lowest()));
2970 EXPECT_EQ(points[2],
Point(std::numeric_limits<float>::lowest(),
2971 std::numeric_limits<float>::max()));
2972 EXPECT_EQ(points[3],
Point(std::numeric_limits<float>::max(),
2973 std::numeric_limits<float>::max()));
2984 TEST(RectTest, RectGetTransformedPoints) {
2993 TEST(RectTest, RectMakePointBounds) {
2995 std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
2998 EXPECT_TRUE(r.has_value());
2999 if (r.has_value()) {
3004 std::vector<Point> points;
3006 EXPECT_FALSE(r.has_value());
3027 EXPECT_EQ(r.GetLeft(), 1);
3028 EXPECT_EQ(r.GetTop(), 2);
3029 EXPECT_EQ(r.GetRight(), 3);
3030 EXPECT_EQ(r.GetBottom(), 4);
3041 auto actual = r.Project(r);
3110 TEST(RectTest, TransformAndClipBounds) {
3115 2.0f, 0.0f, 0.0f, 0.0f,
3116 0.0f, 4.0f, 0.0f, 0.0f,
3117 0.0f, 0.0f, 1.0f, 0.0f,
3118 0.0f, 0.0f, 0.0f, 8.0f
3123 EXPECT_EQ(matrix.TransformHomogenous(src.
GetLeftTop()),
3124 Vector3(200.0f, 400.0f, 8.0f));
3125 EXPECT_EQ(matrix.TransformHomogenous(src.
GetRightTop()),
3126 Vector3(400.0f, 400.0f, 8.0f));
3128 Vector3(200.0f, 800.0f, 8.0f));
3130 Vector3(400.0f, 800.0f, 8.0f));
3141 2.0f, 0.0f, 0.0f, -0.01f,
3142 0.0f, 2.0f, 0.0f, -0.006f,
3143 0.0f, 0.0f, 1.0f, 0.0f,
3144 0.0f, 0.0f, 0.0f, 3.0f
3150 Vector3(200.0f, 200.0f, 1.4f));
3152 Vector3(400.0f, 200.0f, 0.4f));
3154 Vector3(200.0f, 400.0f, 0.8f));
3156 Vector3(400.0f, 400.0f, -0.2f));
3167 2.0f, 0.0f, 0.0f, -.015f,
3168 0.0f, 2.0f, 0.0f, -.006f,
3169 0.0f, 0.0f, 1.0f, 0.0f,
3170 0.0f, 0.0f, 0.0f, 3.0f
3176 Vector3(200.0f, 200.0f, 0.9f));
3178 Vector3(400.0f, 200.0f, -0.6f));
3180 Vector3(200.0f, 400.0f, 0.3f));
3182 Vector3(400.0f, 400.0f, -1.2f));
3193 2.0f, 0.0f, 0.0f, -.02f,
3194 0.0f, 2.0f, 0.0f, -.006f,
3195 0.0f, 0.0f, 1.0f, 0.0f,
3196 0.0f, 0.0f, 0.0f, 3.0f
3202 Vector3(200.0f, 200.0f, 0.4f));
3204 Vector3(400.0f, 200.0f, -1.6f));
3206 Vector3(200.0f, 400.0f, -0.2f));
3208 Vector3(400.0f, 400.0f, -2.2f));
3219 2.0f, 0.0f, 0.0f, -.025f,
3220 0.0f, 2.0f, 0.0f, -.006f,
3221 0.0f, 0.0f, 1.0f, 0.0f,
3222 0.0f, 0.0f, 0.0f, 3.0f
3228 Vector3(200.0f, 200.0f, -0.1f));
3230 Vector3(400.0f, 200.0f, -2.6f));
3232 Vector3(200.0f, 400.0f, -0.7f));
3234 Vector3(400.0f, 400.0f, -3.2f));