Wire up stroke cap/join/miter limit display list ops (flutter/engine#105)

This commit is contained in:
Brandon DeRosier 2022-03-28 11:54:09 -07:00 committed by Dan Field
parent 8e42425e96
commit 83f102353c
4 changed files with 77 additions and 7 deletions

View File

@ -23,6 +23,9 @@ std::shared_ptr<Contents> Paint::CreateContentsForEntity() const {
auto solid_stroke = std::make_shared<SolidStrokeContents>();
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;
}
}

View File

@ -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> contents;

View File

@ -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;

View File

@ -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