diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index a9e4b162f36bc..0460bab2f42d9 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1262,6 +1262,32 @@ TEST_P(AiksTest, CanRenderDifferencePaths) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +// Regression test for https://github.com/flutter/flutter/issues/134816. +// +// It should be possible to draw 3 lines, and not have an implicit close path. +TEST_P(AiksTest, CanDrawAnOpenPath) { + Canvas canvas; + + // Starting at (50, 50), draw lines from: + // 1. (50, height) + // 2. (width, height) + // 3. (width, 50) + PathBuilder builder; + builder.MoveTo({50, 50}); + builder.LineTo({50, 100}); + builder.LineTo({100, 100}); + builder.LineTo({100, 50}); + + Paint paint; + paint.color = Color::Red(); + paint.style = Paint::Style::kStroke; + paint.stroke_width = 10; + + canvas.DrawPath(builder.TakePath(), paint); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + static sk_sp OpenFixtureAsSkData(const char* fixture_name) { auto mapping = flutter::testing::OpenFixtureAsMapping(fixture_name); if (!mapping) { diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index edcd363a7e45c..107389deaf715 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -848,19 +848,29 @@ void DlDispatcher::drawDRRect(const SkRRect& outer, const SkRRect& inner) { // |flutter::DlOpReceiver| void DlDispatcher::drawPath(const SkPath& path) { SkRect rect; - SkRRect rrect; - SkRect oval; - if (path.isRect(&rect)) { + + // We can't "optimize" a path into a rectangle if it's open. + bool closed; + if (path.isRect(&rect, &closed); closed) { canvas_.DrawRect(skia_conversions::ToRect(rect), paint_); - } else if (path.isRRect(&rrect) && rrect.isSimple()) { + return; + } + + SkRRect rrect; + if (path.isRRect(&rrect) && rrect.isSimple()) { canvas_.DrawRRect(skia_conversions::ToRect(rrect.rect()), rrect.getSimpleRadii().fX, paint_); - } else if (path.isOval(&oval) && oval.width() == oval.height()) { + return; + } + + SkRect oval; + if (path.isOval(&oval) && oval.width() == oval.height()) { canvas_.DrawCircle(skia_conversions::ToPoint(oval.center()), oval.width() * 0.5, paint_); - } else { - canvas_.DrawPath(skia_conversions::ToPath(path), paint_); + return; } + + canvas_.DrawPath(skia_conversions::ToPath(path), paint_); } // |flutter::DlOpReceiver| diff --git a/impeller/display_list/dl_unittests.cc b/impeller/display_list/dl_unittests.cc index 70396ccdb2200..7b692363c54b1 100644 --- a/impeller/display_list/dl_unittests.cc +++ b/impeller/display_list/dl_unittests.cc @@ -411,6 +411,33 @@ TEST_P(DisplayListTest, CanDrawWithOddPathWinding) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +// Regression test for https://github.com/flutter/flutter/issues/134816. +// +// It should be possible to draw 3 lines, and not have an implicit close path. +TEST_P(DisplayListTest, CanDrawAnOpenPath) { + flutter::DisplayListBuilder builder; + flutter::DlPaint paint; + + paint.setColor(flutter::DlColor::kRed()); + paint.setDrawStyle(flutter::DlDrawStyle::kStroke); + paint.setStrokeWidth(10); + + builder.Translate(300, 300); + + // Move to (50, 50) and draw lines from: + // 1. (50, height) + // 2. (width, height) + // 3. (width, 50) + SkPath path; + path.moveTo(50, 50); + path.lineTo(50, 100); + path.lineTo(100, 100); + path.lineTo(100, 50); + builder.DrawPath(path, paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + TEST_P(DisplayListTest, CanDrawWithMaskBlur) { auto texture = CreateTextureForFixture("embarcadero.jpg"); flutter::DisplayListBuilder builder;