This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] Fixes stroke path geometry that can draw outside of path if the path ends at sharp turn. #45252
Merged
Merged
[Impeller] Fixes stroke path geometry that can draw outside of path if the path ends at sharp turn. #45252
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
2752bdf
Adds sections to contour to record curve flag
chunhtai 311248c
update
chunhtai be3e636
comment
chunhtai 201d9de
update
chunhtai 1e38853
format
chunhtai 0ed9510
update
chunhtai ca72e9b
format
chunhtai 87a0e2d
Fix more curve
chunhtai ef08968
addressing comments
chunhtai File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -253,6 +253,7 @@ StrokePathGeometry::CreateSolidStrokeVertices( | |
for (size_t contour_i = 0; contour_i < polyline.contours.size(); | ||
contour_i++) { | ||
auto contour = polyline.contours[contour_i]; | ||
size_t contour_component_i = 0; | ||
size_t contour_start_point_i, contour_end_point_i; | ||
std::tie(contour_start_point_i, contour_end_point_i) = | ||
polyline.GetContourPointBounds(contour_i); | ||
|
@@ -308,27 +309,55 @@ StrokePathGeometry::CreateSolidStrokeVertices( | |
// Generate contour geometry. | ||
for (size_t point_i = contour_start_point_i + 1; | ||
point_i < contour_end_point_i; point_i++) { | ||
if ((contour_component_i + 1 >= contour.components.size()) && | ||
contour.components[contour_component_i + 1].component_start_index <= | ||
point_i) { | ||
// The point_i has entered the next component in this contour. | ||
contour_component_i += 1; | ||
} | ||
// Generate line rect. | ||
vtx.position = polyline.points[point_i - 1] + offset; | ||
vtx_builder.AppendVertex(vtx); | ||
vtx.position = polyline.points[point_i - 1] - offset; | ||
vtx_builder.AppendVertex(vtx); | ||
vtx.position = polyline.points[point_i] + offset; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was where the complete rect is drawn. This part is now handle by the join when then draw the first pair of inner miter point and outer |
||
vtx_builder.AppendVertex(vtx); | ||
vtx.position = polyline.points[point_i] - offset; | ||
vtx_builder.AppendVertex(vtx); | ||
|
||
if (point_i < contour_end_point_i - 1) { | ||
compute_offset(point_i + 1); | ||
auto is_end_of_contour = point_i == contour_end_point_i - 1; | ||
|
||
if (!contour.components[contour_component_i].is_curve) { | ||
// For line components, two additional points need to be appended prior | ||
// to appending a join connecting the next component. | ||
vtx.position = polyline.points[point_i] + offset; | ||
vtx_builder.AppendVertex(vtx); | ||
vtx.position = polyline.points[point_i] - offset; | ||
vtx_builder.AppendVertex(vtx); | ||
|
||
// Generate join from the current line to the next line. | ||
join_proc(vtx_builder, polyline.points[point_i], previous_offset, | ||
offset, scaled_miter_limit, scale); | ||
if (!is_end_of_contour) { | ||
compute_offset(point_i + 1); | ||
// Generate join from the current line to the next line. | ||
join_proc(vtx_builder, polyline.points[point_i], previous_offset, | ||
offset, scaled_miter_limit, scale); | ||
} | ||
} else { | ||
// For curve components, the polyline is detailed enough such that | ||
// it can avoid worrying about joins altogether. | ||
if (!is_end_of_contour) { | ||
compute_offset(point_i + 1); | ||
} else { | ||
// If this is a curve and is the end of the contour, two end points | ||
// need to be drawn with the contour end_direction. | ||
auto end_offset = | ||
Vector2(-contour.end_direction.y, contour.end_direction.x) * | ||
stroke_width * 0.5; | ||
vtx.position = polyline.points[contour_end_point_i - 1] + end_offset; | ||
vtx_builder.AppendVertex(vtx); | ||
vtx.position = polyline.points[contour_end_point_i - 1] - end_offset; | ||
vtx_builder.AppendVertex(vtx); | ||
} | ||
} | ||
} | ||
|
||
// Generate end cap or join. | ||
if (!polyline.contours[contour_i].is_closed) { | ||
if (!contour.is_closed) { | ||
auto cap_offset = | ||
Vector2(-contour.end_direction.y, contour.end_direction.x) * | ||
stroke_width * 0.5; // Clockwise normal | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -324,9 +324,10 @@ Path::Polyline Path::CreatePolyline(Scalar scale) const { | |
return Vector2(0, -1); | ||
}; | ||
|
||
std::vector<PolylineContour::Component> components; | ||
std::optional<size_t> previous_path_component_index; | ||
auto end_contour = [&polyline, &previous_path_component_index, | ||
&get_path_component]() { | ||
&get_path_component, &components]() { | ||
// Whenever a contour has ended, extract the exact end direction from the | ||
// last component. | ||
if (polyline.contours.empty()) { | ||
|
@@ -339,6 +340,8 @@ Path::Polyline Path::CreatePolyline(Scalar scale) const { | |
|
||
auto& contour = polyline.contours.back(); | ||
contour.end_direction = Vector2(0, 1); | ||
contour.components = components; | ||
components.clear(); | ||
|
||
size_t previous_index = previous_path_component_index.value(); | ||
while (!std::holds_alternative<std::monostate>( | ||
|
@@ -363,14 +366,26 @@ Path::Polyline Path::CreatePolyline(Scalar scale) const { | |
const auto& component = components_[component_i]; | ||
switch (component.type) { | ||
case ComponentType::kLinear: | ||
components.push_back({ | ||
.component_start_index = polyline.points.size(), | ||
.is_curve = false, | ||
}); | ||
collect_points(linears_[component.index].CreatePolyline()); | ||
previous_path_component_index = component_i; | ||
break; | ||
case ComponentType::kQuadratic: | ||
components.push_back({ | ||
.component_start_index = polyline.points.size(), | ||
.is_curve = true, | ||
}); | ||
collect_points(quads_[component.index].CreatePolyline(scale)); | ||
previous_path_component_index = component_i; | ||
break; | ||
case ComponentType::kCubic: | ||
components.push_back({ | ||
.component_start_index = polyline.points.size(), | ||
.is_curve = true, | ||
}); | ||
collect_points(cubics_[component.index].CreatePolyline(scale)); | ||
previous_path_component_index = component_i; | ||
break; | ||
|
@@ -386,13 +401,14 @@ Path::Polyline Path::CreatePolyline(Scalar scale) const { | |
const auto& contour = contours_[component.index]; | ||
polyline.contours.push_back({.start_index = polyline.points.size(), | ||
.is_closed = contour.is_closed, | ||
.start_direction = start_direction}); | ||
.start_direction = start_direction, | ||
.components = components}); | ||
previous_contour_point = std::nullopt; | ||
collect_points({contour.destination}); | ||
break; | ||
} | ||
end_contour(); | ||
} | ||
end_contour(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice find. :) |
||
return polyline; | ||
} | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not too familiar with the code, let me know if this is enough to set up golden test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, this is the correct way to add a golden. 👍