mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 21:57:12 -06:00
#1172: share an object's appearance with its undo history until it changes
Every edit of an object copied its whole appearance (its fills, strokes and effects, about 540 bytes for a basic object) into the new node, though a move leaves it as it is. Over 45 whole-selection moves of 10,000 paths, undo history grew by 589 MB; now 349 MB (41 % less), and a nudge or a drag of the selection takes 12 ms instead of 15. - Node::appearance is a vectorcraft_doc::Shared<Appearance>: copy-on-write. A clone shares it, and the first change through DerefMut copies it (Arc::make_mut). Reads, writes, equality (also against a plain Appearance) and the saved form are those of the Appearance itself, so call sites read and change it as before. Sites that build or assign a whole appearance add .into(), and the few that need a plain copy take (*n.appearance).clone(). - Node::transform changes the appearance only when it has gradients to transform, and pattern paints are transformed only when there are some: a move no longer copies an appearance it doesn't change. The workspace suite (5,301 tests) and clippy pass with the change; the doc and engine suites pass again after the transform guard. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmMmc1J8XeNLxhRihWv9cc
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
7652439b40
commit
0724aafbb6
@@ -203,10 +203,10 @@ struct Style {
|
||||
|
||||
impl Style {
|
||||
fn of(n: &Node) -> Self {
|
||||
Style { appearance: n.appearance.clone(), opacity: n.opacity, blend: n.blend }
|
||||
Style { appearance: (*n.appearance).clone(), opacity: n.opacity, blend: n.blend }
|
||||
}
|
||||
fn apply(&self, n: &mut Node) {
|
||||
n.appearance = self.appearance.clone();
|
||||
n.appearance = self.appearance.clone().into();
|
||||
n.opacity = self.opacity;
|
||||
n.blend = self.blend;
|
||||
}
|
||||
@@ -377,7 +377,7 @@ fn run_pf(s: &mut Session, op: PathfinderOp) -> Result<Value> {
|
||||
// Outline: open edges stroked with the face's former fill.
|
||||
let fill = st.appearance.fill_paint();
|
||||
let paint = if fill.is_none() { st.appearance.stroke_paint() } else { fill };
|
||||
n.appearance = Appearance { items: vec![AppearanceItem::Stroke(StrokeLayer::new(paint, 1.0))], ..Default::default() };
|
||||
n.appearance = Appearance { items: vec![AppearanceItem::Stroke(StrokeLayer::new(paint, 1.0))], ..Default::default() }.into();
|
||||
}
|
||||
children.push(Arc::new(n));
|
||||
}
|
||||
@@ -519,7 +519,7 @@ pub(crate) fn outlined_stroke(
|
||||
overprint: st.overprint,
|
||||
..vectorcraft_doc::appearance::FillLayer::new(st.paint.clone())
|
||||
};
|
||||
n.appearance = Appearance { items: vec![AppearanceItem::Fill(fill)], ..Default::default() };
|
||||
n.appearance = Appearance { items: vec![AppearanceItem::Fill(fill)], ..Default::default() }.into();
|
||||
Some(n)
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ pub(crate) fn outline_strokes(d: &mut Document, brushes: &[vectorcraft_brush::Br
|
||||
/// A plain copy of path `l` (new ids, no transparency, name or mask) painted with `items`.
|
||||
pub(crate) fn styled_copy(d: &mut Document, l: &Node, items: Vec<AppearanceItem>) -> Node {
|
||||
let mut f = d.reid(l);
|
||||
f.appearance = Appearance { items, ..Default::default() };
|
||||
f.appearance = Appearance { items, ..Default::default() }.into();
|
||||
f.opacity = 1.0;
|
||||
f.blend = BlendMode::Normal;
|
||||
f.name = None;
|
||||
|
||||
Reference in New Issue
Block a user