From f64288a55eae53a7828e4330248e5c9be2448a03 Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Wed, 15 Mar 2023 07:49:16 +0800 Subject: [PATCH] [Impeller] Correct the results of 'GetRight()' and 'GetBottom()' for maximum rect (flutter/engine#40271) [Impeller] Correct the results of 'GetRight()' and 'GetBottom()' for maximum rect --- .../impeller/geometry/geometry_unittests.cc | 66 +++++++++++++++++-- engine/src/flutter/impeller/geometry/rect.h | 22 +++++-- 2 files changed, 75 insertions(+), 13 deletions(-) diff --git a/engine/src/flutter/impeller/geometry/geometry_unittests.cc b/engine/src/flutter/impeller/geometry/geometry_unittests.cc index b5720d0c0ce..191d944952d 100644 --- a/engine/src/flutter/impeller/geometry/geometry_unittests.cc +++ b/engine/src/flutter/impeller/geometry/geometry_unittests.cc @@ -1493,6 +1493,22 @@ TEST(GeometryTest, RectIntersection) { auto u = a.Intersection(b); ASSERT_FALSE(u.has_value()); } + + { + Rect a = Rect::MakeMaximum(); + Rect b(10, 10, 300, 300); + auto u = a.Intersection(b); + ASSERT_TRUE(u); + ASSERT_RECT_NEAR(u.value(), b); + } + + { + Rect a = Rect::MakeMaximum(); + Rect b = Rect::MakeMaximum(); + auto u = a.Intersection(b); + ASSERT_TRUE(u); + ASSERT_EQ(u, Rect::MakeMaximum()); + } } TEST(GeometryTest, RectIntersectsWithRect) { @@ -1519,6 +1535,18 @@ TEST(GeometryTest, RectIntersectsWithRect) { Rect b(100, 100, 100, 100); ASSERT_FALSE(a.IntersectsWithRect(b)); } + + { + Rect a = Rect::MakeMaximum(); + Rect b(10, 10, 100, 100); + ASSERT_TRUE(a.IntersectsWithRect(b)); + } + + { + Rect a = Rect::MakeMaximum(); + Rect b = Rect::MakeMaximum(); + ASSERT_TRUE(a.IntersectsWithRect(b)); + } } TEST(GeometryTest, RectCutout) { @@ -1603,6 +1631,12 @@ TEST(GeometryTest, RectContainsPoint) { Point p(199, 199); ASSERT_TRUE(r.Contains(p)); } + + { + Rect r = Rect::MakeMaximum(); + Point p(199, 199); + ASSERT_TRUE(r.Contains(p)); + } } TEST(GeometryTest, RectContainsRect) { @@ -1635,15 +1669,35 @@ TEST(GeometryTest, RectContainsRect) { Rect b(0, 0, 300, 300); ASSERT_FALSE(a.Contains(b)); } + { + Rect a = Rect::MakeMaximum(); + Rect b(0, 0, 300, 300); + ASSERT_TRUE(a.Contains(b)); + } } TEST(GeometryTest, RectGetPoints) { - Rect r(100, 200, 300, 400); - auto points = r.GetPoints(); - ASSERT_POINT_NEAR(points[0], Point(100, 200)); - ASSERT_POINT_NEAR(points[1], Point(400, 200)); - ASSERT_POINT_NEAR(points[2], Point(100, 600)); - ASSERT_POINT_NEAR(points[3], Point(400, 600)); + { + Rect r(100, 200, 300, 400); + auto points = r.GetPoints(); + ASSERT_POINT_NEAR(points[0], Point(100, 200)); + ASSERT_POINT_NEAR(points[1], Point(400, 200)); + ASSERT_POINT_NEAR(points[2], Point(100, 600)); + ASSERT_POINT_NEAR(points[3], Point(400, 600)); + } + + { + Rect r = Rect::MakeMaximum(); + auto points = r.GetPoints(); + ASSERT_EQ(points[0], Point(-std::numeric_limits::infinity(), + -std::numeric_limits::infinity())); + ASSERT_EQ(points[1], Point(std::numeric_limits::infinity(), + -std::numeric_limits::infinity())); + ASSERT_EQ(points[2], Point(-std::numeric_limits::infinity(), + std::numeric_limits::infinity())); + ASSERT_EQ(points[3], Point(std::numeric_limits::infinity(), + std::numeric_limits::infinity())); + } } TEST(GeometryTest, RectShift) { diff --git a/engine/src/flutter/impeller/geometry/rect.h b/engine/src/flutter/impeller/geometry/rect.h index afeb68620d9..c3468b7a0de 100644 --- a/engine/src/flutter/impeller/geometry/rect.h +++ b/engine/src/flutter/impeller/geometry/rect.h @@ -109,8 +109,8 @@ struct TRect { } constexpr bool Contains(const TPoint& p) const { - return p.x >= origin.x && p.x < origin.x + size.width && p.y >= origin.y && - p.y < origin.y + size.height; + return p.x >= GetLeft() && p.x < GetRight() && p.y >= GetTop() && + p.y < GetBottom(); } constexpr bool Contains(const TRect& o) const { @@ -124,27 +124,35 @@ struct TRect { constexpr bool IsMaximum() const { return *this == MakeMaximum(); } constexpr auto GetLeft() const { + if (IsMaximum()) { + return -std::numeric_limits::infinity(); + } return std::min(origin.x, origin.x + size.width); } constexpr auto GetTop() const { + if (IsMaximum()) { + return -std::numeric_limits::infinity(); + } return std::min(origin.y, origin.y + size.height); } constexpr auto GetRight() const { + if (IsMaximum()) { + return std::numeric_limits::infinity(); + } return std::max(origin.x, origin.x + size.width); } constexpr auto GetBottom() const { + if (IsMaximum()) { + return std::numeric_limits::infinity(); + } return std::max(origin.y, origin.y + size.height); } constexpr std::array GetLTRB() const { - const auto left = std::min(origin.x, origin.x + size.width); - const auto top = std::min(origin.y, origin.y + size.height); - const auto right = std::max(origin.x, origin.x + size.width); - const auto bottom = std::max(origin.y, origin.y + size.height); - return {left, top, right, bottom}; + return {GetLeft(), GetTop(), GetRight(), GetBottom()}; } /// @brief Get a version of this rectangle that has a non-negative size.