mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-14 20:36:02 +00:00
Merge pull request #7599 from dotCooCoo/fix/trace-hand-in-same-document
Image Trace: a finished trace is applied only to the document it was made in
This commit is contained in:
@@ -526,12 +526,15 @@ fn color_groups(cmd: &str, d: &mut Document, items: Vec<Arc<Node>>) -> Result<Ve
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// What a trace depends on: the object traced (an image, or an Image Trace object traced again),
|
||||
/// its image, the image's encoded bytes, and the settings it is traced with. The tracer makes the
|
||||
/// same paths of the same inputs, so a trace made away from the command ([`TraceRun`]) stands in
|
||||
/// for the command's own.
|
||||
/// What a trace depends on: the document it is made in, the object traced (an image, or an Image
|
||||
/// Trace object traced again), its image, the image's encoded bytes, and the settings it is traced
|
||||
/// with. The tracer makes the same paths of the same inputs, so a trace made away from the command
|
||||
/// ([`TraceRun`]) stands in for the command's own in the same document.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct TraceInputs {
|
||||
/// The [`DocState::uid`](crate::DocState::uid) of the document traced in. A trace made in one
|
||||
/// document never stands in for one in another, however alike their images and settings.
|
||||
doc: u64,
|
||||
target: NodeId,
|
||||
image: Box<ImageObject>,
|
||||
/// The settings traced with, as JSON.
|
||||
@@ -600,7 +603,7 @@ fn prepare(s: &Session, c: &str, p: &Value) -> Result<Prepared> {
|
||||
let bytes = Arc::clone(&blob.bytes);
|
||||
let library = trace_library(c, s, &mut params)?;
|
||||
let traced_with = serde_json::to_value(¶ms).map_err(|e| EngineError::Other(e.to_string()))?;
|
||||
let inputs = TraceInputs { target, image, params: traced_with, swatches: params.swatches.clone(), bytes };
|
||||
let inputs = TraceInputs { doc: s.doc()?.uid, target, image, params: traced_with, swatches: params.swatches.clone(), bytes };
|
||||
Ok(Prepared { inputs, trace: params, view, params_json, preset_label, library })
|
||||
}
|
||||
|
||||
@@ -612,8 +615,9 @@ pub struct Traced {
|
||||
}
|
||||
|
||||
impl Traced {
|
||||
/// Hand it to the next run of its command with the same inputs ([`TraceRun::params`]), which
|
||||
/// applies it as one undo step instead of tracing again. Any other trace drops it.
|
||||
/// Hand it to the next run of its command with the same inputs ([`TraceRun::params`]) in the
|
||||
/// document it was made in, which applies it as one undo step instead of tracing again. Any
|
||||
/// other trace drops it, a trace in another document included.
|
||||
pub fn hand_in(self, s: &mut Session) {
|
||||
s.trace_hand_off = Some(self);
|
||||
}
|
||||
@@ -686,7 +690,7 @@ impl TraceRun {
|
||||
}
|
||||
|
||||
/// Does it still apply: would the command trace the same object, image, pixels and settings
|
||||
/// now?
|
||||
/// now, in the document it was prepared in?
|
||||
pub fn current(&self, s: &Session) -> bool {
|
||||
prepare(s, self.command, &self.params).is_ok_and(|now| now.inputs == self.prepared.inputs)
|
||||
}
|
||||
|
||||
@@ -4415,6 +4415,41 @@ fn a_trace_run_hands_its_trace_to_the_command() {
|
||||
assert!((bb.center().x - 160.0).abs() < 1.5, "traced where the image is now: {bb:?}");
|
||||
}
|
||||
|
||||
/// A trace made in one document applies only there: in another document with the same image,
|
||||
/// object and settings, the run no longer applies, and both trace commands drop the trace handed
|
||||
/// in and trace that document's own image, as one undo step.
|
||||
#[test]
|
||||
fn a_trace_run_applies_only_in_its_own_document() {
|
||||
let p = json!({"params": {"ignoreWhite": true}});
|
||||
for command in ["imageTrace.make", "imageTrace.makeAndExpand"] {
|
||||
let mut direct = session();
|
||||
image_doc(&mut direct);
|
||||
let want = direct.execute(command, &p).unwrap();
|
||||
let mut s = session();
|
||||
let img = image_doc(&mut s);
|
||||
let a = s.active_index().unwrap();
|
||||
let copy = (*s.doc().unwrap().doc).clone();
|
||||
let run = cmd::TraceRun::prepare(&s, command, &p).unwrap();
|
||||
let traced = run.run(&|_, _| true).unwrap();
|
||||
let b = s.add_document(copy, None);
|
||||
assert_ne!(s.documents()[a].uid, s.documents()[b].uid);
|
||||
assert!(!run.current(&s), "{command}: another document");
|
||||
assert!(s.set_active(a));
|
||||
assert!(run.current(&s), "{command}: its own document");
|
||||
assert!(s.set_active(b));
|
||||
traced.hand_in(&mut s);
|
||||
let got = s.execute(run.command(), run.params()).unwrap();
|
||||
assert!(s.trace_hand_off.is_none(), "{command}: dropped");
|
||||
assert_eq!(got, want, "{command}");
|
||||
let g = NodeId(got["id"].as_u64().unwrap());
|
||||
assert_eq!(node(&s, g), node(&direct, g), "{command}");
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
assert!(matches!(node(&s, img).kind, NodeKind::Image(_)), "{command}: one undo step");
|
||||
assert!(s.set_active(a));
|
||||
assert!(matches!(node(&s, img).kind, NodeKind::Image(_)), "{command}: the first document is untouched");
|
||||
}
|
||||
}
|
||||
|
||||
/// A plug-in run that calls Image Trace and then fails leaves a trace handed in for the command in
|
||||
/// place, as it leaves the document.
|
||||
#[test]
|
||||
|
||||
@@ -1443,6 +1443,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- **Image Trace, Flat Logo working size:** Flat Logo traces at most 1024 px on a side; a larger decoded raster (the 64-megapixel copy for a bigger image) is averaged down in whole-number blocks first, and the trace's `warnings` name the size it was traced at and the image's own size, in place of the slower-trace and 64-megapixel notes; code-drawn 1024 and 1025 px tests in `crates/trace` and `crates/engine`.
|
||||
- **Image Trace, Flat Logo working size:** Flat Logo traces at most 1024 px on a side; a larger image is averaged down by a whole factor first, and the trace's `warnings` name the size it was traced at and the image's own size, in place of the slower-trace and 64-megapixel notes; code-drawn 1024 and 1025 px tests in `crates/trace` and `crates/engine`.
|
||||
- **Image Trace, Preview:** the Image Trace panel's Preview checkbox, before Trace, is on by default, and a setting change traces the selected Image Trace object again at once. Off, changes wait in the panel until Trace applies them as one undo step, or until Preview is turned on again. Changes stay with the object they were made for while another object is selected. When Preview is turned on with that object not selected, the object is traced with its changes when it is selected again. Preview is kept with the UI preferences, and Reset to Default leaves it. The `imageTrace.preview` command turns it on or off.
|
||||
- **Image Trace, traces made off the UI thread stay with their document:** a trace made away from the command (`TraceRun`) applies only in the document it was made in. In another open document with the same image, object and settings, `imageTrace.make` and `imageTrace.makeAndExpand` drop it and trace that document's image, as one undo step (VectorCraft's own rule). Test: `a_trace_run_applies_only_in_its_own_document` in `crates/engine`. Scores and hours unchanged.
|
||||
- **Image Trace small contours:** closed fits too small to form an editable subpath retain their positioned outline, including holes. Source-generated island, hole/winding and stepped-region regressions cover Corners and Noise; defaults, parity scores and estimates are unchanged.
|
||||
- **Image Trace, custom presets:** Manage Presets next to the Image Trace panel's Preset dropdown saves the panel's settings as a new preset under a name (Save as New Preset…) and renames or deletes the saved preset shown; built-in presets don't change. Saved presets are kept with the preferences and follow the built-in ones in the panel, Control bar and Properties preset lists. `imageTrace.presets.save` and `imageTrace.presets.delete` save, rename and delete them, `imageTrace.presets` lists them, and `imageTrace.make {preset}` traces with one by name.
|
||||
- **Image Trace, preset buttons:** six buttons above the Image Trace panel's Preset dropdown choose a preset as the dropdown does, for the options the [help page](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/image-trace-panel-options.html) lists before Preset. The presets each button chooses are VectorCraft's own: Auto Color chooses Auto Color, High Color chooses High Fidelity Photo, Low Color chooses Low Fidelity Photo, Grayscale chooses Shades of Gray, Black and White chooses Black and White Logo, and Outline chooses Outline. With Preview on, a click traces the selected Image Trace object again as one undo step; with nothing traced selected, it changes the panel's settings only. The button of the panel's preset shows as selected.
|
||||
|
||||
Reference in New Issue
Block a user