From dcefceddf6495e8bd5eeac14c6d5153edd18d8f8 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Wed, 4 Nov 2026 14:37:35 -0800 Subject: [PATCH] UI-1675: Preserve symbol tint when expanding effects --- crates/engine/src/cmd/effectcmd.rs | 2 +- crates/engine/src/tests/expand.rs | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/crates/engine/src/cmd/effectcmd.rs b/crates/engine/src/cmd/effectcmd.rs index 75ffc5021..8718e725f 100644 --- a/crates/engine/src/cmd/effectcmd.rs +++ b/crates/engine/src/cmd/effectcmd.rs @@ -765,7 +765,7 @@ fn expanded_node(d: &mut Document, mut n: Node, brushes: &[vectorcraft_brush::Br // them with a gradient or changes their fills and strokes): through their outlines. let symbol = match &n.kind { NodeKind::SymbolInstance { symbol, .. } => { - d.symbols.iter().find(|s| s.name == *symbol).map(|s| vectorcraft_doc::symbol_overrides::dynamic_art(&s.art, &n)) + d.symbols.iter().find(|s| s.name == *symbol).map(|s| vectorcraft_render::instance_art(&s.art, &n)) } _ => None, }; diff --git a/crates/engine/src/tests/expand.rs b/crates/engine/src/tests/expand.rs index 93759d2b6..c84fb9588 100644 --- a/crates/engine/src/tests/expand.rs +++ b/crates/engine/src/tests/expand.rs @@ -52,6 +52,29 @@ fn expandable(s: &Session) -> bool { s.commands().iter().find(|c| c.id == "effect.expandAppearance").unwrap().enabled } +#[test] +fn symbol_instance_tint_survives_expanding_an_object_effect() { + let mut s = session(); + square(&mut s); + let id = NodeId(run(&mut s, "symbol.new", json!({"name": "Tinted Square"}))["id"].as_u64().unwrap()); + run(&mut s, "appearance.addFill", json!({"ids": [id.0]})); + let fill = node(&s, id).appearance.items.len() - 1; + run(&mut s, "appearance.setItem", json!({"ids": [id.0], "index": fill, "color": "#00ff00", "opacity": 50})); + run(&mut s, "effect.apply", json!({"ids": [id.0], "item": null, "effect": "path.offsetPath", "params": {"offset": 6}})); + assert!(matches!(node(&s, id).kind, NodeKind::SymbolInstance { .. })); + let before = render(&s); + assert_ne!(before.pixel(100, 100), [255, 255, 255, 255], "the symbol is visible"); + assert_ne!(before.pixel(100, 100), [255, 0, 0, 255], "the instance fill tints the red symbol art"); + assert!(expandable(&s)); + + run(&mut s, "effect.expandAppearance", json!({})); + let n = node(&s, id); + assert!(!matches!(n.kind, NodeKind::SymbolInstance { .. })); + n.walk(&mut |part| assert!(part.appearance.effects.is_empty())); + let after = render(&s); + assert!(differing(&before, &after, 8) < 200, "expanding changed {} pixels", differing(&before, &after, 8)); +} + #[test] fn two_fills_and_an_offset_stroke_become_three_paths_that_look_the_same() { let mut s = session();