[Impeller] Enforce a minimum stroke width (flutter/engine#35576)

This commit is contained in:
Jim Graham 2022-08-23 16:28:14 -07:00 committed by GitHub
parent df37ee305f
commit 979fc44c48
2 changed files with 47 additions and 3 deletions

View File

@ -521,5 +521,39 @@ TEST_P(DisplayListTest, CanDrawShadow) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(DisplayListTest, CanDrawZeroWidthLine) {
flutter::DisplayListBuilder builder;
std::vector<flutter::DlStrokeCap> caps = {
flutter::DlStrokeCap::kButt,
flutter::DlStrokeCap::kRound,
flutter::DlStrokeCap::kSquare,
};
flutter::DlPaint paint = //
flutter::DlPaint() //
.setColor(flutter::DlColor::kWhite()) //
.setDrawStyle(flutter::DlDrawStyle::kStroke) //
.setStrokeWidth(0);
flutter::DlPaint outline_paint = //
flutter::DlPaint() //
.setColor(flutter::DlColor::kYellow()) //
.setDrawStyle(flutter::DlDrawStyle::kStroke) //
.setStrokeCap(flutter::DlStrokeCap::kSquare) //
.setStrokeWidth(1);
SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
for (auto cap : caps) {
paint.setStrokeCap(cap);
builder.drawLine({50, 50}, {60, 50}, paint);
builder.drawRect({45, 45, 65, 55}, outline_paint);
builder.drawLine({100, 50}, {100, 50}, paint);
if (cap != flutter::DlStrokeCap::kButt) {
builder.drawRect({95, 45, 105, 55}, outline_paint);
}
builder.drawPath(path, paint);
builder.drawRect(path.getBounds().makeOutset(5, 5), outline_paint);
builder.translate(0, 150);
}
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
} // namespace testing
} // namespace impeller

View File

@ -52,8 +52,13 @@ std::optional<Rect> SolidStrokeContents::GetCoverage(
if (join_ == Join::kMiter) {
max_radius = std::max(max_radius, miter_limit_ * 0.5f);
}
Scalar determinant = entity.GetTransformation().GetDeterminant();
if (determinant == 0) {
return std::nullopt;
}
Scalar min_size = 1.0f / sqrt(std::abs(determinant));
Vector2 max_radius_xy = entity.GetTransformation().TransformDirection(
Vector2(max_radius, max_radius) * stroke_size_);
Vector2(max_radius, max_radius) * std::max(stroke_size_, min_size));
return Rect(path_coverage.origin - max_radius_xy,
Size(path_coverage.size.width + max_radius_xy.x * 2,
@ -182,7 +187,7 @@ static VertexBuffer CreateSolidStrokeVertices(
bool SolidStrokeContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
if (stroke_size_ <= 0.0) {
if (stroke_size_ < 0.0) {
return true;
}
@ -192,7 +197,12 @@ bool SolidStrokeContents::Render(const ContentContext& renderer,
VS::VertInfo vert_info;
vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
entity.GetTransformation();
vert_info.size = stroke_size_;
Scalar determinant = entity.GetTransformation().GetDeterminant();
if (determinant == 0) {
return true;
}
Scalar min_size = 1.0f / sqrt(std::abs(determinant));
vert_info.size = std::max(stroke_size_, min_size);
FS::FragInfo frag_info;
frag_info.color = color_.Premultiply();