fix(pdf): per-piece snap bounds, linear image layering, snap op checks

Review of #1484:
- The underlay's snap geometry became one hidden wire per segment, but
  every piece took the whole page's bounding box, so each cursor move
  visited every piece. Each piece now gets its own box.
- Assigning unlayered images to the last layer compared Debug strings of
  every layered path and text per drawn item (quadratic, formatted anew
  each time); the owners are keyed once in a map.
- The `snap` automation op used (0, 0, 0) for a missing point; it now
  answers invalid_point. It also left the live snapper's base point set
  to the query's; the base point is restored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-09-25 15:17:53 +03:00
1 parent fc48087e50
commit 7e90d4d1a1
4 files changed
+23 -15

No files matched your search

+8 -5
View File
@@ -200,11 +200,14 @@ fn images_to_last_layer(
return;
};
let key = |s: &dyn std::fmt::Debug| format!("{s:?}");
let owner = |item: String| {
layered.iter().position(|(_, pv)| {
pv.paths.iter().any(|p| key(p) == item) || pv.texts.iter().any(|t| key(t) == item)
})
};
// Each layered path and text keyed once; the first layer holding it wins.
let mut owners: std::collections::HashMap<String, usize> = std::collections::HashMap::new();
for (n, (_, pv)) in layered.iter().enumerate() {
for item in pv.paths.iter().map(|p| key(p)).chain(pv.texts.iter().map(|t| key(t))) {
owners.entry(item).or_insert(n);
}
}
let owner = |item: String| owners.get(&item).copied();
let mut last: Option<usize> = None;
let mut moves: Vec<(usize, PdfImage)> = Vec::new();
for drawn in &full.order {