Expand the stroke of stroked type into filled outlines

Fixes #4306

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-29 09:57:34 +07:00
committed by bflatastic
co-authored by Claude Opus 5.5
parent 6026772765
commit bcbc8a1713
2 changed files with 30 additions and 1 deletions
+5 -1
View File
@@ -131,7 +131,11 @@ impl Expandable {
e.placed |= matches!(c.kind, NodeKind::PlacedDocument(_));
e.repeats |= matches!(c.kind, NodeKind::Repeat(_));
e.intertwines |= matches!(c.kind, NodeKind::Intertwine { .. });
e.stroke |= shape && !c.appearance.stroke_paint().is_none();
e.stroke |= match &c.kind {
// Type's outlines take its characters' stroke (see `type.createOutlines`).
NodeKind::Text(t) => t.runs.iter().any(|r| r.style.has_stroke()),
_ => shape && !c.appearance.stroke_paint().is_none(),
};
e.gradient |= match &c.kind {
NodeKind::Text(t) => t.runs.iter().any(|r| matches!(r.style.fill, Paint::Gradient(_))),
_ => shape && c.appearance.items.iter().any(|i| gradient_fill(i).is_some()),
+25
View File
@@ -645,6 +645,31 @@ fn expand_live_shape_and_text_in_one_undo_step() {
assert!(s.doc().unwrap().doc.node(t).is_some());
}
#[test]
fn expand_text_outlines_its_stroke_too() {
let mut s = session();
let t = text(&mut s, "Hi");
sel(&mut s, &[t]);
s.execute("paint.setStroke", &json!({"color": "#ff0000"})).unwrap();
let info = s.execute("object.expand.info", &json!({})).unwrap();
assert_eq!(info["stroke"], json!(true), "stroked type has a stroke to expand");
let n = undo_len(&s);
s.execute("object.expand", &json!({})).unwrap();
assert_eq!(undo_len(&s), n + 1);
let d = &s.doc().unwrap().doc;
let (mut paths, mut stroked) = (0, 0);
for id in &s.doc().unwrap().selection.objects {
d.node(*id).unwrap().walk(&mut |c| {
if matches!(c.kind, NodeKind::Path { .. } | NodeKind::Compound { .. }) {
paths += 1;
stroked += usize::from(!c.appearance.stroke_paint().is_none());
}
});
}
assert!(paths > 0);
assert_eq!(stroked, 0, "every glyph's stroke became a filled outline ({paths} paths)");
}
#[test]
fn expand_nothing_errors() {
let mut s = session();