mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Clear dangling handles when deleting anchors from a closed path
Found while testing crates/engine/src/cmd/path.rs:632 (without_anchors, closed-path branch uses keep instead of open_run) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Haiku 5.5
parent
bdd5470dcf
commit
85af04a83a
@@ -602,7 +602,6 @@ fn without_anchors(sp: SubPath, removed: &BTreeSet<usize>) -> Vec<SubPath> {
|
||||
if gone.is_empty() {
|
||||
return vec![sp];
|
||||
}
|
||||
let keep = |anchors: Vec<Anchor>| (anchors.len() >= 2).then(|| SubPath::new(anchors, false));
|
||||
let mut runs: Vec<Vec<Anchor>> = vec![];
|
||||
let mut run = vec![];
|
||||
for (i, anchor) in sp.anchors.into_iter().enumerate() {
|
||||
@@ -630,7 +629,7 @@ fn without_anchors(sp: SubPath, removed: &BTreeSet<usize>) -> Vec<SubPath> {
|
||||
} else if !run.is_empty() {
|
||||
runs.push(run);
|
||||
}
|
||||
runs.into_iter().filter_map(keep).collect()
|
||||
runs.into_iter().filter_map(open_run).collect()
|
||||
}
|
||||
|
||||
/// Remove connections, splitting open/closed contours into their surviving open runs.
|
||||
|
||||
@@ -1968,6 +1968,26 @@ fn open_anchor_delete_preserves_curves_appearance_and_history() {
|
||||
assert_eq!(s.doc().unwrap().doc, after);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn closed_anchor_delete_then_join_closes_with_a_line() {
|
||||
let mut s = session();
|
||||
let data = "M100 100C120 60 180 60 200 100C220 140 280 140 300 100C320 60 380 60 400 100C420 140 480 140 500 100C500 200 100 200 100 100Z";
|
||||
let id = NodeId(s.execute("path.create", &json!({"d": data})).unwrap()["id"].as_u64().unwrap());
|
||||
s.execute("select.anchors", &json!({"id": id.0, "anchors": [[0, 2]]})).unwrap();
|
||||
s.execute("path.deleteAnchors", &json!({})).unwrap();
|
||||
let result = path(&s, id);
|
||||
assert_eq!(result.subpaths.len(), 1);
|
||||
let sp = &result.subpaths[0];
|
||||
assert!(!sp.closed);
|
||||
assert!(!sp.anchors.first().unwrap().has_in() && !sp.anchors.last().unwrap().has_out(), "dangling handles are cleared");
|
||||
s.execute("path.join", &json!({"ids": [id.0]})).unwrap();
|
||||
let joined = path(&s, id);
|
||||
let sp = &joined.subpaths[0];
|
||||
assert!(sp.closed);
|
||||
let closing = sp.segment(sp.segment_count() - 1);
|
||||
assert!(closing.p1 == closing.p0 && closing.p2 == closing.p3, "closing segment is a line: {closing:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn open_anchor_delete_does_not_change_explicit_remove_anchors() {
|
||||
for command in ["path.removeAnchors", "path.removeAnchor"] {
|
||||
|
||||
Reference in New Issue
Block a user