mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 18:56:55 -06:00
Merge pull request #4240 from dotCooCoo/fix/brush-art-symbol-renames
Render: brush art is made again when a symbol or pattern it shows is renamed
This commit is contained in:
@@ -46,9 +46,9 @@ fn shows_definitions(brush: &Brush, st: &StrokeLayer) -> bool {
|
||||
matches!(st.paint, vectorcraft_color::Paint::Pattern { .. }) || crate::fx::Reads::of_all(art.into_iter()).shows_definitions()
|
||||
}
|
||||
|
||||
/// The art of `doc`'s patterns and symbols, in order.
|
||||
fn definitions(doc: &Document) -> impl Iterator<Item = &Arc<Node>> {
|
||||
doc.patterns.iter().flat_map(|p| &p.art).chain(doc.symbols.iter().map(|s| &s.art))
|
||||
/// The names and art of `doc`'s patterns and symbols, in order.
|
||||
fn definitions(doc: &Document) -> impl Iterator<Item = (&str, &Arc<Node>)> {
|
||||
doc.patterns.iter().flat_map(|p| p.art.iter().map(|a| (p.name.as_str(), a))).chain(doc.symbols.iter().map(|s| (s.name.as_str(), &s.art)))
|
||||
}
|
||||
|
||||
/// Parsed brush library and generated brush art.
|
||||
@@ -61,9 +61,9 @@ pub(crate) struct BrushCache {
|
||||
/// (frame stamp, document address) the library was last validated for.
|
||||
checked: (u64, usize),
|
||||
lib: HashMap<String, Arc<Brush>>,
|
||||
/// The art of the document's patterns and symbols ([`definitions`]) when the library was last
|
||||
/// validated, held weakly as the pattern tiles hold theirs.
|
||||
definitions: Vec<Weak<Node>>,
|
||||
/// The names and art of the document's patterns and symbols ([`definitions`]) when the library
|
||||
/// was last validated, the art held weakly as the pattern tiles hold theirs.
|
||||
definitions: Vec<(String, Weak<Node>)>,
|
||||
/// Brush art per (node id, stroke item index, [`path_key`] of the stroked path).
|
||||
pub(crate) entries: FrameCache<(u64, usize, u64), Entry>,
|
||||
/// How many times [`Renderer::draw_brush`] made brush art.
|
||||
@@ -93,8 +93,8 @@ impl BrushCache {
|
||||
return;
|
||||
}
|
||||
self.checked = key;
|
||||
if !self.definitions.iter().map(Weak::as_ptr).eq(definitions(doc).map(Arc::as_ptr)) {
|
||||
self.definitions = definitions(doc).map(Arc::downgrade).collect();
|
||||
if !self.definitions.iter().map(|(n, a)| (n.as_str(), a.as_ptr())).eq(definitions(doc).map(|(n, a)| (n, Arc::as_ptr(a)))) {
|
||||
self.definitions = definitions(doc).map(|(n, a)| (n.to_string(), Arc::downgrade(a))).collect();
|
||||
self.entries.retain(|e| !e.definitions);
|
||||
}
|
||||
let cur = doc.unknown.get(vectorcraft_brush::DOC_KEY);
|
||||
|
||||
@@ -801,6 +801,68 @@ fn brush_art_draws_edits_of_the_symbols_and_patterns_it_shows() {
|
||||
}
|
||||
}
|
||||
|
||||
/// As above, with symbols `Dot` (a blue square) and `Other` (a red square with a brushed line),
|
||||
/// and patterns `Fill` (a green square) and `Spare` (a red square with a brushed line). After a
|
||||
/// frame, the next one draws as a new renderer does when two symbols or two patterns swap names,
|
||||
/// their art left as it is: the brush art's instance of `Dot` or its square painted with `Fill`
|
||||
/// then shows art that draws a brushed stroke.
|
||||
#[test]
|
||||
fn brush_art_draws_renamed_symbols_and_patterns_it_shows() {
|
||||
let _fonts = fonts_steady();
|
||||
use vectorcraft_brush::{Brush, BrushKind, Scatter};
|
||||
use vectorcraft_doc::pattern::{PatternDef, pattern_paint};
|
||||
use vectorcraft_geom::shapes::{line, rectangle};
|
||||
let square = |d: &mut Document, paint: Paint| filled(d, rectangle(Rect::new(-4.0, -4.0, 4.0, 4.0)), paint, vec![]);
|
||||
let art = |d: &mut Document, paint: Paint, brushed: bool| {
|
||||
let mut members = vec![Arc::new(square(d, paint))];
|
||||
if brushed {
|
||||
members.push(Arc::new(brushed_line(d)));
|
||||
}
|
||||
Node::group(d.alloc_id(), members)
|
||||
};
|
||||
let doc = || {
|
||||
let mut d = Document::new(200.0, 100.0);
|
||||
for (name, paint, brushed) in
|
||||
[("Dot", Paint::solid(Color::rgb(0.0, 0.0, 1.0)), false), ("Other", Paint::solid(Color::rgb(1.0, 0.0, 0.0)), true)]
|
||||
{
|
||||
let a = art(&mut d, paint, brushed);
|
||||
d.symbols.push(vectorcraft_doc::Symbol { name: name.into(), art: Arc::new(a) });
|
||||
}
|
||||
for (name, paint, brushed) in
|
||||
[("Fill", Paint::solid(Color::rgb(0.0, 0.6, 0.0)), false), ("Spare", Paint::solid(Color::rgb(1.0, 0.0, 0.0)), true)]
|
||||
{
|
||||
let a = art(&mut d, paint, brushed);
|
||||
let mut def = PatternDef::new(name, vec![Arc::new(a)]);
|
||||
def.tile = Rect::new(-6.0, -6.0, 6.0, 6.0);
|
||||
d.patterns.push(def);
|
||||
}
|
||||
let id = d.alloc_id();
|
||||
let instance = Node::new(id, NodeKind::SymbolInstance { symbol: "Dot".into(), xf: Affine::translate((0.0, -8.0)) });
|
||||
let mut painted = square(&mut d, pattern_paint("Fill"));
|
||||
painted.transform(Affine::translate((0.0, 8.0)), true);
|
||||
let scatter = Node::group(d.alloc_id(), vec![Arc::new(instance), Arc::new(painted)]);
|
||||
let mut lib = vectorcraft_brush::library(&d);
|
||||
lib.push(Brush { name: "Dots".into(), kind: BrushKind::Scatter(Scatter { art: scatter, spacing: (150.0, 150.0), ..Default::default() }) });
|
||||
vectorcraft_brush::store(&mut d, &lib);
|
||||
let mut ap = vectorcraft_doc::Appearance::basic(Paint::None, Paint::solid(Color::BLACK), 1.0);
|
||||
if let Some(s) = ap.stroke_mut() {
|
||||
s.brush = Some("Dots".into());
|
||||
}
|
||||
let path = Node::path(d.alloc_id(), line((20.0, 50.0).into(), (180.0, 50.0).into()), ap);
|
||||
let l = d.layers[0].id;
|
||||
d.insert(Some(l), usize::MAX, path).unwrap();
|
||||
d
|
||||
};
|
||||
edit_draws_as_new(doc(), |d| {
|
||||
d.symbols[0].name = "Other".into();
|
||||
d.symbols[1].name = "Dot".into();
|
||||
});
|
||||
edit_draws_as_new(doc(), |d| {
|
||||
d.patterns[0].name = "Spare".into();
|
||||
d.patterns[1].name = "Fill".into();
|
||||
});
|
||||
}
|
||||
|
||||
/// A path of the document and an instance of symbol `Wave` (a group holding another path) are
|
||||
/// stroked with scatter brush `Bent`, whose art is an arc envelope around a green band: the second
|
||||
/// frame evaluates none of the envelopes in their brush art again, and draws what the first drew
|
||||
|
||||
Reference in New Issue
Block a user