From 8d2acb0187e5427a546b291d780ed256c3722846 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Thu, 21 Dec 2023 11:11:36 -0800 Subject: [PATCH] [Impeller] Remove use of private Rect fields from PathBuilder --- impeller/aiks/aiks_unittests.cc | 90 +++++++++++++++++++++++++++++ impeller/geometry/path_builder.cc | 96 +++++++++++++++---------------- impeller/geometry/rect.h | 2 - 3 files changed, 136 insertions(+), 52 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 3fe4f77b4ecbd..b7a7e0d8bc2f2 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1819,6 +1819,96 @@ TEST_P(AiksTest, FilledRoundRectsRenderCorrectly) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +TEST_P(AiksTest, FilledRoundRectPathsRenderCorrectly) { + Canvas canvas; + canvas.Scale(GetContentScale()); + Paint paint; + const int color_count = 3; + Color colors[color_count] = { + Color::Blue(), + Color::Green(), + Color::Crimson(), + }; + + paint.color = Color::White(); + canvas.DrawPaint(paint); + + auto draw_rrect_as_path = [&canvas](const Rect& rect, const Size& radii, + const Paint& paint) { + PathBuilder builder = PathBuilder(); + builder.AddRoundedRect(rect, radii); + canvas.DrawPath(builder.TakePath(), paint); + }; + + int c_index = 0; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + paint.color = colors[(c_index++) % color_count]; + draw_rrect_as_path(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80), + Size(i * 5 + 10, j * 5 + 10), paint); + } + } + paint.color = colors[(c_index++) % color_count]; + draw_rrect_as_path(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint); + paint.color = colors[(c_index++) % color_count]; + draw_rrect_as_path(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint); + + std::vector gradient_colors = { + Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}, + Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}, + Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}, + Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}, + Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}, + Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}, + Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}}; + std::vector stops = { + 0.0, + (1.0 / 6.0) * 1, + (1.0 / 6.0) * 2, + (1.0 / 6.0) * 3, + (1.0 / 6.0) * 4, + (1.0 / 6.0) * 5, + 1.0, + }; + auto texture = CreateTextureForFixture("airplane.jpg", + /*enable_mipmapping=*/true); + + paint.color = Color::White().WithAlpha(0.1); + paint.color_source = ColorSource::MakeRadialGradient( + {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {}); + for (int i = 1; i <= 10; i++) { + int j = 11 - i; + draw_rrect_as_path(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, // + 550 + i * 20, 550 + j * 20), + Size(i * 10, j * 10), paint); + } + paint.color = Color::White().WithAlpha(0.5); + paint.color_source = ColorSource::MakeRadialGradient( + {200, 650}, 75, std::move(gradient_colors), std::move(stops), + Entity::TileMode::kMirror, {}); + draw_rrect_as_path(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint); + draw_rrect_as_path(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint); + + paint.color = Color::White().WithAlpha(0.1); + paint.color_source = ColorSource::MakeImage( + texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, + Matrix::MakeTranslation({520, 20})); + for (int i = 1; i <= 10; i++) { + int j = 11 - i; + draw_rrect_as_path(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, // + 720 + i * 20, 220 + j * 20), + Size(i * 10, j * 10), paint); + } + paint.color = Color::White().WithAlpha(0.5); + paint.color_source = ColorSource::MakeImage( + texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, + Matrix::MakeTranslation({800, 300})); + draw_rrect_as_path(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint); + draw_rrect_as_path(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + TEST_P(AiksTest, CoverageOriginShouldBeAccountedForInSubpasses) { auto callback = [&](AiksContext& renderer) -> std::optional { Canvas canvas; diff --git a/impeller/geometry/path_builder.cc b/impeller/geometry/path_builder.cc index 616b165aed2e6..599e8f2e75d25 100644 --- a/impeller/geometry/path_builder.cc +++ b/impeller/geometry/path_builder.cc @@ -114,12 +114,13 @@ PathBuilder& PathBuilder::AddCubicCurve(Point p1, } PathBuilder& PathBuilder::AddRect(Rect rect) { - current_ = rect.origin; + auto origin = rect.GetOrigin(); + auto size = rect.GetSize(); - auto tl = rect.origin; - auto bl = rect.origin + Point{0.0, rect.size.height}; - auto br = rect.origin + Point{rect.size.width, rect.size.height}; - auto tr = rect.origin + Point{rect.size.width, 0.0}; + auto tl = origin; + auto bl = origin + Point{0.0, size.height}; + auto br = origin + size; + auto tr = origin + Point{size.width, 0.0}; MoveTo(tl); LineTo(tr); @@ -150,16 +151,19 @@ PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) { return AddRect(rect); } - current_ = rect.origin + Point{radii.top_left.x, 0.0}; + auto rect_origin = rect.GetOrigin(); + auto rect_size = rect.GetSize(); - MoveTo({rect.origin.x + radii.top_left.x, rect.origin.y}); + current_ = rect_origin + Point{radii.top_left.x, 0.0}; + + MoveTo({rect_origin.x + radii.top_left.x, rect_origin.y}); //---------------------------------------------------------------------------- // Top line. // prototype_.AddLinearComponent( - {rect.origin.x + radii.top_left.x, rect.origin.y}, - {rect.origin.x + rect.size.width - radii.top_right.x, rect.origin.y}); + {rect_origin.x + radii.top_left.x, rect_origin.y}, + {rect_origin.x + rect_size.width - radii.top_right.x, rect_origin.y}); //---------------------------------------------------------------------------- // Top right arc. @@ -170,9 +174,9 @@ PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) { // Right line. // prototype_.AddLinearComponent( - {rect.origin.x + rect.size.width, rect.origin.y + radii.top_right.y}, - {rect.origin.x + rect.size.width, - rect.origin.y + rect.size.height - radii.bottom_right.y}); + {rect_origin.x + rect_size.width, rect_origin.y + radii.top_right.y}, + {rect_origin.x + rect_size.width, + rect_origin.y + rect_size.height - radii.bottom_right.y}); //---------------------------------------------------------------------------- // Bottom right arc. @@ -183,9 +187,9 @@ PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) { // Bottom line. // prototype_.AddLinearComponent( - {rect.origin.x + rect.size.width - radii.bottom_right.x, - rect.origin.y + rect.size.height}, - {rect.origin.x + radii.bottom_left.x, rect.origin.y + rect.size.height}); + {rect_origin.x + rect_size.width - radii.bottom_right.x, + rect_origin.y + rect_size.height}, + {rect_origin.x + radii.bottom_left.x, rect_origin.y + rect_size.height}); //---------------------------------------------------------------------------- // Bottom left arc. @@ -196,8 +200,8 @@ PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) { // Left line. // prototype_.AddLinearComponent( - {rect.origin.x, rect.origin.y + rect.size.height - radii.bottom_left.y}, - {rect.origin.x, rect.origin.y + radii.top_left.y}); + {rect_origin.x, rect_origin.y + rect_size.height - radii.bottom_left.y}, + {rect_origin.x, rect_origin.y + radii.top_left.y}); //---------------------------------------------------------------------------- // Top left arc. @@ -212,54 +216,48 @@ PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) { PathBuilder& PathBuilder::AddRoundedRectTopLeft(Rect rect, RoundingRadii radii) { const auto magic_top_left = radii.top_left * kArcApproximationMagic; + const auto corner = rect.GetOrigin(); prototype_.AddCubicComponent( - {rect.origin.x, rect.origin.y + radii.top_left.y}, - {rect.origin.x, rect.origin.y + radii.top_left.y - magic_top_left.y}, - {rect.origin.x + radii.top_left.x - magic_top_left.x, rect.origin.y}, - {rect.origin.x + radii.top_left.x, rect.origin.y}); + {corner.x, corner.y + radii.top_left.y}, + {corner.x, corner.y + radii.top_left.y - magic_top_left.y}, + {corner.x + radii.top_left.x - magic_top_left.x, corner.y}, + {corner.x + radii.top_left.x, corner.y}); return *this; } PathBuilder& PathBuilder::AddRoundedRectTopRight(Rect rect, RoundingRadii radii) { const auto magic_top_right = radii.top_right * kArcApproximationMagic; + const auto corner = rect.GetOrigin() + Point{rect.GetWidth(), 0}; prototype_.AddCubicComponent( - {rect.origin.x + rect.size.width - radii.top_right.x, rect.origin.y}, - {rect.origin.x + rect.size.width - radii.top_right.x + magic_top_right.x, - rect.origin.y}, - {rect.origin.x + rect.size.width, - rect.origin.y + radii.top_right.y - magic_top_right.y}, - {rect.origin.x + rect.size.width, rect.origin.y + radii.top_right.y}); + {corner.x - radii.top_right.x, corner.y}, + {corner.x - radii.top_right.x + magic_top_right.x, corner.y}, + {corner.x, corner.y + radii.top_right.y - magic_top_right.y}, + {corner.x, corner.y + radii.top_right.y}); return *this; } PathBuilder& PathBuilder::AddRoundedRectBottomRight(Rect rect, RoundingRadii radii) { const auto magic_bottom_right = radii.bottom_right * kArcApproximationMagic; + const auto corner = rect.GetOrigin() + rect.GetSize(); prototype_.AddCubicComponent( - {rect.origin.x + rect.size.width, - rect.origin.y + rect.size.height - radii.bottom_right.y}, - {rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - - radii.bottom_right.y + - magic_bottom_right.y}, - {rect.origin.x + rect.size.width - radii.bottom_right.x + - magic_bottom_right.x, - rect.origin.y + rect.size.height}, - {rect.origin.x + rect.size.width - radii.bottom_right.x, - rect.origin.y + rect.size.height}); + {corner.x, corner.y - radii.bottom_right.y}, + {corner.x, corner.y - radii.bottom_right.y + magic_bottom_right.y}, + {corner.x - radii.bottom_right.x + magic_bottom_right.x, corner.y}, + {corner.x - radii.bottom_right.x, corner.y}); return *this; } PathBuilder& PathBuilder::AddRoundedRectBottomLeft(Rect rect, RoundingRadii radii) { const auto magic_bottom_left = radii.bottom_left * kArcApproximationMagic; + const auto corner = rect.GetOrigin() + Point{0, rect.GetHeight()}; prototype_.AddCubicComponent( - {rect.origin.x + radii.bottom_left.x, rect.origin.y + rect.size.height}, - {rect.origin.x + radii.bottom_left.x - magic_bottom_left.x, - rect.origin.y + rect.size.height}, - {rect.origin.x, rect.origin.y + rect.size.height - radii.bottom_left.y + - magic_bottom_left.y}, - {rect.origin.x, rect.origin.y + rect.size.height - radii.bottom_left.y}); + {corner.x + radii.bottom_left.x, corner.y}, + {corner.x + radii.bottom_left.x - magic_bottom_left.x, corner.y}, + {corner.x, corner.y - radii.bottom_left.y + magic_bottom_left.y}, + {corner.x, corner.y - radii.bottom_left.y}); return *this; } @@ -274,10 +272,8 @@ PathBuilder& PathBuilder::AddArc(const Rect& oval_bounds, sweep.radians = std::min(k2Pi, sweep.radians); start.radians = std::fmod(start.radians, k2Pi); - const Point radius = {oval_bounds.size.width * 0.5f, - oval_bounds.size.height * 0.5f}; - const Point center = {oval_bounds.origin.x + radius.x, - oval_bounds.origin.y + radius.y}; + const Point center = oval_bounds.GetCenter(); + const Point radius = center - oval_bounds.GetOrigin(); Vector2 p1_unit(std::cos(start.radians), std::sin(start.radians)); @@ -324,9 +320,9 @@ PathBuilder& PathBuilder::AddArc(const Rect& oval_bounds, } PathBuilder& PathBuilder::AddOval(const Rect& container) { - const Point r = {container.size.width * 0.5f, container.size.height * 0.5f}; - const Point c = {container.origin.x + r.x, container.origin.y + r.y}; - const Point m = {kArcApproximationMagic * r.x, kArcApproximationMagic * r.y}; + const Point c = container.GetCenter(); + const Point r = c - container.GetOrigin(); + const Point m = r * kArcApproximationMagic; MoveTo({c.x, c.y - r.y}); diff --git a/impeller/geometry/rect.h b/impeller/geometry/rect.h index 637f3ce5250e0..817326b96c06b 100644 --- a/impeller/geometry/rect.h +++ b/impeller/geometry/rect.h @@ -483,8 +483,6 @@ struct TRect { TPoint origin; TSize size; // NOLINTEND - - friend class PathBuilder; }; using Rect = TRect;