mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-30 04:37:29 -06:00
Swatches: global swatch edits also update graph designs and the art of brushes
Squashed from #4489 onto main.
This commit is contained in:
@@ -108,9 +108,10 @@ impl Document {
|
||||
Some(list.remove(i))
|
||||
}
|
||||
|
||||
/// Visit every colour that can link to a swatch — solid paints and gradient stops of fills,
|
||||
/// strokes and text runs — in the art (opacity masks included), symbol definitions, pattern
|
||||
/// tiles, graphic styles and the swatches themselves (tint swatches, gradient swatches' stops).
|
||||
/// Visit every color that can link to a swatch (solid paints and gradient stops of fills,
|
||||
/// strokes and text runs) in the art (opacity masks included), symbol definitions, graph
|
||||
/// designs, pattern tiles and the tile that pattern editing's Cancel puts back, graphic styles
|
||||
/// and the swatches themselves (tint swatches, gradient swatches' stops).
|
||||
/// `f(colour, link, tint)` may change them and returns true when it did
|
||||
/// ([`Paint::map_links`]). Only nodes holding a changed paint (and the paths to them) are
|
||||
/// copied. Returns the number of changed paints.
|
||||
@@ -119,7 +120,10 @@ impl Document {
|
||||
for s in &mut self.symbols {
|
||||
n += map_tree(&mut s.art, f);
|
||||
}
|
||||
for p in &mut self.patterns {
|
||||
for g in &mut self.graph_designs {
|
||||
n += map_tree(&mut g.art, f);
|
||||
}
|
||||
for p in self.patterns.iter_mut().chain(self.pattern_edit.iter_mut().filter_map(|pe| pe.original.as_mut())) {
|
||||
n += map_trees(&mut p.art, f);
|
||||
}
|
||||
for gs in &mut self.graphic_styles {
|
||||
@@ -307,6 +311,19 @@ pub fn walk_with_masks<'a>(n: &'a Node, f: &mut dyn FnMut(&'a Node)) {
|
||||
}
|
||||
}
|
||||
|
||||
/// [`Document::map_solid_paints`] for art a document keeps outside its trees, such as the art of a
|
||||
/// brush: `f` applied to the linkable colors of `n` and its subtree (opacity masks included). Only
|
||||
/// the nodes holding a changed paint are copied. Returns the number of changed paints.
|
||||
pub fn map_node_solid_paints(n: &mut Node, f: &mut LinkFn) -> usize {
|
||||
match map_node(n, f) {
|
||||
Some((new, count)) => {
|
||||
*n = new;
|
||||
count
|
||||
}
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_tree(n: &mut Arc<Node>, f: &mut LinkFn) -> usize {
|
||||
match map_node(n, f) {
|
||||
Some((new, count)) => {
|
||||
@@ -400,6 +417,25 @@ mod tests {
|
||||
assert!(Arc::ptr_eq(&d.layers[0], &again.layers[0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mapping_reaches_graph_designs_and_the_tile_that_pattern_cancel_puts_back() {
|
||||
let (mut d, a, _) = doc();
|
||||
let art = d.node_arc(a).cloned().unwrap();
|
||||
d.graph_designs.push(crate::GraphDesign { name: "Bar".into(), art: art.clone() });
|
||||
d.pattern_edit =
|
||||
Some(crate::PatternEdit { pattern: "Tile".into(), layer: NodeId(0), original: Some(crate::PatternDef::new("Tile", vec![art])) });
|
||||
let mut loose = d.node(a).unwrap().clone();
|
||||
let blue = Color::rgb(0.0, 0.0, 1.0);
|
||||
let mut to_blue = |c: &mut Color, s: &mut Option<String>, _: &mut f32| s.as_deref() == Some("Brand") && std::mem::replace(c, blue) != blue;
|
||||
assert_eq!(d.map_solid_paints(&mut to_blue), 3, "the layer's rectangle, the design and the Cancel tile");
|
||||
assert_eq!(d.graph_designs[0].art.appearance.fill_paint(), linked(blue, "Brand"));
|
||||
let tile = &d.pattern_edit.as_ref().unwrap().original.as_ref().unwrap().art[0];
|
||||
assert_eq!(tile.appearance.fill_paint(), linked(blue, "Brand"));
|
||||
assert_eq!(map_node_solid_paints(&mut loose, &mut to_blue), 1);
|
||||
assert_eq!(loose.appearance.fill_paint(), linked(blue, "Brand"));
|
||||
assert_eq!(map_node_solid_paints(&mut loose, &mut to_blue), 0, "nothing left to change");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mapping_within_ids_visits_each_paint_once() {
|
||||
let (mut d, a, b) = doc();
|
||||
|
||||
Reference in New Issue
Block a user