Skip to content

Commit 24fd06e

Browse files
authored
[Impeller] Fix stroke cap drawing not correct. (flutter#39481)
* ++ * ++
1 parent 9aa088d commit 24fd06e

3 files changed

Lines changed: 35 additions & 5 deletions

File tree

‎impeller/display_list/display_list_unittests.cc‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,34 @@ TEST_P(DisplayListTest, CanDrawArc) {
121121
static float stroke_width = 10;
122122
static bool use_center = true;
123123

124+
static int selected_cap = 0;
125+
const char* cap_names[] = {"Butt", "Round", "Square"};
126+
flutter::DlStrokeCap cap;
127+
124128
ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
125129
ImGui::SliderFloat("Start angle", &start_angle, -360, 360);
126130
ImGui::SliderFloat("Sweep angle", &sweep_angle, -360, 360);
127131
ImGui::SliderFloat("Stroke width", &stroke_width, 0, 100);
132+
ImGui::Combo("Cap", &selected_cap, cap_names,
133+
sizeof(cap_names) / sizeof(char*));
128134
ImGui::Checkbox("Use center", &use_center);
129135
ImGui::End();
130136

137+
switch (selected_cap) {
138+
case 0:
139+
cap = flutter::DlStrokeCap::kButt;
140+
break;
141+
case 1:
142+
cap = flutter::DlStrokeCap::kRound;
143+
break;
144+
case 2:
145+
cap = flutter::DlStrokeCap::kSquare;
146+
break;
147+
default:
148+
cap = flutter::DlStrokeCap::kButt;
149+
break;
150+
}
151+
131152
auto [p1, p2] = IMPELLER_PLAYGROUND_LINE(
132153
Point(200, 200), Point(400, 400), 20, Color::White(), Color::White());
133154

@@ -136,7 +157,7 @@ TEST_P(DisplayListTest, CanDrawArc) {
136157
Vector2 scale = GetContentScale();
137158
builder.scale(scale.x, scale.y);
138159
builder.setStyle(flutter::DlDrawStyle::kStroke);
139-
builder.setStrokeCap(flutter::DlStrokeCap::kButt);
160+
builder.setStrokeCap(cap);
140161
builder.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
141162
builder.setStrokeMiter(10);
142163
auto rect = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);

‎impeller/entity/geometry.cc‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
302302
HostBuffer& buffer,
303303
Scalar stroke_width,
304304
Scalar scaled_miter_limit,
305+
Cap cap,
305306
const StrokePathGeometry::JoinProc& join_proc,
306307
const StrokePathGeometry::CapProc& cap_proc,
307308
Scalar tolerance) {
@@ -370,9 +371,15 @@ VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
370371

371372
// Generate start cap.
372373
if (!polyline.contours[contour_i].is_closed) {
373-
auto cap_offset =
374-
Vector2(contour.start_direction.y, -contour.start_direction.x) *
375-
stroke_width * 0.5;
374+
Vector2 direction;
375+
if (cap == Cap::kButt) {
376+
direction =
377+
Vector2(contour.start_direction.y, -contour.start_direction.x);
378+
} else {
379+
direction =
380+
Vector2(-contour.start_direction.y, contour.start_direction.x);
381+
}
382+
auto cap_offset = direction * stroke_width * 0.5;
376383
cap_proc(vtx_builder, polyline.points[contour_start_point_i], cap_offset,
377384
tolerance);
378385
}
@@ -439,7 +446,8 @@ GeometryResult StrokePathGeometry::GetPositionBuffer(
439446
auto& host_buffer = pass.GetTransientsBuffer();
440447
auto vertex_buffer = CreateSolidStrokeVertices(
441448
path_, host_buffer, stroke_width, miter_limit_ * stroke_width_ * 0.5,
442-
GetJoinProc(stroke_join_), GetCapProc(stroke_cap_), tolerance);
449+
stroke_cap_, GetJoinProc(stroke_join_), GetCapProc(stroke_cap_),
450+
tolerance);
443451

444452
return GeometryResult{
445453
.type = PrimitiveType::kTriangleStrip,

‎impeller/entity/geometry.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ class StrokePathGeometry : public Geometry {
164164
HostBuffer& buffer,
165165
Scalar stroke_width,
166166
Scalar scaled_miter_limit,
167+
Cap cap,
167168
const JoinProc& join_proc,
168169
const CapProc& cap_proc,
169170
Scalar tolerance);

0 commit comments

Comments
 (0)