🐛 Do not apply stroke style to caps (#11744)

This commit is contained in:
Elena Torró 2026-09-17 09:39:39 +02:00 committed by GitHub
parent 729cc5a828
commit cc9c60507d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 70 additions and 0 deletions

View File

@ -409,6 +409,8 @@ pub(super) fn handle_stroke_caps(
if let [first_point, .., last_point] = points.as_slice() {
let mut paint_stroke = paint.clone();
paint_stroke.set_path_effect(None);
if let Some(filter) = blur {
paint_stroke.set_image_filter(filter.clone());
}

View File

@ -423,4 +423,43 @@ mod tests {
assert!(bounds.left < -1., "bounds: {bounds:?}");
assert!(bounds.right > 104., "bounds: {bounds:?}");
}
#[test]
fn dashed_stroke_keeps_solid_caps() {
let stroke = Stroke::new_center_stroke(
4.,
StrokeStyle::Dashed,
Some(StrokeCap::Round),
Some(StrokeCap::Round),
Some(7.),
Some(7.),
);
let selrect = Rect::from_xywh(0., 0., 100., 0.);
let path = stroke_to_path(&stroke, &horizontal_line(), None, &selrect, None, false)
.expect("stroke outline")
.to_skia_path(None);
assert!(path.contains((-1.5, 0.)), "start cap missing");
assert!(path.contains((101.5, 0.)), "end cap missing");
}
#[test]
fn dashed_stroke_marker_caps_are_not_dashed() {
let stroke = Stroke::new_center_stroke(
4.,
StrokeStyle::Dashed,
None,
Some(StrokeCap::SquareMarker),
Some(3.),
Some(3.),
);
let selrect = Rect::from_xywh(0., 0., 100., 0.);
let path = stroke_to_path(&stroke, &horizontal_line(), None, &selrect, None, false)
.expect("stroke outline")
.to_skia_path(None);
for x in [100., 102., 104., 106., 107.5] {
assert!(path.contains((x, 0.)), "marker has a gap at x = {x}");
}
}
}

View File

@ -463,6 +463,9 @@ impl Stroke {
/// so this is a no-op on closed paths and avoids the extra fill draw the
/// manual caps would otherwise require on open paths.
pub fn to_skia_linecap(&self) -> Option<skia::paint::Cap> {
if self.style != StrokeStyle::Solid {
return None;
}
match (self.cap_start, self.cap_end) {
(Some(StrokeCap::Round), Some(StrokeCap::Round)) => Some(skia::paint::Cap::Round),
(Some(StrokeCap::Square), Some(StrokeCap::Square)) => Some(skia::paint::Cap::Square),
@ -587,6 +590,32 @@ mod tests {
assert_eq!(dashed.style_at_scale(0.05), StrokeStyle::Dashed);
}
#[test]
fn native_linecap_is_used_for_solid_strokes() {
let solid = Stroke::new_center_stroke(
4.0,
StrokeStyle::Solid,
Some(StrokeCap::Round),
Some(StrokeCap::Round),
None,
None,
);
assert_eq!(solid.to_skia_linecap(), Some(skia::paint::Cap::Round));
}
#[test]
fn native_linecap_is_skipped_for_dashed_strokes() {
let dashed = Stroke::new_center_stroke(
4.0,
StrokeStyle::Dashed,
Some(StrokeCap::Round),
Some(StrokeCap::Round),
None,
None,
);
assert_eq!(dashed.to_skia_linecap(), None);
}
#[test]
fn path_lod_never_drops_thin_stroke() {
// Hairline strokes must still paint (stroke-only icons).