302TEST(RectTest, RectOverflowXYWH) {
303 auto min = std::numeric_limits<Scalar>::lowest();
304 auto max = std::numeric_limits<Scalar>::max();
305 auto inf = std::numeric_limits<Scalar>::infinity();
323 EXPECT_EQ(rect.GetLeft(), 5.0f);
324 EXPECT_EQ(rect.GetTop(), 10.0f);
325 EXPECT_EQ(rect.GetRight(), max);
326 EXPECT_EQ(rect.GetBottom(), 25.0f);
327 EXPECT_EQ(rect.GetX(), 5.0f);
328 EXPECT_EQ(rect.GetY(), 10.0f);
329 EXPECT_EQ(rect.GetWidth(), max);
330 EXPECT_EQ(rect.GetHeight(), 15.0f);
331 EXPECT_FALSE(rect.IsEmpty());
332 EXPECT_TRUE(rect.IsFinite());
338 EXPECT_EQ(rect.GetLeft(), max);
339 EXPECT_EQ(rect.GetTop(), 10.0f);
340 EXPECT_EQ(rect.GetRight(), inf);
341 EXPECT_EQ(rect.GetBottom(), 25.0f);
342 EXPECT_EQ(rect.GetX(), max);
343 EXPECT_EQ(rect.GetY(), 10.0f);
344 EXPECT_EQ(rect.GetWidth(), inf);
345 EXPECT_EQ(rect.GetHeight(), 15.0f);
346 EXPECT_FALSE(rect.IsEmpty());
347 EXPECT_FALSE(rect.IsFinite());
353 EXPECT_EQ(rect.GetLeft(), 5.0f);
354 EXPECT_EQ(rect.GetTop(), 10.0f);
355 EXPECT_EQ(rect.GetRight(), 25.0f);
356 EXPECT_EQ(rect.GetBottom(), max);
357 EXPECT_EQ(rect.GetX(), 5.0f);
358 EXPECT_EQ(rect.GetY(), 10.0f);
359 EXPECT_EQ(rect.GetWidth(), 20.0f);
360 EXPECT_EQ(rect.GetHeight(), max);
361 EXPECT_FALSE(rect.IsEmpty());
362 EXPECT_TRUE(rect.IsFinite());
368 EXPECT_EQ(rect.GetLeft(), 5.0f);
369 EXPECT_EQ(rect.GetTop(), max);
370 EXPECT_EQ(rect.GetRight(), 25.0f);
371 EXPECT_EQ(rect.GetBottom(), inf);
372 EXPECT_EQ(rect.GetX(), 5.0f);
373 EXPECT_EQ(rect.GetY(), max);
374 EXPECT_EQ(rect.GetWidth(), 20.0f);
375 EXPECT_EQ(rect.GetHeight(), inf);
376 EXPECT_FALSE(rect.IsEmpty());
377 EXPECT_FALSE(rect.IsFinite());
383 EXPECT_EQ(rect.GetLeft(), 5.0f);
384 EXPECT_EQ(rect.GetTop(), 10.0f);
385 EXPECT_EQ(rect.GetRight(), min);
386 EXPECT_EQ(rect.GetBottom(), 25.0f);
387 EXPECT_EQ(rect.GetX(), 5.0f);
388 EXPECT_EQ(rect.GetY(), 10.0f);
389 EXPECT_EQ(rect.GetWidth(), min);
390 EXPECT_EQ(rect.GetHeight(), 15.0f);
391 EXPECT_TRUE(rect.IsEmpty());
392 EXPECT_TRUE(rect.IsFinite());
398 EXPECT_EQ(rect.GetLeft(), min);
399 EXPECT_EQ(rect.GetTop(), 10.0f);
400 EXPECT_EQ(rect.GetRight(), -inf);
401 EXPECT_EQ(rect.GetBottom(), 25.0f);
402 EXPECT_EQ(rect.GetX(), min);
403 EXPECT_EQ(rect.GetY(), 10.0f);
404 EXPECT_EQ(rect.GetWidth(), -inf);
405 EXPECT_EQ(rect.GetHeight(), 15.0f);
406 EXPECT_TRUE(rect.IsEmpty());
407 EXPECT_FALSE(rect.IsFinite());
413 EXPECT_EQ(rect.GetLeft(), 5.0f);
414 EXPECT_EQ(rect.GetTop(), 10.0f);
415 EXPECT_EQ(rect.GetRight(), 25.0f);
416 EXPECT_EQ(rect.GetBottom(), min);
417 EXPECT_EQ(rect.GetX(), 5.0f);
418 EXPECT_EQ(rect.GetY(), 10.0f);
419 EXPECT_EQ(rect.GetWidth(), 20.0f);
420 EXPECT_EQ(rect.GetHeight(), min);
421 EXPECT_TRUE(rect.IsEmpty());
422 EXPECT_TRUE(rect.IsFinite());
428 EXPECT_EQ(rect.GetLeft(), 5.0f);
429 EXPECT_EQ(rect.GetTop(), min);
430 EXPECT_EQ(rect.GetRight(), 25.0f);
431 EXPECT_EQ(rect.GetBottom(), -inf);
432 EXPECT_EQ(rect.GetX(), 5.0f);
433 EXPECT_EQ(rect.GetY(), min);
434 EXPECT_EQ(rect.GetWidth(), 20.0f);
435 EXPECT_EQ(rect.GetHeight(), -inf);
436 EXPECT_TRUE(rect.IsEmpty());
437 EXPECT_FALSE(rect.IsFinite());
508TEST(RectTest, RectOverflowLTRB) {
509 auto min = std::numeric_limits<Scalar>::lowest();
510 auto max = std::numeric_limits<Scalar>::max();
511 auto inf = std::numeric_limits<Scalar>::infinity();
529 EXPECT_EQ(rect.GetLeft(), -5.0f);
530 EXPECT_EQ(rect.GetTop(), 10.0f);
531 EXPECT_EQ(rect.GetRight(), max);
532 EXPECT_EQ(rect.GetBottom(), 25.0f);
533 EXPECT_EQ(rect.GetX(), -5.0f);
534 EXPECT_EQ(rect.GetY(), 10.0f);
535 EXPECT_EQ(rect.GetWidth(), max);
536 EXPECT_EQ(rect.GetHeight(), 15.0f);
537 EXPECT_FALSE(rect.IsEmpty());
538 EXPECT_TRUE(rect.IsFinite());
544 EXPECT_EQ(rect.GetLeft(), min + 5.0f);
545 EXPECT_EQ(rect.GetTop(), 10.0f);
546 EXPECT_EQ(rect.GetRight(), max - 5.0f);
547 EXPECT_EQ(rect.GetBottom(), 25.0f);
548 EXPECT_EQ(rect.GetX(), min + 5.0f);
549 EXPECT_EQ(rect.GetY(), 10.0f);
550 EXPECT_EQ(rect.GetWidth(), inf);
551 EXPECT_EQ(rect.GetHeight(), 15.0f);
552 EXPECT_FALSE(rect.IsEmpty());
553 EXPECT_TRUE(rect.IsFinite());
559 EXPECT_EQ(rect.GetLeft(), 5.0f);
560 EXPECT_EQ(rect.GetTop(), -10.0f);
561 EXPECT_EQ(rect.GetRight(), 20.0f);
562 EXPECT_EQ(rect.GetBottom(), max);
563 EXPECT_EQ(rect.GetX(), 5.0f);
564 EXPECT_EQ(rect.GetY(), -10.0f);
565 EXPECT_EQ(rect.GetWidth(), 15.0f);
566 EXPECT_EQ(rect.GetHeight(), max);
567 EXPECT_FALSE(rect.IsEmpty());
568 EXPECT_TRUE(rect.IsFinite());
574 EXPECT_EQ(rect.GetLeft(), 5.0f);
575 EXPECT_EQ(rect.GetTop(), min + 10.0f);
576 EXPECT_EQ(rect.GetRight(), 20.0f);
577 EXPECT_EQ(rect.GetBottom(), max - 15.0f);
578 EXPECT_EQ(rect.GetX(), 5.0f);
579 EXPECT_EQ(rect.GetY(), min + 10.0f);
580 EXPECT_EQ(rect.GetWidth(), 15.0f);
581 EXPECT_EQ(rect.GetHeight(), inf);
582 EXPECT_FALSE(rect.IsEmpty());
583 EXPECT_TRUE(rect.IsFinite());
589 EXPECT_EQ(rect.GetLeft(), 5.0f);
590 EXPECT_EQ(rect.GetTop(), 10.0f);
591 EXPECT_EQ(rect.GetRight(), min);
592 EXPECT_EQ(rect.GetBottom(), 25.0f);
593 EXPECT_EQ(rect.GetX(), 5.0f);
594 EXPECT_EQ(rect.GetY(), 10.0f);
595 EXPECT_EQ(rect.GetWidth(), min);
596 EXPECT_EQ(rect.GetHeight(), 15.0f);
597 EXPECT_TRUE(rect.IsEmpty());
598 EXPECT_TRUE(rect.IsFinite());
604 EXPECT_EQ(rect.GetLeft(), max - 5.0f);
605 EXPECT_EQ(rect.GetTop(), 10.0f);
606 EXPECT_EQ(rect.GetRight(), min + 10.0f);
607 EXPECT_EQ(rect.GetBottom(), 25.0f);
608 EXPECT_EQ(rect.GetX(), max - 5.0f);
609 EXPECT_EQ(rect.GetY(), 10.0f);
610 EXPECT_EQ(rect.GetWidth(), -inf);
611 EXPECT_EQ(rect.GetHeight(), 15.0f);
612 EXPECT_TRUE(rect.IsEmpty());
613 EXPECT_TRUE(rect.IsFinite());
619 EXPECT_EQ(rect.GetLeft(), 5.0f);
620 EXPECT_EQ(rect.GetTop(), 10.0f);
621 EXPECT_EQ(rect.GetRight(), 20.0f);
622 EXPECT_EQ(rect.GetBottom(), min);
623 EXPECT_EQ(rect.GetX(), 5.0f);
624 EXPECT_EQ(rect.GetY(), 10.0f);
625 EXPECT_EQ(rect.GetWidth(), 15.0f);
626 EXPECT_EQ(rect.GetHeight(), min);
627 EXPECT_TRUE(rect.IsEmpty());
628 EXPECT_TRUE(rect.IsFinite());
634 EXPECT_EQ(rect.GetLeft(), 5.0f);
635 EXPECT_EQ(rect.GetTop(), max - 5.0f);
636 EXPECT_EQ(rect.GetRight(), 20.0f);
637 EXPECT_EQ(rect.GetBottom(), min + 10.0f);
638 EXPECT_EQ(rect.GetX(), 5.0f);
639 EXPECT_EQ(rect.GetY(), max - 5.0f);
640 EXPECT_EQ(rect.GetWidth(), 15.0f);
641 EXPECT_EQ(rect.GetHeight(), -inf);
642 EXPECT_TRUE(rect.IsEmpty());
643 EXPECT_TRUE(rect.IsFinite());
1056 rect.GetY() * scale,
1057 rect.GetWidth() * scale,
1058 rect.GetHeight() * scale);
1061 << rect <<
" * " << scale;
1063 << rect <<
" * " << scale;
1065 << rect <<
" * " << scale;
1067 << rect <<
" * " << scale;
1072 rect.GetY() * scale_y,
1073 rect.GetWidth() * scale_x,
1074 rect.GetHeight() * scale_y);
1077 << rect <<
" * " << scale_x <<
", " << scale_y;
1079 << rect <<
" * " << scale_x <<
", " << scale_y;
1081 << rect <<
" * " << scale_x <<
", " << scale_y;
1083 test1(rect, scale_x);
1084 test1(rect, scale_y);
1099 auto test1 = [](
IRect rect, int64_t scale) {
1101 rect.
GetY() * scale,
1105 EXPECT_EQ(rect.
Scale(scale), expected)
1106 << rect <<
" * " << scale;
1107 EXPECT_EQ(rect.
Scale(scale, scale), expected)
1108 << rect <<
" * " << scale;
1109 EXPECT_EQ(rect.
Scale(
IPoint(scale, scale)), expected)
1110 << rect <<
" * " << scale;
1111 EXPECT_EQ(rect.
Scale(
ISize(scale, scale)), expected)
1112 << rect <<
" * " << scale;
1115 auto test2 = [&test1](
IRect rect, int64_t scale_x, int64_t scale_y) {
1117 rect.
GetY() * scale_y,
1121 EXPECT_EQ(rect.
Scale(scale_x, scale_y), expected)
1122 << rect <<
" * " << scale_x <<
", " << scale_y;
1123 EXPECT_EQ(rect.
Scale(
IPoint(scale_x, scale_y)), expected)
1124 << rect <<
" * " << scale_x <<
", " << scale_y;
1125 EXPECT_EQ(rect.
Scale(
ISize(scale_x, scale_y)), expected)
1126 << rect <<
" * " << scale_x <<
", " << scale_y;
1128 test1(rect, scale_x);
1129 test1(rect, scale_y);
1158TEST(RectTest, RectGetNormalizingTransform) {
1164 EXPECT_EQ(r.GetNormalizingTransform(),
1173 auto m = r.GetNormalizingTransform();
1182 EXPECT_EQ(m *
Point(350, 600),
Point(0.5, 0.5));
1185 EXPECT_EQ(m *
Point(200, 300),
Point(-1, -1));
1186 EXPECT_EQ(m *
Point(500, 300),
Point(2, -1));
1188 EXPECT_EQ(m *
Point(200, 900),
Point(-1, 2));
1197 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1198 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1199 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1202 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1203 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1204 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1211 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1212 auto inf = std::numeric_limits<Scalar>::infinity();
1215 EXPECT_EQ(
Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1216 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1217 EXPECT_EQ(
Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1220 EXPECT_EQ(
Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1221 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1222 EXPECT_EQ(
Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1225 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1226 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1227 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1230 EXPECT_EQ(
Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1231 EXPECT_EQ(
Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1232 EXPECT_EQ(
Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1235 EXPECT_EQ(
Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1236 EXPECT_EQ(
Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1237 EXPECT_EQ(
Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1240 EXPECT_EQ(
Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1241 EXPECT_EQ(
Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1242 EXPECT_EQ(
Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1297 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1754 auto check_nans = [](
const Rect& a,
const Rect& b,
const std::string& label) {
1755 ASSERT_TRUE(a.IsFinite()) << label;
1756 ASSERT_TRUE(b.IsFinite()) << label;
1758 for (
int i = 1;
i < 16;
i++) {
1760 EXPECT_FALSE(
swap_nan(a,
i).Intersection(b).has_value())
1761 << label <<
", index = " <<
i;
1763 EXPECT_FALSE(a.Intersection(
swap_nan(b,
i)).has_value())
1764 << label <<
", index = " <<
i;
1766 for (
int j = 1; j < 16; j++) {
1768 << label <<
", indices = " <<
i <<
", " << j;
1773 auto check_empty_flips = [](
const Rect& a,
const Rect& b,
1774 const std::string& label) {
1775 ASSERT_FALSE(a.IsEmpty());
1779 EXPECT_FALSE(a.Intersection(
flip_lr(b)).has_value()) << label;
1780 EXPECT_TRUE(a.IntersectionOrEmpty(
flip_lr(b)).IsEmpty()) << label;
1781 EXPECT_FALSE(a.Intersection(
flip_tb(b)).has_value()) << label;
1782 EXPECT_TRUE(a.IntersectionOrEmpty(
flip_tb(b)).IsEmpty()) << label;
1783 EXPECT_FALSE(a.Intersection(
flip_lrtb(b)).has_value()) << label;
1784 EXPECT_TRUE(a.IntersectionOrEmpty(
flip_lrtb(b)).IsEmpty()) << label;
1787 EXPECT_FALSE(
flip_lr(a).Intersection(b).has_value()) << label;
1788 EXPECT_TRUE(
flip_lr(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1789 EXPECT_FALSE(
flip_tb(a).Intersection(b).has_value()) << label;
1790 EXPECT_TRUE(
flip_tb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1791 EXPECT_FALSE(
flip_lrtb(a).Intersection(b).has_value()) << label;
1792 EXPECT_TRUE(
flip_lrtb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1795 EXPECT_FALSE(
flip_lr(a).Intersection(
flip_lr(b)).has_value()) << label;
1796 EXPECT_TRUE(
flip_lr(a).IntersectionOrEmpty(
flip_lr(b)).IsEmpty()) << label;
1797 EXPECT_FALSE(
flip_tb(a).Intersection(
flip_tb(b)).has_value()) << label;
1798 EXPECT_TRUE(
flip_tb(a).IntersectionOrEmpty(
flip_tb(b)).IsEmpty()) << label;
1804 auto test_non_empty = [&check_nans, &check_empty_flips](
1806 ASSERT_FALSE(a.IsEmpty()) << a;
1809 std::stringstream stream;
1810 stream << a <<
" union " << b;
1811 auto label = stream.str();
1813 EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1814 EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1815 EXPECT_EQ(a.Intersection(b), result) << label;
1816 EXPECT_EQ(b.Intersection(a), result) << label;
1817 check_empty_flips(a, b, label);
1818 check_nans(a, b, label);
1821 auto test_empty = [&check_nans, &check_empty_flips](
const Rect& a,
1823 ASSERT_FALSE(a.IsEmpty()) << a;
1826 std::stringstream stream;
1827 stream << a <<
" union " << b;
1828 auto label = stream.str();
1830 EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1831 EXPECT_TRUE(a.IntersectionOrEmpty(b).IsEmpty()) << label;
1832 EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1833 EXPECT_TRUE(b.IntersectionOrEmpty(a).IsEmpty()) << label;
1834 check_empty_flips(a, b, label);
1835 check_nans(a, b, label);
1857 test_non_empty(a, b, expected);
1871 test_non_empty(a, b, b);
2087TEST(RectTest, RectIntersectsWithRect) {
2088 auto check_nans = [](
const Rect& a,
const Rect& b,
const std::string& label) {
2089 ASSERT_TRUE(a.IsFinite()) << label;
2090 ASSERT_TRUE(b.IsFinite()) << label;
2092 for (
int i = 1;
i < 16;
i++) {
2094 EXPECT_FALSE(
swap_nan(a,
i).IntersectsWithRect(b))
2095 << label <<
", index = " <<
i;
2097 EXPECT_FALSE(a.IntersectsWithRect(
swap_nan(b,
i)))
2098 << label <<
", index = " <<
i;
2100 for (
int j = 1; j < 16; j++) {
2102 << label <<
", indices = " <<
i <<
", " << j;
2107 auto check_empty_flips = [](
const Rect& a,
const Rect& b,
2108 const std::string& label) {
2109 ASSERT_FALSE(a.IsEmpty());
2113 EXPECT_FALSE(a.IntersectsWithRect(
flip_lr(b))) << label;
2114 EXPECT_FALSE(a.IntersectsWithRect(
flip_tb(b))) << label;
2115 EXPECT_FALSE(a.IntersectsWithRect(
flip_lrtb(b))) << label;
2118 EXPECT_FALSE(
flip_lr(a).IntersectsWithRect(b)) << label;
2119 EXPECT_FALSE(
flip_tb(a).IntersectsWithRect(b)) << label;
2120 EXPECT_FALSE(
flip_lrtb(a).IntersectsWithRect(b)) << label;
2123 EXPECT_FALSE(
flip_lr(a).IntersectsWithRect(
flip_lr(b))) << label;
2124 EXPECT_FALSE(
flip_tb(a).IntersectsWithRect(
flip_tb(b))) << label;
2128 auto test_non_empty = [&check_nans, &check_empty_flips](
const Rect& a,
2130 ASSERT_FALSE(a.IsEmpty()) << a;
2133 std::stringstream stream;
2134 stream << a <<
" union " << b;
2135 auto label = stream.str();
2137 EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
2138 EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
2139 check_empty_flips(a, b, label);
2140 check_nans(a, b, label);
2143 auto test_empty = [&check_nans, &check_empty_flips](
const Rect& a,
2145 ASSERT_FALSE(a.IsEmpty()) << a;
2148 std::stringstream stream;
2149 stream << a <<
" union " << b;
2150 auto label = stream.str();
2152 EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2153 EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2154 check_empty_flips(a, b, label);
2155 check_nans(a, b, label);
2176 test_non_empty(a, b);
2190 test_non_empty(a, b);
2197 test_non_empty(a, b);
2293 auto check_nans = [](
const Rect& rect,
const Point& point,
2294 const std::string& label) {
2295 ASSERT_TRUE(rect.IsFinite()) << label;
2296 ASSERT_TRUE(point.IsFinite()) << label;
2298 for (
int i = 1;
i < 16;
i++) {
2299 EXPECT_FALSE(
swap_nan(rect,
i).Contains(point))
2300 << label <<
", index = " <<
i;
2301 for (
int j = 1; j < 4; j++) {
2303 << label <<
", indices = " <<
i <<
", " << j;
2308 auto check_empty_flips = [](
const Rect& rect,
const Point& point,
2309 const std::string& label) {
2310 ASSERT_FALSE(rect.IsEmpty());
2312 EXPECT_FALSE(
flip_lr(rect).Contains(point)) << label;
2313 EXPECT_FALSE(
flip_tb(rect).Contains(point)) << label;
2314 EXPECT_FALSE(
flip_lrtb(rect).Contains(point)) << label;
2317 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& rect,
2318 const Point& point) {
2319 ASSERT_FALSE(rect.IsEmpty()) << rect;
2321 std::stringstream stream;
2322 stream << rect <<
" contains " << point;
2323 auto label = stream.str();
2325 EXPECT_TRUE(rect.Contains(point)) << label;
2326 check_empty_flips(rect, point, label);
2327 check_nans(rect, point, label);
2330 auto test_outside = [&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_FALSE(rect.Contains(point)) << label;
2339 check_empty_flips(rect, point, label);
2340 check_nans(rect, point, label);
2346 auto p =
Point(100, 100);
2353 auto p =
Point(200, 200);
2359 auto p =
Point(99, 99);
2365 auto p =
Point(199, 199);
2372 auto p =
Point(199, 199);
2447TEST(RectTest, RectContainsInclusivePoint) {
2448 auto check_nans = [](
const Rect& rect,
const Point& point,
2449 const std::string& label) {
2450 ASSERT_TRUE(rect.IsFinite()) << label;
2451 ASSERT_TRUE(point.IsFinite()) << label;
2453 for (
int i = 1;
i < 16;
i++) {
2454 EXPECT_FALSE(
swap_nan(rect,
i).ContainsInclusive(point))
2455 << label <<
", index = " <<
i;
2456 for (
int j = 1; j < 4; j++) {
2458 << label <<
", indices = " <<
i <<
", " << j;
2463 auto check_empty_flips = [](
const Rect& rect,
const Point& point,
2464 const std::string& label) {
2465 ASSERT_FALSE(rect.IsEmpty());
2467 EXPECT_FALSE(
flip_lr(rect).ContainsInclusive(point)) << label;
2468 EXPECT_FALSE(
flip_tb(rect).ContainsInclusive(point)) << label;
2469 EXPECT_FALSE(
flip_lrtb(rect).ContainsInclusive(point)) << label;
2472 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& rect,
2473 const Point& point) {
2474 ASSERT_FALSE(rect.IsEmpty()) << rect;
2476 std::stringstream stream;
2477 stream << rect <<
" contains " << point;
2478 auto label = stream.str();
2480 EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2481 check_empty_flips(rect, point, label);
2482 check_nans(rect, point, label);
2485 auto test_outside = [&check_nans, &check_empty_flips](
const Rect& rect,
2486 const Point& point) {
2487 ASSERT_FALSE(rect.IsEmpty()) << rect;
2489 std::stringstream stream;
2490 stream << rect <<
" contains " << point;
2491 auto label = stream.str();
2493 EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2494 check_empty_flips(rect, point, label);
2495 check_nans(rect, point, label);
2501 auto p =
Point(100, 100);
2508 auto p =
Point(200, 200);
2521 auto p =
Point(99, 99);
2527 auto p =
Point(199, 199);
2534 auto p =
Point(199, 199);
2617 auto check_nans = [](
const Rect& a,
const Rect& b,
const std::string& label) {
2618 ASSERT_TRUE(a.IsFinite()) << label;
2619 ASSERT_TRUE(b.IsFinite()) << label;
2620 ASSERT_FALSE(a.IsEmpty());
2622 for (
int i = 1;
i < 16;
i++) {
2624 EXPECT_FALSE(
swap_nan(a,
i).Contains(b)) << label <<
", index = " <<
i;
2626 EXPECT_TRUE(a.Contains(
swap_nan(b,
i))) << label <<
", index = " <<
i;
2628 for (
int j = 1; j < 16; j++) {
2630 << label <<
", indices = " <<
i <<
", " << j;
2635 auto check_empty_flips = [](
const Rect& a,
const Rect& b,
2636 const std::string& label) {
2637 ASSERT_FALSE(a.IsEmpty());
2639 ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2642 EXPECT_TRUE(a.Contains(
flip_lr(b))) << label;
2643 EXPECT_TRUE(a.Contains(
flip_tb(b))) << label;
2644 EXPECT_TRUE(a.Contains(
flip_lrtb(b))) << label;
2647 EXPECT_FALSE(
flip_lr(a).Contains(b)) << label;
2648 EXPECT_FALSE(
flip_tb(a).Contains(b)) << label;
2649 EXPECT_FALSE(
flip_lrtb(a).Contains(b)) << label;
2657 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& a,
2659 ASSERT_FALSE(a.IsEmpty()) << a;
2661 ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2663 std::stringstream stream;
2664 stream << a <<
" contains " << b;
2665 auto label = stream.str();
2667 EXPECT_TRUE(a.Contains(b)) << label;
2668 check_empty_flips(a, b, label);
2669 check_nans(a, b, label);
2672 auto test_not_inside = [&check_nans, &check_empty_flips](
const Rect& a,
2674 ASSERT_FALSE(a.IsEmpty()) << a;
2677 ASSERT_FALSE(b.IsEmpty()) << b;
2679 std::stringstream stream;
2680 stream << a <<
" contains " << b;
2681 auto label = stream.str();
2683 EXPECT_FALSE(a.Contains(b)) << label;
2684 check_empty_flips(a, b, label);
2685 check_nans(a, b, label);
2709 test_not_inside(a, b);
2715 test_not_inside(a, b);
2721 test_not_inside(a, b);
2827 auto check_nans = [&cull_rect](
const Rect& diff_rect,
2828 const std::string& label) {
2829 EXPECT_TRUE(cull_rect.IsFinite()) << label;
2830 EXPECT_TRUE(diff_rect.IsFinite()) << label;
2832 for (
int i = 1;
i < 16;
i++) {
2834 EXPECT_FALSE(
swap_nan(cull_rect,
i).Cutout(diff_rect).has_value())
2835 << label <<
", index " <<
i;
2836 EXPECT_EQ(
swap_nan(cull_rect,
i).CutoutOrEmpty(diff_rect),
Rect())
2837 << label <<
", index " <<
i;
2840 EXPECT_TRUE(cull_rect.Cutout(
swap_nan(diff_rect,
i)).has_value())
2841 << label <<
", index " <<
i;
2842 EXPECT_EQ(cull_rect.CutoutOrEmpty(
swap_nan(diff_rect,
i)), cull_rect)
2843 << label <<
", index " <<
i;
2845 for (
int j = 1; j < 16; j++) {
2849 << label <<
", indices " <<
i <<
", " << j;
2852 << label <<
", indices " <<
i <<
", " << j;
2857 auto check_empty_flips = [&cull_rect](
const Rect& diff_rect,
2858 const std::string& label) {
2859 EXPECT_FALSE(cull_rect.IsEmpty()) << label;
2860 EXPECT_FALSE(diff_rect.IsEmpty()) << label;
2864 EXPECT_TRUE(cull_rect.Cutout(
flip_lr(diff_rect)).has_value()) << label;
2865 EXPECT_EQ(cull_rect.Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2866 EXPECT_TRUE(cull_rect.Cutout(
flip_tb(diff_rect)).has_value()) << label;
2867 EXPECT_EQ(cull_rect.Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2868 EXPECT_TRUE(cull_rect.Cutout(
flip_lrtb(diff_rect)).has_value()) << label;
2869 EXPECT_EQ(cull_rect.Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2873 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2874 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2875 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2876 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2877 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2878 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2882 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
2886 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
2896 auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2897 const Rect& diff_rect,
const std::string& label) {
2898 EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2899 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2900 check_empty_flips(diff_rect, label);
2901 check_nans(diff_rect, label);
2904 auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2905 const Rect& diff_rect,
const Rect& result_rect,
2906 const std::string& label) {
2907 EXPECT_TRUE(!result_rect.IsEmpty());
2908 EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2909 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2910 check_empty_flips(diff_rect, label);
2911 check_nans(diff_rect, label);
2914 auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2915 const Rect& diff_rect,
const std::string& label) {
2916 EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2917 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect),
Rect()) << label;
2918 check_empty_flips(diff_rect, label);
2919 check_nans(diff_rect, label);
2923 non_reducing(
Rect::MakeLTRB(10, 10, 20, 20),
"outside UL corner");
2925 non_reducing(
Rect::MakeLTRB(40, 10, 50, 20),
"outside UR corner");
2927 non_reducing(
Rect::MakeLTRB(40, 40, 50, 50),
"outside LR corner");
2929 non_reducing(
Rect::MakeLTRB(10, 40, 20, 50),
"outside LR corner");
2933 non_reducing(
Rect::MakeLTRB(15, 15, 25, 25),
"covering UL corner");
2934 non_reducing(
Rect::MakeLTRB(35, 15, 45, 25),
"covering UR corner");
2935 non_reducing(
Rect::MakeLTRB(35, 35, 45, 45),
"covering LR corner");
2936 non_reducing(
Rect::MakeLTRB(15, 35, 25, 45),
"covering LL corner");
2939 non_reducing(
Rect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
2940 non_reducing(
Rect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
2941 non_reducing(
Rect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
2942 non_reducing(
Rect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
2943 non_reducing(
Rect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
2944 non_reducing(
Rect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
2945 non_reducing(
Rect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
2946 non_reducing(
Rect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
2949 non_reducing(
Rect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
2950 non_reducing(
Rect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
2961 "Slice off bottom");
2967 non_reducing(
Rect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
2970 emptying(cull_rect,
"Perfectly covering");
2979 auto check_empty_flips = [&cull_rect](
const IRect& diff_rect,
2980 const std::string& label) {
2981 EXPECT_FALSE(diff_rect.
IsEmpty());
2982 EXPECT_FALSE(cull_rect.
IsEmpty());
2986 EXPECT_TRUE(cull_rect.
Cutout(
flip_lr(diff_rect)).has_value()) << label;
2987 EXPECT_EQ(cull_rect.
Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2988 EXPECT_TRUE(cull_rect.
Cutout(
flip_tb(diff_rect)).has_value()) << label;
2989 EXPECT_EQ(cull_rect.
Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2990 EXPECT_TRUE(cull_rect.
Cutout(
flip_lrtb(diff_rect)).has_value()) << label;
2991 EXPECT_EQ(cull_rect.
Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2995 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2996 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2997 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2998 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2999 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
3000 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
3004 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
3008 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
3018 auto non_reducing = [&cull_rect, &check_empty_flips](
3019 const IRect& diff_rect,
const std::string& label) {
3020 EXPECT_EQ(cull_rect.
Cutout(diff_rect), cull_rect) << label;
3021 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), cull_rect) << label;
3022 check_empty_flips(diff_rect, label);
3025 auto reducing = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
3026 const IRect& result_rect,
3027 const std::string& label) {
3028 EXPECT_TRUE(!result_rect.IsEmpty());
3029 EXPECT_EQ(cull_rect.
Cutout(diff_rect), result_rect) << label;
3030 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), result_rect) << label;
3031 check_empty_flips(diff_rect, label);
3034 auto emptying = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
3035 const std::string& label) {
3036 EXPECT_FALSE(cull_rect.
Cutout(diff_rect).has_value()) << label;
3038 check_empty_flips(diff_rect, label);
3058 non_reducing(
IRect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
3059 non_reducing(
IRect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
3060 non_reducing(
IRect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
3061 non_reducing(
IRect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
3062 non_reducing(
IRect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
3063 non_reducing(
IRect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
3064 non_reducing(
IRect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
3065 non_reducing(
IRect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
3068 non_reducing(
IRect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
3069 non_reducing(
IRect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
3080 "Slice off bottom");
3086 non_reducing(
IRect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
3089 emptying(cull_rect,
"Perfectly covering");