From 6c131431edda4d5b348660068dd9bdd6e2cc8e94 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Sat, 10 Oct 2026 11:19:45 +0700 Subject: [PATCH] Fix #890: artboard art includes art flush with its right or bottom edge The art that goes with an artboard (Duplicate Artboard and Copy/Cut with art, the Artboard tool's Move/Copy Artwork with Artboard, and moving an artboard by its X and Y) was found with a half-open containment test, so an object whose right or bottom edge lay exactly on the artboard's was left behind. Its edges now count as inside. Co-Authored-By: Claude Opus 5.5 --- crates/doc/src/lib.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/doc/src/lib.rs b/crates/doc/src/lib.rs index 0c0ff99e..49a394cf 100644 --- a/crates/doc/src/lib.rs +++ b/crates/doc/src/lib.rs @@ -960,8 +960,12 @@ impl Document { if c.is_layer() { collect(c, rect, all, out); } else if let Some(b) = c.geometric_bounds() - && rect.contains(Point::new(b.x0, b.y0)) - && rect.contains(Point::new(b.x1, b.y1)) + // Inside it, edges included: art flush with the right or bottom edge is on it too + // (`Rect::contains` leaves those out, #890). + && b.x0 >= rect.x0 + && b.y0 >= rect.y0 + && b.x1 <= rect.x1 + && b.y1 <= rect.y1 { out.push(c.id); } @@ -1174,6 +1178,10 @@ mod tests { let wide = Rect::new(-1.0, -1.0, 40.0, 15.0); assert_eq!(d.art_on_artboard(Rect::new(-1.0, -1.0, 15.0, 15.0), false), vec![a]); assert_eq!(d.art_on_artboard(Rect::new(-1.0, -1.0, 25.0, 15.0), false), vec![a], "b only half inside"); + // Flush with the artboard's edges counts as inside: the right and bottom ones too (#890). + for board in [Rect::new(0.0, 0.0, 10.0, 10.0), Rect::new(-5.0, 0.0, 10.0, 15.0), Rect::new(0.0, -5.0, 15.0, 10.0)] { + assert_eq!(d.art_on_artboard(board, false), vec![a], "{board:?}"); + } d.node_mut(a).unwrap().locked = true; assert_eq!(d.art_on_artboard(wide, false), vec![b]); // Move Locked and Hidden Artwork with Artboard (#394): hidden art stays too, unless on.