Skip to content

Commit

Permalink
[Impeller] Add rect cutout (#38020)
Browse files Browse the repository at this point in the history
* [Impeller] Incorporate difference clips in stencil coverage

* [Impeller] Add rect cutout
  • Loading branch information
bdero authored Dec 2, 2022
1 parent 025aefc commit 4c72d5c
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
59 changes: 59 additions & 0 deletions impeller/geometry/geometry_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,65 @@ TEST(GeometryTest, RectIntersectsWithRect) {
}
}

TEST(GeometryTest, RectCutout) {
// No cutout.
{
Rect a(0, 0, 100, 100);
Rect b(0, 0, 50, 50);
auto u = a.Cutout(b);
ASSERT_TRUE(u.has_value());
ASSERT_RECT_NEAR(u.value(), a);
}

// Full cutout.
{
Rect a(0, 0, 100, 100);
Rect b(-10, -10, 120, 120);
auto u = a.Cutout(b);
ASSERT_FALSE(u.has_value());
}

// Cutout from top.
{
auto a = Rect::MakeLTRB(0, 0, 100, 100);
auto b = Rect::MakeLTRB(-10, -10, 110, 90);
auto u = a.Cutout(b);
auto expected = Rect::MakeLTRB(0, 90, 100, 100);
ASSERT_TRUE(u.has_value());
ASSERT_RECT_NEAR(u.value(), expected);
}

// Cutout from bottom.
{
auto a = Rect::MakeLTRB(0, 0, 100, 100);
auto b = Rect::MakeLTRB(-10, 10, 110, 110);
auto u = a.Cutout(b);
auto expected = Rect::MakeLTRB(0, 0, 100, 10);
ASSERT_TRUE(u.has_value());
ASSERT_RECT_NEAR(u.value(), expected);
}

// Cutout from left.
{
auto a = Rect::MakeLTRB(0, 0, 100, 100);
auto b = Rect::MakeLTRB(-10, -10, 90, 110);
auto u = a.Cutout(b);
auto expected = Rect::MakeLTRB(90, 0, 100, 100);
ASSERT_TRUE(u.has_value());
ASSERT_RECT_NEAR(u.value(), expected);
}

// Cutout from right.
{
auto a = Rect::MakeLTRB(0, 0, 100, 100);
auto b = Rect::MakeLTRB(10, -10, 110, 110);
auto u = a.Cutout(b);
auto expected = Rect::MakeLTRB(0, 0, 10, 100);
ASSERT_TRUE(u.has_value());
ASSERT_RECT_NEAR(u.value(), expected);
}
}

TEST(GeometryTest, RectContainsPoint) {
{
// Origin is inclusive
Expand Down
33 changes: 33 additions & 0 deletions impeller/geometry/rect.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,39 @@ struct TRect {
constexpr bool IntersectsWithRect(const TRect& o) const {
return Intersection(o).has_value();
}

/// @brief Returns the new boundary rectangle that would result from the
/// rectangle being cutout by a second rectangle.
constexpr std::optional<TRect<T>> Cutout(const TRect& o) const {
const auto& [a_left, a_top, a_right, a_bottom] = GetLTRB(); // Source rect.
const auto& [b_left, b_top, b_right, b_bottom] = o.GetLTRB(); // Cutout.
if (b_left <= a_left && b_right >= a_right) {
if (b_top <= a_top && b_bottom >= a_bottom) {
// Full cutout.
return std::nullopt;
}
if (b_top <= a_top) {
// Cuts off the top.
return TRect::MakeLTRB(a_left, b_bottom, a_right, a_bottom);
}
if (b_bottom >= b_bottom) {
// Cuts out the bottom.
return TRect::MakeLTRB(a_left, a_top, a_right, b_top);
}
}
if (b_top <= a_top && b_bottom >= a_bottom) {
if (b_left <= a_left) {
// Cuts out the left.
return TRect::MakeLTRB(b_right, a_top, a_right, a_bottom);
}
if (b_right >= a_right) {
// Cuts out the right.
return TRect::MakeLTRB(a_left, a_top, b_left, a_bottom);
}
}

return *this;
}
};

using Rect = TRect<Scalar>;
Expand Down

0 comments on commit 4c72d5c

Please sign in to comment.