Merge pull request #4272 from nrq6993-a11y/stream/vc-issue-2899-join-scrub-ends

G11: Join tool connects endpoints near scrub line ends
This commit is contained in:
BFlat
2026-10-26 22:11:54 +07:00
committed by GitHub
2 changed files with 29 additions and 2 deletions
+14 -2
View File
@@ -1497,6 +1497,7 @@ fn join_scrub(s: &mut Session, p: &Value) -> Result<Value> {
.min_by(|a, b| a.1.total_cmp(&b.1))
.map_or(0.0, |x| x.0)
};
let (first_pt, last_pt) = (pts.first().copied(), pts.last().copied());
let mut ends: Vec<(f64, NodeId, usize, bool, Point)> = vec![];
for id in target_paths(&st.doc, &st.selection, poly_bounds(&pts, tol)) {
let (pd, _) = path_of(&st.doc, id)?;
@@ -1505,9 +1506,20 @@ fn join_scrub(s: &mut Session, p: &Value) -> Result<Value> {
continue;
}
for (start, a) in [(true, sp.anchors[0].p), (false, sp.anchors[sp.anchors.len() - 1].p)] {
if dist_to_polyline(&pts, a) <= tol {
ends.push((order(a), id, si, start, a));
let on_scrub = dist_to_polyline(&pts, a) <= tol;
let near_start = first_pt.is_some_and(|p| a.distance(p) <= tol);
let near_end = last_pt.is_some_and(|p| a.distance(p) <= tol);
if !on_scrub && !near_start && !near_end {
continue;
}
let ord = if on_scrub {
order(a)
} else if near_start && (!near_end || first_pt.is_some_and(|p| a.distance(p) <= a.distance(last_pt.unwrap_or(p)))) {
-1.0
} else {
1e30
};
ends.push((ord, id, si, start, a));
}
}
}
+15
View File
@@ -944,6 +944,21 @@ fn join_tool_joins_two_lines() {
assert_eq!(p.subpaths[0].anchors[2].p, Point::new(300.0, 150.0));
}
/// #2899: a scrub from one open end toward the other joins them when the line passes near the
/// endpoints, not only when it crosses them.
#[test]
fn join_tool_joins_endpoints_near_the_scrub_ends() {
let mut s = session();
let a = line(&mut s, 100.0, 100.0, 200.0, 100.0);
line(&mut s, 205.0, 100.0, 300.0, 150.0);
s.execute("select.none", &json!({})).unwrap();
drag(&mut s, "join", &[(198.0, 92.0), (207.0, 92.0)], Mods::default());
assert_eq!(paths(&s).len(), 1);
let p = path(&s, a);
assert_eq!(p.anchor_count(), 3);
assert_eq!(p.subpaths[0].anchors[1].p, Point::new(202.5, 100.0));
}
#[test]
fn line_family_tools_draw_and_click_asks_dialog() {
let mut s = session();