diff --git a/crates/engine/src/cmd/appearance.rs b/crates/engine/src/cmd/appearance.rs index b4c8ad42e..17f7d6941 100644 --- a/crates/engine/src/cmd/appearance.rs +++ b/crates/engine/src/cmd/appearance.rs @@ -522,6 +522,11 @@ fn set_item(s: &mut Session, p: &Value) -> Result { s.edit("Appearance", |d, _| { for id in &ids { let Some(n) = d.node_mut(*id) else { continue }; + if p.get("weight").is_none() + && let Some(pa) = &paint + { + super::paint::restore_unpainted_stroke(&mut n.appearance, Some(idx), pa); + } let bounds = n.geometric_bounds(); let Some(item) = n.appearance.items.get_mut(idx) else { continue }; let (pp, op, bl, vis, bounds) = match item { diff --git a/crates/engine/src/cmd/paint.rs b/crates/engine/src/cmd/paint.rs index a8c73694a..9406faf48 100644 --- a/crates/engine/src/cmd/paint.rs +++ b/crates/engine/src/cmd/paint.rs @@ -502,7 +502,7 @@ fn set_run_stroke(style: &mut CharStyle, paint: Paint) { } /// Use the existing 1 pt default when adding paint to an unpainted zero-width stroke. -fn restore_unpainted_stroke(ap: &mut Appearance, index: Option, paint: &Paint) { +pub(super) fn restore_unpainted_stroke(ap: &mut Appearance, index: Option, paint: &Paint) { if !paint.is_none() && let Some(stroke) = ap.stroke_at_mut(index) && stroke.paint.is_none() diff --git a/crates/engine/tests/stroke_visibility.rs b/crates/engine/tests/stroke_visibility.rs index 442d52cf3..f9c574ab7 100644 --- a/crates/engine/tests/stroke_visibility.rs +++ b/crates/engine/tests/stroke_visibility.rs @@ -105,3 +105,15 @@ fn existing_weights_and_explicitly_zero_painted_strokes_keep_their_widths() { s.execute("paint.setStroke", &json!({"none": true})).unwrap(); assert_eq!(width(&s, id), 0.0, "fill edits and removing paint do not enable a stroke"); } + +#[test] +fn appearance_panel_stroke_colour_restores_an_unpainted_zero_width_stroke() { + let (mut s, id) = fixture(); + s.execute("paint.setStroke", &json!({"none": true})).unwrap(); + s.execute("stroke.set", &json!({"weight": 0})).unwrap(); + s.execute("appearance.setItem", &json!({"index": 1, "color": "#00ff00"})).unwrap(); + assert_eq!(width(&s, id), 1.0); + s.execute("appearance.setItem", &json!({"index": 1, "weight": 0})).unwrap(); + s.execute("appearance.setItem", &json!({"index": 1, "color": "#0000ff"})).unwrap(); + assert_eq!(width(&s, id), 0.0, "a painted stroke keeps an explicit zero width"); +}