diff --git a/crates/engine/src/cmd/expand.rs b/crates/engine/src/cmd/expand.rs index b0df586cf..a62d5b18f 100644 --- a/crates/engine/src/cmd/expand.rs +++ b/crates/engine/src/cmd/expand.rs @@ -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()), diff --git a/crates/engine/src/tests/menucmds.rs b/crates/engine/src/tests/menucmds.rs index 1be9fa5fb..a1672d65c 100644 --- a/crates/engine/src/tests/menucmds.rs +++ b/crates/engine/src/tests/menucmds.rs @@ -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();