From 6f02b89434a0368b8554a929ecea297aff08d6ff Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 28 Mar 2022 11:54:09 -0700 Subject: [PATCH] Wire up stroke cap/join/miter limit display list ops (#105) --- impeller/aiks/paint.cc | 3 ++ impeller/aiks/paint.h | 4 ++ .../display_list/display_list_dispatcher.cc | 31 ++++++++++--- .../display_list/display_list_unittests.cc | 46 +++++++++++++++++++ 4 files changed, 77 insertions(+), 7 deletions(-) diff --git a/impeller/aiks/paint.cc b/impeller/aiks/paint.cc index d79a67b71453a..ac1f712908fc5 100644 --- a/impeller/aiks/paint.cc +++ b/impeller/aiks/paint.cc @@ -23,6 +23,9 @@ std::shared_ptr Paint::CreateContentsForEntity() const { auto solid_stroke = std::make_shared(); solid_stroke->SetColor(color.Premultiply()); solid_stroke->SetStrokeSize(stroke_width); + solid_stroke->SetStrokeMiter(stroke_miter); + solid_stroke->SetStrokeCap(stroke_cap); + solid_stroke->SetStrokeJoin(stroke_join); return solid_stroke; } } diff --git a/impeller/aiks/paint.h b/impeller/aiks/paint.h index a559c4c1a9fa9..be9262d0225ac 100644 --- a/impeller/aiks/paint.h +++ b/impeller/aiks/paint.h @@ -8,6 +8,7 @@ #include "flutter/fml/macros.h" #include "impeller/entity/contents/contents.h" +#include "impeller/entity/contents/solid_stroke_contents.h" #include "impeller/entity/entity.h" #include "impeller/geometry/color.h" @@ -21,6 +22,9 @@ struct Paint { Color color = Color::Black(); Scalar stroke_width = 0.0; + SolidStrokeContents::Cap stroke_cap = SolidStrokeContents::Cap::kButt; + SolidStrokeContents::Join stroke_join = SolidStrokeContents::Join::kMiter; + Scalar stroke_miter = 4.0; Style style = Style::kFill; Entity::BlendMode blend_mode = Entity::BlendMode::kSourceOver; std::shared_ptr contents; diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index 6ca0db6fc682a..6dba4f2fbd0b9 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -8,6 +8,7 @@ #include "flutter/fml/trace_event.h" #include "impeller/entity/contents/linear_gradient_contents.h" +#include "impeller/entity/contents/solid_stroke_contents.h" #include "impeller/entity/entity.h" #include "impeller/geometry/path_builder.h" #include "impeller/typographer/backends/skia/text_frame_skia.h" @@ -65,17 +66,37 @@ void DisplayListDispatcher::setStrokeWidth(SkScalar width) { // |flutter::Dispatcher| void DisplayListDispatcher::setStrokeMiter(SkScalar limit) { - UNIMPLEMENTED; + paint_.stroke_miter = limit; } // |flutter::Dispatcher| void DisplayListDispatcher::setStrokeCap(SkPaint::Cap cap) { - UNIMPLEMENTED; + switch (cap) { + case SkPaint::kButt_Cap: + paint_.stroke_cap = SolidStrokeContents::Cap::kButt; + break; + case SkPaint::kRound_Cap: + paint_.stroke_cap = SolidStrokeContents::Cap::kRound; + break; + case SkPaint::kSquare_Cap: + paint_.stroke_cap = SolidStrokeContents::Cap::kSquare; + break; + } } // |flutter::Dispatcher| void DisplayListDispatcher::setStrokeJoin(SkPaint::Join join) { - UNIMPLEMENTED; + switch (join) { + case SkPaint::kMiter_Join: + paint_.stroke_join = SolidStrokeContents::Join::kMiter; + break; + case SkPaint::kRound_Join: + paint_.stroke_join = SolidStrokeContents::Join::kRound; + break; + case SkPaint::kBevel_Join: + paint_.stroke_join = SolidStrokeContents::Join::kBevel; + break; + } } static Point ToPoint(const SkPoint& point) { @@ -397,11 +418,9 @@ static Path ToPath(const SkPath& path) { builder.MoveTo(ToPoint(data.points[0])); break; case SkPath::kLine_Verb: - builder.LineTo(ToPoint(data.points[0])); builder.LineTo(ToPoint(data.points[1])); break; case SkPath::kQuad_Verb: - builder.LineTo(ToPoint(data.points[0])); builder.QuadraticCurveTo(ToPoint(data.points[1]), ToPoint(data.points[2])); break; @@ -422,13 +441,11 @@ static Path ToPath(const SkPath& path) { curve_index < curve_count; // curve_index++, point_index += 2 // ) { - builder.LineTo(ToPoint(points[point_index + 0])); builder.QuadraticCurveTo(ToPoint(points[point_index + 1]), ToPoint(points[point_index + 2])); } } break; case SkPath::kCubic_Verb: - builder.LineTo(ToPoint(data.points[0])); builder.CubicCurveTo(ToPoint(data.points[1]), ToPoint(data.points[2]), ToPoint(data.points[3])); break; diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc index 6fef7b37f5c89..ecfaf36e23fe9 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -5,6 +5,7 @@ #include "flutter/display_list/display_list_builder.h" #include "flutter/testing/testing.h" #include "impeller/display_list/display_list_playground.h" +#include "third_party/skia/include/core/SkPathBuilder.h" namespace impeller { namespace testing { @@ -26,5 +27,50 @@ TEST_F(DisplayListTest, CanDrawTextBlob) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +TEST_F(DisplayListTest, CapsAndJoins) { + flutter::DisplayListBuilder builder; + + builder.setStyle(SkPaint::Style::kStroke_Style); + builder.setStrokeWidth(30); + builder.setColor(SK_ColorRED); + + auto path = + SkPathBuilder{}.moveTo(-50, 0).lineTo(0, -50).lineTo(50, 0).snapshot(); + + builder.translate(100, 100); + { + builder.setStrokeCap(SkPaint::Cap::kButt_Cap); + builder.setStrokeJoin(SkPaint::Join::kMiter_Join); + builder.setStrokeMiter(4); + builder.drawPath(path); + } + + { + builder.save(); + builder.translate(0, 100); + // The joint in the path is 45 degrees. A miter length of 1 convert to a + // bevel in this case. + builder.setStrokeMiter(1); + builder.drawPath(path); + builder.restore(); + } + + builder.translate(150, 0); + { + builder.setStrokeCap(SkPaint::Cap::kSquare_Cap); + builder.setStrokeJoin(SkPaint::Join::kBevel_Join); + builder.drawPath(path); + } + + builder.translate(150, 0); + { + builder.setStrokeCap(SkPaint::Cap::kRound_Cap); + builder.setStrokeJoin(SkPaint::Join::kRound_Join); + builder.drawPath(path); + } + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + } // namespace testing } // namespace impeller