mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-07 13:23:22 +00:00
Symbols: an instance fill with no opacity keeps the art's swatch links
A symbol instance whose fill has an opacity of 0 no longer counts as stained. Expand Appearance and the other places that build an instance's art used to rebuild every solid paint as an unlinked color even though the tint changed nothing, so the art lost its global and spot swatch links.
This commit is contained in:
@@ -132,9 +132,10 @@ pub fn tint_node(n: &mut Node, color: &Color, amount: f32) {
|
||||
}
|
||||
|
||||
/// The stain instance `inst` puts on its symbol's art: its visible fill colour and that fill's
|
||||
/// opacity (how far the art mixes towards it). `None` for an unstained instance.
|
||||
/// opacity (how far the art mixes towards it). `None` for an unstained instance, including one
|
||||
/// whose fill has an opacity of 0, so its art keeps its paints and their swatch links.
|
||||
pub fn stain(inst: &Node) -> Option<(Color, f32)> {
|
||||
let f = inst.appearance.fill().filter(|f| f.visible)?;
|
||||
let f = inst.appearance.fill().filter(|f| f.visible && f.opacity > 0.0)?;
|
||||
Some((f.paint.color()?, f.opacity))
|
||||
}
|
||||
|
||||
|
||||
@@ -764,6 +764,26 @@ fn stain_mixes_type_strokes_too() {
|
||||
assert_eq!(run_paints(&[art]), [(Paint::solid(blue), Paint::solid(blue))]);
|
||||
}
|
||||
|
||||
/// An instance whose fill has an opacity of 0 does not stain its symbol's art, so the art keeps its
|
||||
/// swatch links.
|
||||
#[test]
|
||||
fn a_fill_with_no_opacity_leaves_the_symbol_art_linked() {
|
||||
let spot = Paint::Solid { color: Color::cmyk(1.0, 0.7, 0.0, 0.4), swatch: Some("Spot".into()), tint: 1.0 };
|
||||
let art = Node::path(NodeId(1), shapes::rectangle(Rect::new(0.0, 0.0, 10.0, 10.0)), Appearance::basic(spot.clone(), Paint::None, 0.0));
|
||||
let mut inst = Node::new(NodeId(2), NodeKind::SymbolInstance { symbol: "Dot".into(), xf: Affine::IDENTITY });
|
||||
inst.appearance = Appearance::basic(Paint::solid(Color::rgb(1.0, 0.0, 0.0)), Paint::None, 0.0).into();
|
||||
if let Some(f) = inst.appearance.fill_mut() {
|
||||
f.opacity = 0.0;
|
||||
}
|
||||
assert_eq!(stain(&inst), None);
|
||||
assert_eq!(instance_art(&art, &inst).appearance.fill_paint(), spot);
|
||||
// Any opacity above 0 still stains.
|
||||
if let Some(f) = inst.appearance.fill_mut() {
|
||||
f.opacity = 0.01;
|
||||
}
|
||||
assert_ne!(instance_art(&art, &inst).appearance.fill_paint(), spot);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn library_defaults_store_and_find() {
|
||||
let mut d = Document::new(100.0, 100.0);
|
||||
|
||||
@@ -75,6 +75,34 @@ fn symbol_instance_tint_survives_expanding_an_object_effect() {
|
||||
assert!(differing(&before, &after, 8) < 200, "expanding changed {} pixels", differing(&before, &after, 8));
|
||||
}
|
||||
|
||||
/// An instance fill with an opacity of 0 does not tint the symbol's art, so expanding keeps the
|
||||
/// art's global swatch link.
|
||||
#[test]
|
||||
fn a_symbol_instance_fill_with_no_opacity_keeps_swatch_links_when_expanded() {
|
||||
let mut s = session();
|
||||
let sq = square(&mut s);
|
||||
run(&mut s, "swatch.new", json!({"name": "Brand", "color": "#2a6fb0", "global": true}));
|
||||
run(&mut s, "paint.setFill", json!({"ids": [sq.0], "swatch": "Brand"}));
|
||||
let id = NodeId(run(&mut s, "symbol.new", json!({"name": "Linked 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": 0}));
|
||||
run(&mut s, "effect.apply", json!({"ids": [id.0], "item": null, "effect": "path.offsetPath", "params": {"offset": 6}}));
|
||||
assert!(expandable(&s));
|
||||
|
||||
run(&mut s, "effect.expandAppearance", json!({}));
|
||||
let n = node(&s, id);
|
||||
assert!(!matches!(n.kind, NodeKind::SymbolInstance { .. }));
|
||||
let mut linked = 0;
|
||||
n.walk(&mut |part| {
|
||||
if let vectorcraft_color::Paint::Solid { swatch: Some(name), .. } = part.appearance.fill_paint() {
|
||||
assert_eq!(name, "Brand");
|
||||
linked += 1;
|
||||
}
|
||||
});
|
||||
assert!(linked > 0, "the expanded art keeps the Brand swatch link");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_fills_and_an_offset_stroke_become_three_paths_that_look_the_same() {
|
||||
let mut s = session();
|
||||
|
||||
Reference in New Issue
Block a user