[Impeller] Move to the new location before rendering a stroke path contour containing only one point (#165940)

Fixes https://github.com/flutter/flutter/issues/165190
This commit is contained in:
Jason Simmons
2025-03-27 15:27:03 +00:00
committed by GitHub
parent 31ed3b7b83
commit e17287da31
3 changed files with 38 additions and 13 deletions

View File

@@ -641,5 +641,25 @@ TEST_P(AiksTest, CanRenderOverlappingMultiContourPath) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(AiksTest, TwoContourPathWithSinglePointContour) {
DisplayListBuilder builder;
DlPaint paint;
paint.setColor(DlColor::kRed());
paint.setDrawStyle(DlDrawStyle::kStroke);
paint.setStrokeWidth(15.0);
paint.setStrokeCap(DlStrokeCap::kRound);
DlPathBuilder path_builder;
path_builder.MoveTo(DlPoint(100, 100));
path_builder.LineTo(DlPoint(150, 150));
path_builder.MoveTo(DlPoint(200, 200));
path_builder.LineTo(DlPoint(200, 200));
builder.DrawPath(DlPath(path_builder), paint);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
} // namespace testing
} // namespace impeller

View File

@@ -87,22 +87,10 @@ class StrokeGenerator {
polyline.GetContourPointBounds(contour_i);
size_t contour_delta = contour_end_point_i - contour_start_point_i;
if (contour_delta == 1) {
Point p = polyline.GetPoint(contour_start_point_i);
cap_proc(vtx_builder, p, {-stroke_width * 0.5f, 0}, scale,
/*reverse=*/false);
cap_proc(vtx_builder, p, {stroke_width * 0.5f, 0}, scale,
/*reverse=*/false);
continue;
} else if (contour_delta == 0) {
if (contour_delta == 0) {
continue; // This contour has no renderable content.
}
previous_offset = offset;
offset = ComputeOffset(contour_start_point_i, contour_start_point_i,
contour_end_point_i, contour);
const Point contour_first_offset = offset.GetVector();
if (contour_i > 0) {
// This branch only executes when we've just finished drawing a contour
// and are switching to a new one.
@@ -125,6 +113,20 @@ class StrokeGenerator {
vtx_builder.AppendVertex(vtx.position);
}
if (contour_delta == 1) {
Point p = polyline.GetPoint(contour_start_point_i);
cap_proc(vtx_builder, p, {-stroke_width * 0.5f, 0}, scale,
/*reverse=*/false);
cap_proc(vtx_builder, p, {stroke_width * 0.5f, 0}, scale,
/*reverse=*/false);
continue;
}
previous_offset = offset;
offset = ComputeOffset(contour_start_point_i, contour_start_point_i,
contour_end_point_i, contour);
const Point contour_first_offset = offset.GetVector();
// Generate start cap.
if (!polyline.contours[contour_i].is_closed) {
Point cap_offset =

View File

@@ -963,6 +963,9 @@ impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrec
impeller_Play_AiksTest_TransparentShadowProducesCorrectColor_Metal.png
impeller_Play_AiksTest_TransparentShadowProducesCorrectColor_OpenGLES.png
impeller_Play_AiksTest_TransparentShadowProducesCorrectColor_Vulkan.png
impeller_Play_AiksTest_TwoContourPathWithSinglePointContour_Metal.png
impeller_Play_AiksTest_TwoContourPathWithSinglePointContour_OpenGLES.png
impeller_Play_AiksTest_TwoContourPathWithSinglePointContour_Vulkan.png
impeller_Play_AiksTest_VerifyNonOptimizedGradient_Metal.png
impeller_Play_AiksTest_VerifyNonOptimizedGradient_OpenGLES.png
impeller_Play_AiksTest_VerifyNonOptimizedGradient_Vulkan.png