From 19680779846e8bb596d58bd54298eae5e465df71 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Wed, 4 Nov 2026 14:53:30 -0800 Subject: [PATCH] UI-1676: Ignore hidden symbol tint when expanding --- crates/engine/src/cmd/brushsym/symbols.rs | 6 ++---- crates/engine/src/tests/brushsym.rs | 26 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/crates/engine/src/cmd/brushsym/symbols.rs b/crates/engine/src/cmd/brushsym/symbols.rs index 77a61c58a..6ab7acad0 100644 --- a/crates/engine/src/cmd/brushsym/symbols.rs +++ b/crates/engine/src/cmd/brushsym/symbols.rs @@ -347,10 +347,8 @@ fn expanded_instance(d: &mut Document, inst: &Node, own: bool) -> Option { let NodeKind::SymbolInstance { symbol, xf } = &inst.kind else { return None }; let sym = d.symbols.iter().find(|s| &s.name == symbol)?; let mut art = if own { vectorcraft_doc::symbol_overrides::dynamic_art(&sym.art, inst) } else { (*sym.art).clone() }; - if let Some(f) = inst.appearance.fill() - && let Some(c) = f.paint.color() - { - brush::tint_node(&mut art, &c, f.opacity); + if let Some((color, amount)) = brush::stain(inst) { + brush::tint_node(&mut art, &color, amount); } let art = d.place_symbol_art(symbol, &art, *xf)?; let mut art = d.reid(&art); diff --git a/crates/engine/src/tests/brushsym.rs b/crates/engine/src/tests/brushsym.rs index 7a28b922b..4784831ef 100644 --- a/crates/engine/src/tests/brushsym.rs +++ b/crates/engine/src/tests/brushsym.rs @@ -1224,6 +1224,32 @@ fn place_and_break_link_round_trip_geometry() { assert_eq!(n.appearance.stroke_width(), 1.0, "strokes are not scaled by normalisation"); } +#[test] +fn hidden_instance_fill_does_not_tint_expanded_symbol_art() { + for command in ["symbol.breakLink", "object.expand"] { + let mut s = session(); + let source = rect(&mut s, 100.0, 50.0, 80.0, 40.0); + s.execute("paint.setFill", &json!({"ids": [source.0], "color": "#0000ff"})).unwrap(); + let inst = NodeId(s.execute("symbol.new", &json!({"name": "Blue Box"})).unwrap()["id"].as_u64().unwrap()); + s.execute("appearance.addFill", &json!({"ids": [inst.0]})).unwrap(); + let fill = node(&s, inst).appearance.items.len() - 1; + s.execute("appearance.setItem", &json!({"ids": [inst.0], "index": fill, "color": "#ff0000"})).unwrap(); + let center = |s: &Session| { + let doc = s.doc().unwrap().doc.clone(); + vectorcraft_render::Renderer::new().render_region(&doc, Rect::new(0.0, 0.0, 400.0, 300.0), 1.0, true).pixel(140, 70) + }; + let tinted = center(&s); + assert!(tinted[0] > tinted[2], "the visible instance fill tints the symbol: {tinted:?}"); + s.execute("appearance.setItem", &json!({"ids": [inst.0], "index": fill, "visible": false})).unwrap(); + let original = center(&s); + assert!(original[2] > original[0], "hiding the fill restores the blue symbol: {original:?}"); + + let params = if command == "symbol.breakLink" { json!({"ids": [inst.0]}) } else { json!({"object": true, "fill": false, "stroke": false}) }; + s.execute(command, ¶ms).unwrap(); + assert_eq!(center(&s), original, "{command} must keep the untinted colors"); + } +} + #[test] fn break_link_then_update_redefines_all_instances() { let mut s = session();