178TEST(RectTest, RectOverflowXYWH) {
179 auto min = std::numeric_limits<Scalar>::lowest();
180 auto max = std::numeric_limits<Scalar>::max();
181 auto inf = std::numeric_limits<Scalar>::infinity();
199 EXPECT_EQ(rect.GetLeft(), 5.0f);
200 EXPECT_EQ(rect.GetTop(), 10.0f);
201 EXPECT_EQ(rect.GetRight(), max);
202 EXPECT_EQ(rect.GetBottom(), 25.0f);
203 EXPECT_EQ(rect.GetX(), 5.0f);
204 EXPECT_EQ(rect.GetY(), 10.0f);
205 EXPECT_EQ(rect.GetWidth(), max);
206 EXPECT_EQ(rect.GetHeight(), 15.0f);
207 EXPECT_FALSE(rect.IsEmpty());
208 EXPECT_TRUE(rect.IsFinite());
214 EXPECT_EQ(rect.GetLeft(), max);
215 EXPECT_EQ(rect.GetTop(), 10.0f);
216 EXPECT_EQ(rect.GetRight(), inf);
217 EXPECT_EQ(rect.GetBottom(), 25.0f);
218 EXPECT_EQ(rect.GetX(), max);
219 EXPECT_EQ(rect.GetY(), 10.0f);
220 EXPECT_EQ(rect.GetWidth(), inf);
221 EXPECT_EQ(rect.GetHeight(), 15.0f);
222 EXPECT_FALSE(rect.IsEmpty());
223 EXPECT_FALSE(rect.IsFinite());
229 EXPECT_EQ(rect.GetLeft(), 5.0f);
230 EXPECT_EQ(rect.GetTop(), 10.0f);
231 EXPECT_EQ(rect.GetRight(), 25.0f);
232 EXPECT_EQ(rect.GetBottom(), max);
233 EXPECT_EQ(rect.GetX(), 5.0f);
234 EXPECT_EQ(rect.GetY(), 10.0f);
235 EXPECT_EQ(rect.GetWidth(), 20.0f);
236 EXPECT_EQ(rect.GetHeight(), max);
237 EXPECT_FALSE(rect.IsEmpty());
238 EXPECT_TRUE(rect.IsFinite());
244 EXPECT_EQ(rect.GetLeft(), 5.0f);
245 EXPECT_EQ(rect.GetTop(), max);
246 EXPECT_EQ(rect.GetRight(), 25.0f);
247 EXPECT_EQ(rect.GetBottom(), inf);
248 EXPECT_EQ(rect.GetX(), 5.0f);
249 EXPECT_EQ(rect.GetY(), max);
250 EXPECT_EQ(rect.GetWidth(), 20.0f);
251 EXPECT_EQ(rect.GetHeight(), inf);
252 EXPECT_FALSE(rect.IsEmpty());
253 EXPECT_FALSE(rect.IsFinite());
259 EXPECT_EQ(rect.GetLeft(), 5.0f);
260 EXPECT_EQ(rect.GetTop(), 10.0f);
261 EXPECT_EQ(rect.GetRight(), min);
262 EXPECT_EQ(rect.GetBottom(), 25.0f);
263 EXPECT_EQ(rect.GetX(), 5.0f);
264 EXPECT_EQ(rect.GetY(), 10.0f);
265 EXPECT_EQ(rect.GetWidth(), min);
266 EXPECT_EQ(rect.GetHeight(), 15.0f);
267 EXPECT_TRUE(rect.IsEmpty());
268 EXPECT_TRUE(rect.IsFinite());
274 EXPECT_EQ(rect.GetLeft(), min);
275 EXPECT_EQ(rect.GetTop(), 10.0f);
276 EXPECT_EQ(rect.GetRight(), -inf);
277 EXPECT_EQ(rect.GetBottom(), 25.0f);
278 EXPECT_EQ(rect.GetX(), min);
279 EXPECT_EQ(rect.GetY(), 10.0f);
280 EXPECT_EQ(rect.GetWidth(), -inf);
281 EXPECT_EQ(rect.GetHeight(), 15.0f);
282 EXPECT_TRUE(rect.IsEmpty());
283 EXPECT_FALSE(rect.IsFinite());
289 EXPECT_EQ(rect.GetLeft(), 5.0f);
290 EXPECT_EQ(rect.GetTop(), 10.0f);
291 EXPECT_EQ(rect.GetRight(), 25.0f);
292 EXPECT_EQ(rect.GetBottom(), min);
293 EXPECT_EQ(rect.GetX(), 5.0f);
294 EXPECT_EQ(rect.GetY(), 10.0f);
295 EXPECT_EQ(rect.GetWidth(), 20.0f);
296 EXPECT_EQ(rect.GetHeight(), min);
297 EXPECT_TRUE(rect.IsEmpty());
298 EXPECT_TRUE(rect.IsFinite());
304 EXPECT_EQ(rect.GetLeft(), 5.0f);
305 EXPECT_EQ(rect.GetTop(), min);
306 EXPECT_EQ(rect.GetRight(), 25.0f);
307 EXPECT_EQ(rect.GetBottom(), -inf);
308 EXPECT_EQ(rect.GetX(), 5.0f);
309 EXPECT_EQ(rect.GetY(), min);
310 EXPECT_EQ(rect.GetWidth(), 20.0f);
311 EXPECT_EQ(rect.GetHeight(), -inf);
312 EXPECT_TRUE(rect.IsEmpty());
313 EXPECT_FALSE(rect.IsFinite());
384TEST(RectTest, RectOverflowLTRB) {
385 auto min = std::numeric_limits<Scalar>::lowest();
386 auto max = std::numeric_limits<Scalar>::max();
387 auto inf = std::numeric_limits<Scalar>::infinity();
405 EXPECT_EQ(rect.GetLeft(), -5.0f);
406 EXPECT_EQ(rect.GetTop(), 10.0f);
407 EXPECT_EQ(rect.GetRight(), max);
408 EXPECT_EQ(rect.GetBottom(), 25.0f);
409 EXPECT_EQ(rect.GetX(), -5.0f);
410 EXPECT_EQ(rect.GetY(), 10.0f);
411 EXPECT_EQ(rect.GetWidth(), max);
412 EXPECT_EQ(rect.GetHeight(), 15.0f);
413 EXPECT_FALSE(rect.IsEmpty());
414 EXPECT_TRUE(rect.IsFinite());
420 EXPECT_EQ(rect.GetLeft(), min + 5.0f);
421 EXPECT_EQ(rect.GetTop(), 10.0f);
422 EXPECT_EQ(rect.GetRight(), max - 5.0f);
423 EXPECT_EQ(rect.GetBottom(), 25.0f);
424 EXPECT_EQ(rect.GetX(), min + 5.0f);
425 EXPECT_EQ(rect.GetY(), 10.0f);
426 EXPECT_EQ(rect.GetWidth(), inf);
427 EXPECT_EQ(rect.GetHeight(), 15.0f);
428 EXPECT_FALSE(rect.IsEmpty());
429 EXPECT_TRUE(rect.IsFinite());
435 EXPECT_EQ(rect.GetLeft(), 5.0f);
436 EXPECT_EQ(rect.GetTop(), -10.0f);
437 EXPECT_EQ(rect.GetRight(), 20.0f);
438 EXPECT_EQ(rect.GetBottom(), max);
439 EXPECT_EQ(rect.GetX(), 5.0f);
440 EXPECT_EQ(rect.GetY(), -10.0f);
441 EXPECT_EQ(rect.GetWidth(), 15.0f);
442 EXPECT_EQ(rect.GetHeight(), max);
443 EXPECT_FALSE(rect.IsEmpty());
444 EXPECT_TRUE(rect.IsFinite());
450 EXPECT_EQ(rect.GetLeft(), 5.0f);
451 EXPECT_EQ(rect.GetTop(), min + 10.0f);
452 EXPECT_EQ(rect.GetRight(), 20.0f);
453 EXPECT_EQ(rect.GetBottom(), max - 15.0f);
454 EXPECT_EQ(rect.GetX(), 5.0f);
455 EXPECT_EQ(rect.GetY(), min + 10.0f);
456 EXPECT_EQ(rect.GetWidth(), 15.0f);
457 EXPECT_EQ(rect.GetHeight(), inf);
458 EXPECT_FALSE(rect.IsEmpty());
459 EXPECT_TRUE(rect.IsFinite());
465 EXPECT_EQ(rect.GetLeft(), 5.0f);
466 EXPECT_EQ(rect.GetTop(), 10.0f);
467 EXPECT_EQ(rect.GetRight(), min);
468 EXPECT_EQ(rect.GetBottom(), 25.0f);
469 EXPECT_EQ(rect.GetX(), 5.0f);
470 EXPECT_EQ(rect.GetY(), 10.0f);
471 EXPECT_EQ(rect.GetWidth(), min);
472 EXPECT_EQ(rect.GetHeight(), 15.0f);
473 EXPECT_TRUE(rect.IsEmpty());
474 EXPECT_TRUE(rect.IsFinite());
480 EXPECT_EQ(rect.GetLeft(), max - 5.0f);
481 EXPECT_EQ(rect.GetTop(), 10.0f);
482 EXPECT_EQ(rect.GetRight(), min + 10.0f);
483 EXPECT_EQ(rect.GetBottom(), 25.0f);
484 EXPECT_EQ(rect.GetX(), max - 5.0f);
485 EXPECT_EQ(rect.GetY(), 10.0f);
486 EXPECT_EQ(rect.GetWidth(), -inf);
487 EXPECT_EQ(rect.GetHeight(), 15.0f);
488 EXPECT_TRUE(rect.IsEmpty());
489 EXPECT_TRUE(rect.IsFinite());
495 EXPECT_EQ(rect.GetLeft(), 5.0f);
496 EXPECT_EQ(rect.GetTop(), 10.0f);
497 EXPECT_EQ(rect.GetRight(), 20.0f);
498 EXPECT_EQ(rect.GetBottom(), min);
499 EXPECT_EQ(rect.GetX(), 5.0f);
500 EXPECT_EQ(rect.GetY(), 10.0f);
501 EXPECT_EQ(rect.GetWidth(), 15.0f);
502 EXPECT_EQ(rect.GetHeight(), min);
503 EXPECT_TRUE(rect.IsEmpty());
504 EXPECT_TRUE(rect.IsFinite());
510 EXPECT_EQ(rect.GetLeft(), 5.0f);
511 EXPECT_EQ(rect.GetTop(), max - 5.0f);
512 EXPECT_EQ(rect.GetRight(), 20.0f);
513 EXPECT_EQ(rect.GetBottom(), min + 10.0f);
514 EXPECT_EQ(rect.GetX(), 5.0f);
515 EXPECT_EQ(rect.GetY(), max - 5.0f);
516 EXPECT_EQ(rect.GetWidth(), 15.0f);
517 EXPECT_EQ(rect.GetHeight(), -inf);
518 EXPECT_TRUE(rect.IsEmpty());
519 EXPECT_TRUE(rect.IsFinite());
933 rect.GetWidth() * scale,
934 rect.GetHeight() * scale);
937 << rect <<
" * " << scale;
939 << rect <<
" * " << scale;
941 << rect <<
" * " << scale;
943 << rect <<
" * " << scale;
948 rect.GetY() * scale_y,
949 rect.GetWidth() * scale_x,
950 rect.GetHeight() * scale_y);
953 << rect <<
" * " << scale_x <<
", " << scale_y;
955 << rect <<
" * " << scale_x <<
", " << scale_y;
957 << rect <<
" * " << scale_x <<
", " << scale_y;
959 test1(rect, scale_x);
960 test1(rect, scale_y);
975 auto test1 = [](
IRect rect, int64_t scale) {
981 EXPECT_EQ(rect.
Scale(scale), expected)
982 << rect <<
" * " << scale;
983 EXPECT_EQ(rect.
Scale(scale, scale), expected)
984 << rect <<
" * " << scale;
985 EXPECT_EQ(rect.
Scale(
IPoint(scale, scale)), expected)
986 << rect <<
" * " << scale;
987 EXPECT_EQ(rect.
Scale(
ISize(scale, scale)), expected)
988 << rect <<
" * " << scale;
991 auto test2 = [&test1](
IRect rect, int64_t scale_x, int64_t scale_y) {
993 rect.
GetY() * scale_y,
997 EXPECT_EQ(rect.
Scale(scale_x, scale_y), expected)
998 << rect <<
" * " << scale_x <<
", " << scale_y;
999 EXPECT_EQ(rect.
Scale(
IPoint(scale_x, scale_y)), expected)
1000 << rect <<
" * " << scale_x <<
", " << scale_y;
1001 EXPECT_EQ(rect.
Scale(
ISize(scale_x, scale_y)), expected)
1002 << rect <<
" * " << scale_x <<
", " << scale_y;
1004 test1(rect, scale_x);
1005 test1(rect, scale_y);
1034TEST(RectTest, RectGetNormalizingTransform) {
1040 EXPECT_EQ(r.GetNormalizingTransform(),
1049 auto m = r.GetNormalizingTransform();
1058 EXPECT_EQ(m *
Point(350, 600),
Point(0.5, 0.5));
1061 EXPECT_EQ(m *
Point(200, 300),
Point(-1, -1));
1062 EXPECT_EQ(m *
Point(500, 300),
Point(2, -1));
1064 EXPECT_EQ(m *
Point(200, 900),
Point(-1, 2));
1073 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1074 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1075 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1078 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1079 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1080 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1087 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1088 auto inf = std::numeric_limits<Scalar>::infinity();
1091 EXPECT_EQ(
Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1092 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1093 EXPECT_EQ(
Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1096 EXPECT_EQ(
Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1097 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1098 EXPECT_EQ(
Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1101 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1102 EXPECT_EQ(
Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1103 EXPECT_EQ(
Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1106 EXPECT_EQ(
Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1107 EXPECT_EQ(
Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1108 EXPECT_EQ(
Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1111 EXPECT_EQ(
Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1112 EXPECT_EQ(
Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1113 EXPECT_EQ(
Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1116 EXPECT_EQ(
Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1117 EXPECT_EQ(
Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1118 EXPECT_EQ(
Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1173 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1618 auto check_nans = [](
const Rect& a,
const Rect& b,
const std::string& label) {
1619 ASSERT_TRUE(a.IsFinite()) << label;
1620 ASSERT_TRUE(b.IsFinite()) << label;
1622 for (
int i = 1;
i < 16;
i++) {
1624 EXPECT_FALSE(
swap_nan(a,
i).Intersection(b).has_value())
1625 << label <<
", index = " <<
i;
1627 EXPECT_FALSE(a.Intersection(
swap_nan(b,
i)).has_value())
1628 << label <<
", index = " <<
i;
1630 for (
int j = 1; j < 16; j++) {
1632 << label <<
", indices = " <<
i <<
", " << j;
1637 auto check_empty_flips = [](
const Rect& a,
const Rect& b,
1638 const std::string& label) {
1639 ASSERT_FALSE(a.IsEmpty());
1643 EXPECT_FALSE(a.Intersection(
flip_lr(b)).has_value()) << label;
1644 EXPECT_TRUE(a.IntersectionOrEmpty(
flip_lr(b)).IsEmpty()) << label;
1645 EXPECT_FALSE(a.Intersection(
flip_tb(b)).has_value()) << label;
1646 EXPECT_TRUE(a.IntersectionOrEmpty(
flip_tb(b)).IsEmpty()) << label;
1647 EXPECT_FALSE(a.Intersection(
flip_lrtb(b)).has_value()) << label;
1648 EXPECT_TRUE(a.IntersectionOrEmpty(
flip_lrtb(b)).IsEmpty()) << label;
1651 EXPECT_FALSE(
flip_lr(a).Intersection(b).has_value()) << label;
1652 EXPECT_TRUE(
flip_lr(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1653 EXPECT_FALSE(
flip_tb(a).Intersection(b).has_value()) << label;
1654 EXPECT_TRUE(
flip_tb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1655 EXPECT_FALSE(
flip_lrtb(a).Intersection(b).has_value()) << label;
1656 EXPECT_TRUE(
flip_lrtb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1659 EXPECT_FALSE(
flip_lr(a).Intersection(
flip_lr(b)).has_value()) << label;
1660 EXPECT_TRUE(
flip_lr(a).IntersectionOrEmpty(
flip_lr(b)).IsEmpty()) << label;
1661 EXPECT_FALSE(
flip_tb(a).Intersection(
flip_tb(b)).has_value()) << label;
1662 EXPECT_TRUE(
flip_tb(a).IntersectionOrEmpty(
flip_tb(b)).IsEmpty()) << label;
1668 auto test_non_empty = [&check_nans, &check_empty_flips](
1670 ASSERT_FALSE(a.IsEmpty()) << a;
1673 std::stringstream stream;
1674 stream << a <<
" union " << b;
1675 auto label = stream.str();
1677 EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1678 EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1679 EXPECT_EQ(a.Intersection(b), result) << label;
1680 EXPECT_EQ(b.Intersection(a), result) << label;
1681 check_empty_flips(a, b, label);
1682 check_nans(a, b, label);
1685 auto test_empty = [&check_nans, &check_empty_flips](
const Rect& a,
1687 ASSERT_FALSE(a.IsEmpty()) << a;
1690 std::stringstream stream;
1691 stream << a <<
" union " << b;
1692 auto label = stream.str();
1694 EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1695 EXPECT_TRUE(a.IntersectionOrEmpty(b).IsEmpty()) << label;
1696 EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1697 EXPECT_TRUE(b.IntersectionOrEmpty(a).IsEmpty()) << label;
1698 check_empty_flips(a, b, label);
1699 check_nans(a, b, label);
1721 test_non_empty(a, b, expected);
1735 test_non_empty(a, b, b);
1951TEST(RectTest, RectIntersectsWithRect) {
1952 auto check_nans = [](
const Rect& a,
const Rect& b,
const std::string& label) {
1953 ASSERT_TRUE(a.IsFinite()) << label;
1954 ASSERT_TRUE(b.IsFinite()) << label;
1956 for (
int i = 1;
i < 16;
i++) {
1958 EXPECT_FALSE(
swap_nan(a,
i).IntersectsWithRect(b))
1959 << label <<
", index = " <<
i;
1961 EXPECT_FALSE(a.IntersectsWithRect(
swap_nan(b,
i)))
1962 << label <<
", index = " <<
i;
1964 for (
int j = 1; j < 16; j++) {
1966 << label <<
", indices = " <<
i <<
", " << j;
1971 auto check_empty_flips = [](
const Rect& a,
const Rect& b,
1972 const std::string& label) {
1973 ASSERT_FALSE(a.IsEmpty());
1977 EXPECT_FALSE(a.IntersectsWithRect(
flip_lr(b))) << label;
1978 EXPECT_FALSE(a.IntersectsWithRect(
flip_tb(b))) << label;
1979 EXPECT_FALSE(a.IntersectsWithRect(
flip_lrtb(b))) << label;
1982 EXPECT_FALSE(
flip_lr(a).IntersectsWithRect(b)) << label;
1983 EXPECT_FALSE(
flip_tb(a).IntersectsWithRect(b)) << label;
1984 EXPECT_FALSE(
flip_lrtb(a).IntersectsWithRect(b)) << label;
1987 EXPECT_FALSE(
flip_lr(a).IntersectsWithRect(
flip_lr(b))) << label;
1988 EXPECT_FALSE(
flip_tb(a).IntersectsWithRect(
flip_tb(b))) << label;
1992 auto test_non_empty = [&check_nans, &check_empty_flips](
const Rect& a,
1994 ASSERT_FALSE(a.IsEmpty()) << a;
1997 std::stringstream stream;
1998 stream << a <<
" union " << b;
1999 auto label = stream.str();
2001 EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
2002 EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
2003 check_empty_flips(a, b, label);
2004 check_nans(a, b, label);
2007 auto test_empty = [&check_nans, &check_empty_flips](
const Rect& a,
2009 ASSERT_FALSE(a.IsEmpty()) << a;
2012 std::stringstream stream;
2013 stream << a <<
" union " << b;
2014 auto label = stream.str();
2016 EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2017 EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2018 check_empty_flips(a, b, label);
2019 check_nans(a, b, label);
2040 test_non_empty(a, b);
2054 test_non_empty(a, b);
2061 test_non_empty(a, b);
2157 auto check_nans = [](
const Rect& rect,
const Point& point,
2158 const std::string& label) {
2159 ASSERT_TRUE(rect.IsFinite()) << label;
2160 ASSERT_TRUE(point.IsFinite()) << label;
2162 for (
int i = 1;
i < 16;
i++) {
2163 EXPECT_FALSE(
swap_nan(rect,
i).Contains(point))
2164 << label <<
", index = " <<
i;
2165 for (
int j = 1; j < 4; j++) {
2167 << label <<
", indices = " <<
i <<
", " << j;
2172 auto check_empty_flips = [](
const Rect& rect,
const Point& point,
2173 const std::string& label) {
2174 ASSERT_FALSE(rect.IsEmpty());
2176 EXPECT_FALSE(
flip_lr(rect).Contains(point)) << label;
2177 EXPECT_FALSE(
flip_tb(rect).Contains(point)) << label;
2178 EXPECT_FALSE(
flip_lrtb(rect).Contains(point)) << label;
2181 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& rect,
2182 const Point& point) {
2183 ASSERT_FALSE(rect.IsEmpty()) << rect;
2185 std::stringstream stream;
2186 stream << rect <<
" contains " << point;
2187 auto label = stream.str();
2189 EXPECT_TRUE(rect.Contains(point)) << label;
2190 check_empty_flips(rect, point, label);
2191 check_nans(rect, point, label);
2194 auto test_outside = [&check_nans, &check_empty_flips](
const Rect& rect,
2195 const Point& point) {
2196 ASSERT_FALSE(rect.IsEmpty()) << rect;
2198 std::stringstream stream;
2199 stream << rect <<
" contains " << point;
2200 auto label = stream.str();
2202 EXPECT_FALSE(rect.Contains(point)) << label;
2203 check_empty_flips(rect, point, label);
2204 check_nans(rect, point, label);
2210 auto p =
Point(100, 100);
2217 auto p =
Point(200, 200);
2223 auto p =
Point(99, 99);
2229 auto p =
Point(199, 199);
2236 auto p =
Point(199, 199);
2311TEST(RectTest, RectContainsInclusivePoint) {
2312 auto check_nans = [](
const Rect& rect,
const Point& point,
2313 const std::string& label) {
2314 ASSERT_TRUE(rect.IsFinite()) << label;
2315 ASSERT_TRUE(point.IsFinite()) << label;
2317 for (
int i = 1;
i < 16;
i++) {
2318 EXPECT_FALSE(
swap_nan(rect,
i).ContainsInclusive(point))
2319 << label <<
", index = " <<
i;
2320 for (
int j = 1; j < 4; j++) {
2322 << label <<
", indices = " <<
i <<
", " << j;
2327 auto check_empty_flips = [](
const Rect& rect,
const Point& point,
2328 const std::string& label) {
2329 ASSERT_FALSE(rect.IsEmpty());
2331 EXPECT_FALSE(
flip_lr(rect).ContainsInclusive(point)) << label;
2332 EXPECT_FALSE(
flip_tb(rect).ContainsInclusive(point)) << label;
2333 EXPECT_FALSE(
flip_lrtb(rect).ContainsInclusive(point)) << label;
2336 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& rect,
2337 const Point& point) {
2338 ASSERT_FALSE(rect.IsEmpty()) << rect;
2340 std::stringstream stream;
2341 stream << rect <<
" contains " << point;
2342 auto label = stream.str();
2344 EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2345 check_empty_flips(rect, point, label);
2346 check_nans(rect, point, label);
2349 auto test_outside = [&check_nans, &check_empty_flips](
const Rect& rect,
2350 const Point& point) {
2351 ASSERT_FALSE(rect.IsEmpty()) << rect;
2353 std::stringstream stream;
2354 stream << rect <<
" contains " << point;
2355 auto label = stream.str();
2357 EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2358 check_empty_flips(rect, point, label);
2359 check_nans(rect, point, label);
2365 auto p =
Point(100, 100);
2372 auto p =
Point(200, 200);
2385 auto p =
Point(99, 99);
2391 auto p =
Point(199, 199);
2398 auto p =
Point(199, 199);
2481 auto check_nans = [](
const Rect& a,
const Rect& b,
const std::string& label) {
2482 ASSERT_TRUE(a.IsFinite()) << label;
2483 ASSERT_TRUE(b.IsFinite()) << label;
2484 ASSERT_FALSE(a.IsEmpty());
2486 for (
int i = 1;
i < 16;
i++) {
2488 EXPECT_FALSE(
swap_nan(a,
i).Contains(b)) << label <<
", index = " <<
i;
2490 EXPECT_TRUE(a.Contains(
swap_nan(b,
i))) << label <<
", index = " <<
i;
2492 for (
int j = 1; j < 16; j++) {
2494 << label <<
", indices = " <<
i <<
", " << j;
2499 auto check_empty_flips = [](
const Rect& a,
const Rect& b,
2500 const std::string& label) {
2501 ASSERT_FALSE(a.IsEmpty());
2503 ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2506 EXPECT_TRUE(a.Contains(
flip_lr(b))) << label;
2507 EXPECT_TRUE(a.Contains(
flip_tb(b))) << label;
2508 EXPECT_TRUE(a.Contains(
flip_lrtb(b))) << label;
2511 EXPECT_FALSE(
flip_lr(a).Contains(b)) << label;
2512 EXPECT_FALSE(
flip_tb(a).Contains(b)) << label;
2513 EXPECT_FALSE(
flip_lrtb(a).Contains(b)) << label;
2521 auto test_inside = [&check_nans, &check_empty_flips](
const Rect& a,
2523 ASSERT_FALSE(a.IsEmpty()) << a;
2525 ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2527 std::stringstream stream;
2528 stream << a <<
" contains " << b;
2529 auto label = stream.str();
2531 EXPECT_TRUE(a.Contains(b)) << label;
2532 check_empty_flips(a, b, label);
2533 check_nans(a, b, label);
2536 auto test_not_inside = [&check_nans, &check_empty_flips](
const Rect& a,
2538 ASSERT_FALSE(a.IsEmpty()) << a;
2541 ASSERT_FALSE(b.IsEmpty()) << b;
2543 std::stringstream stream;
2544 stream << a <<
" contains " << b;
2545 auto label = stream.str();
2547 EXPECT_FALSE(a.Contains(b)) << label;
2548 check_empty_flips(a, b, label);
2549 check_nans(a, b, label);
2573 test_not_inside(a, b);
2579 test_not_inside(a, b);
2585 test_not_inside(a, b);
2691 auto check_nans = [&cull_rect](
const Rect& diff_rect,
2692 const std::string& label) {
2693 EXPECT_TRUE(cull_rect.IsFinite()) << label;
2694 EXPECT_TRUE(diff_rect.IsFinite()) << label;
2696 for (
int i = 1;
i < 16;
i++) {
2698 EXPECT_FALSE(
swap_nan(cull_rect,
i).Cutout(diff_rect).has_value())
2699 << label <<
", index " <<
i;
2700 EXPECT_EQ(
swap_nan(cull_rect,
i).CutoutOrEmpty(diff_rect),
Rect())
2701 << label <<
", index " <<
i;
2704 EXPECT_TRUE(cull_rect.Cutout(
swap_nan(diff_rect,
i)).has_value())
2705 << label <<
", index " <<
i;
2706 EXPECT_EQ(cull_rect.CutoutOrEmpty(
swap_nan(diff_rect,
i)), cull_rect)
2707 << label <<
", index " <<
i;
2709 for (
int j = 1; j < 16; j++) {
2713 << label <<
", indices " <<
i <<
", " << j;
2716 << label <<
", indices " <<
i <<
", " << j;
2721 auto check_empty_flips = [&cull_rect](
const Rect& diff_rect,
2722 const std::string& label) {
2723 EXPECT_FALSE(cull_rect.IsEmpty()) << label;
2724 EXPECT_FALSE(diff_rect.IsEmpty()) << label;
2728 EXPECT_TRUE(cull_rect.Cutout(
flip_lr(diff_rect)).has_value()) << label;
2729 EXPECT_EQ(cull_rect.Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2730 EXPECT_TRUE(cull_rect.Cutout(
flip_tb(diff_rect)).has_value()) << label;
2731 EXPECT_EQ(cull_rect.Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2732 EXPECT_TRUE(cull_rect.Cutout(
flip_lrtb(diff_rect)).has_value()) << label;
2733 EXPECT_EQ(cull_rect.Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2737 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2738 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2739 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2740 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2741 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2742 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
Rect()) << label;
2746 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
2750 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
2760 auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2761 const Rect& diff_rect,
const std::string& label) {
2762 EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2763 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2764 check_empty_flips(diff_rect, label);
2765 check_nans(diff_rect, label);
2768 auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2769 const Rect& diff_rect,
const Rect& result_rect,
2770 const std::string& label) {
2771 EXPECT_TRUE(!result_rect.IsEmpty());
2772 EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2773 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2774 check_empty_flips(diff_rect, label);
2775 check_nans(diff_rect, label);
2778 auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2779 const Rect& diff_rect,
const std::string& label) {
2780 EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2781 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect),
Rect()) << label;
2782 check_empty_flips(diff_rect, label);
2783 check_nans(diff_rect, label);
2787 non_reducing(
Rect::MakeLTRB(10, 10, 20, 20),
"outside UL corner");
2789 non_reducing(
Rect::MakeLTRB(40, 10, 50, 20),
"outside UR corner");
2791 non_reducing(
Rect::MakeLTRB(40, 40, 50, 50),
"outside LR corner");
2793 non_reducing(
Rect::MakeLTRB(10, 40, 20, 50),
"outside LR corner");
2797 non_reducing(
Rect::MakeLTRB(15, 15, 25, 25),
"covering UL corner");
2798 non_reducing(
Rect::MakeLTRB(35, 15, 45, 25),
"covering UR corner");
2799 non_reducing(
Rect::MakeLTRB(35, 35, 45, 45),
"covering LR corner");
2800 non_reducing(
Rect::MakeLTRB(15, 35, 25, 45),
"covering LL corner");
2803 non_reducing(
Rect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
2804 non_reducing(
Rect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
2805 non_reducing(
Rect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
2806 non_reducing(
Rect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
2807 non_reducing(
Rect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
2808 non_reducing(
Rect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
2809 non_reducing(
Rect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
2810 non_reducing(
Rect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
2813 non_reducing(
Rect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
2814 non_reducing(
Rect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
2825 "Slice off bottom");
2831 non_reducing(
Rect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
2834 emptying(cull_rect,
"Perfectly covering");
2843 auto check_empty_flips = [&cull_rect](
const IRect& diff_rect,
2844 const std::string& label) {
2845 EXPECT_FALSE(diff_rect.
IsEmpty());
2846 EXPECT_FALSE(cull_rect.
IsEmpty());
2850 EXPECT_TRUE(cull_rect.
Cutout(
flip_lr(diff_rect)).has_value()) << label;
2851 EXPECT_EQ(cull_rect.
Cutout(
flip_lr(diff_rect)), cull_rect) << label;
2852 EXPECT_TRUE(cull_rect.
Cutout(
flip_tb(diff_rect)).has_value()) << label;
2853 EXPECT_EQ(cull_rect.
Cutout(
flip_tb(diff_rect)), cull_rect) << label;
2854 EXPECT_TRUE(cull_rect.
Cutout(
flip_lrtb(diff_rect)).has_value()) << label;
2855 EXPECT_EQ(cull_rect.
Cutout(
flip_lrtb(diff_rect)), cull_rect) << label;
2859 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2860 EXPECT_EQ(
flip_lr(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2861 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2862 EXPECT_EQ(
flip_tb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2863 EXPECT_FALSE(
flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2864 EXPECT_EQ(
flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect),
IRect()) << label;
2868 EXPECT_FALSE(
flip_lr(cull_rect).Cutout(
flip_lr(diff_rect)).has_value())
2872 EXPECT_FALSE(
flip_tb(cull_rect).Cutout(
flip_tb(diff_rect)).has_value())
2882 auto non_reducing = [&cull_rect, &check_empty_flips](
2883 const IRect& diff_rect,
const std::string& label) {
2884 EXPECT_EQ(cull_rect.
Cutout(diff_rect), cull_rect) << label;
2885 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), cull_rect) << label;
2886 check_empty_flips(diff_rect, label);
2889 auto reducing = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
2890 const IRect& result_rect,
2891 const std::string& label) {
2892 EXPECT_TRUE(!result_rect.IsEmpty());
2893 EXPECT_EQ(cull_rect.
Cutout(diff_rect), result_rect) << label;
2894 EXPECT_EQ(cull_rect.
CutoutOrEmpty(diff_rect), result_rect) << label;
2895 check_empty_flips(diff_rect, label);
2898 auto emptying = [&cull_rect, &check_empty_flips](
const IRect& diff_rect,
2899 const std::string& label) {
2900 EXPECT_FALSE(cull_rect.
Cutout(diff_rect).has_value()) << label;
2902 check_empty_flips(diff_rect, label);
2922 non_reducing(
IRect::MakeLTRB(20, 15, 39, 25),
"Top edge left-biased");
2923 non_reducing(
IRect::MakeLTRB(21, 15, 40, 25),
"Top edge, right biased");
2924 non_reducing(
IRect::MakeLTRB(35, 20, 45, 39),
"Right edge, top-biased");
2925 non_reducing(
IRect::MakeLTRB(35, 21, 45, 40),
"Right edge, bottom-biased");
2926 non_reducing(
IRect::MakeLTRB(20, 35, 39, 45),
"Bottom edge, left-biased");
2927 non_reducing(
IRect::MakeLTRB(21, 35, 40, 45),
"Bottom edge, right-biased");
2928 non_reducing(
IRect::MakeLTRB(15, 20, 25, 39),
"Left edge, top-biased");
2929 non_reducing(
IRect::MakeLTRB(15, 21, 25, 40),
"Left edge, bottom-biased");
2932 non_reducing(
IRect::MakeLTRB(25, 15, 35, 45),
"Vertical interior slice");
2933 non_reducing(
IRect::MakeLTRB(15, 25, 45, 35),
"Horizontal interior slice");
2944 "Slice off bottom");
2950 non_reducing(
IRect::MakeLTRB(21, 21, 39, 39),
"Contained, non-covering");
2953 emptying(cull_rect,
"Perfectly covering");
3116TEST(RectTest, TransformAndClipBounds) {
3121 2.0f, 0.0f, 0.0f, 0.0f,
3122 0.0f, 4.0f, 0.0f, 0.0f,
3123 0.0f, 0.0f, 1.0f, 0.0f,
3124 0.0f, 0.0f, 0.0f, 8.0f
3129 EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftTop()),
3130 Vector3(200.0f, 400.0f, 8.0f));
3131 EXPECT_EQ(matrix.TransformHomogenous(src.GetRightTop()),
3132 Vector3(400.0f, 400.0f, 8.0f));
3133 EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftBottom()),
3134 Vector3(200.0f, 800.0f, 8.0f));
3135 EXPECT_EQ(matrix.TransformHomogenous(src.GetRightBottom()),
3136 Vector3(400.0f, 800.0f, 8.0f));
3139 EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3140 EXPECT_EQ(src.TransformAndClipBounds(matrix), expect);
3147 2.0f, 0.0f, 0.0f, -0.01f,
3148 0.0f, 2.0f, 0.0f, -0.006f,
3149 0.0f, 0.0f, 1.0f, 0.0f,
3150 0.0f, 0.0f, 0.0f, 3.0f
3156 Vector3(200.0f, 200.0f, 1.4f));
3158 Vector3(400.0f, 200.0f, 0.4f));
3160 Vector3(200.0f, 400.0f, 0.8f));
3162 Vector3(400.0f, 400.0f, -0.2f));
3165 EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3173 2.0f, 0.0f, 0.0f, -.015f,
3174 0.0f, 2.0f, 0.0f, -.006f,
3175 0.0f, 0.0f, 1.0f, 0.0f,
3176 0.0f, 0.0f, 0.0f, 3.0f
3182 Vector3(200.0f, 200.0f, 0.9f));
3184 Vector3(400.0f, 200.0f, -0.6f));
3186 Vector3(200.0f, 400.0f, 0.3f));
3188 Vector3(400.0f, 400.0f, -1.2f));
3191 EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3199 2.0f, 0.0f, 0.0f, -.02f,
3200 0.0f, 2.0f, 0.0f, -.006f,
3201 0.0f, 0.0f, 1.0f, 0.0f,
3202 0.0f, 0.0f, 0.0f, 3.0f
3208 Vector3(200.0f, 200.0f, 0.4f));
3210 Vector3(400.0f, 200.0f, -1.6f));
3212 Vector3(200.0f, 400.0f, -0.2f));
3214 Vector3(400.0f, 400.0f, -2.2f));
3217 EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3225 2.0f, 0.0f, 0.0f, -.025f,
3226 0.0f, 2.0f, 0.0f, -.006f,
3227 0.0f, 0.0f, 1.0f, 0.0f,
3228 0.0f, 0.0f, 0.0f, 3.0f
3234 Vector3(200.0f, 200.0f, -0.1f));
3236 Vector3(400.0f, 200.0f, -2.6f));
3238 Vector3(200.0f, 400.0f, -0.7f));
3240 Vector3(400.0f, 400.0f, -3.2f));
3242 EXPECT_TRUE(src.TransformAndClipBounds(matrix).IsEmpty());