mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-14 19:26:56 -04:00
Merge pull request #1375 from storytold/fix/artboard-flush-roundoff
Artboards: art flush with an artboard moves with it despite a rounding error
This commit is contained in:
2 files changed
+59
No files matched your search
@@ -1100,6 +1100,9 @@ impl Document {
|
||||
/// `locked_and_hidden` (Selection & Anchor Display › Move Locked and Hidden Artwork with
|
||||
/// Artboard).
|
||||
pub fn art_on_artboard(&self, rect: Rect, locked_and_hidden: bool) -> Vec<NodeId> {
|
||||
// Art drawn flush with the artboard can end up a rounding error outside it (a background
|
||||
// 3e-14 pt past the top edge, #1295): a millionth of a point is far below anything visible.
|
||||
let rect = rect.inflate(1e-6, 1e-6);
|
||||
fn collect(n: &Node, rect: Rect, all: bool, out: &mut Vec<NodeId>) {
|
||||
for c in n.children().into_iter().flatten().filter(|c| c.rides_with_artboard(all)) {
|
||||
if c.is_layer() {
|
||||
@@ -1405,6 +1408,26 @@ mod tests {
|
||||
assert_eq!(d.art_on_artboard(wide, true), vec![a, b], "a locked layer's art too");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn art_on_artboard_tolerates_roundoff_at_each_edge() {
|
||||
let (d, a, _) = doc_with_rects();
|
||||
let roundoff = 1e-12;
|
||||
for board in [
|
||||
Rect::new(roundoff, 0.0, 10.0, 10.0),
|
||||
Rect::new(0.0, roundoff, 10.0, 10.0),
|
||||
Rect::new(0.0, 0.0, 10.0 - roundoff, 10.0),
|
||||
Rect::new(0.0, 0.0, 10.0, 10.0 - roundoff),
|
||||
] {
|
||||
assert_eq!(d.art_on_artboard(board, false), vec![a], "roundoff at {board:?}");
|
||||
}
|
||||
// A real overhang remains outside.
|
||||
for board in
|
||||
[Rect::new(0.001, 0.0, 10.0, 10.0), Rect::new(0.0, 0.001, 10.0, 10.0), Rect::new(0.0, 0.0, 9.999, 10.0), Rect::new(0.0, 0.0, 10.0, 9.999)]
|
||||
{
|
||||
assert!(d.art_on_artboard(board, false).is_empty(), "overhang at {board:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_and_paths() {
|
||||
let (d, a, b) = doc_with_rects();
|
||||
|
||||
@@ -289,6 +289,42 @@ fn artboard_tool_moves_with_art_creates_and_deletes() {
|
||||
assert_eq!(s.doc().unwrap().doc.artboards.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artboard_drag_keeps_a_flush_background_with_roundoff_and_multiple_texts() {
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", &json!({"width": 600, "height": 400})).unwrap();
|
||||
let (x, y) = (-35.23064566724116, -107.85371637852609);
|
||||
s.execute("artboard.setProps", &json!({"index": 0, "x": x, "y": y})).unwrap();
|
||||
// The background's top is 2.84e-14 pt above the artboard's top.
|
||||
let background = rect(&mut s, x, -107.85371637852612, 600.0, 400.0);
|
||||
let mut ids = vec![background];
|
||||
for i in 0..3 {
|
||||
let text = s.execute("text.create", &json!({"x": x + 100.0, "y": y + 80.0 + f64::from(i) * 60.0, "text": "Test", "size": 12})).unwrap();
|
||||
ids.push(NodeId(text["id"].as_u64().unwrap()));
|
||||
}
|
||||
s.execute("select.none", &json!({})).unwrap();
|
||||
let before: Vec<Rect> = ids.iter().map(|id| bounds(&s, *id)).collect();
|
||||
let board = s.doc().unwrap().doc.artboards[0].rect;
|
||||
let history = undo_len(&s);
|
||||
gesture(&mut s, "artboard", &[(x + 300.0, y + 200.0), (x + 400.0, y + 240.0), (x + 400.0, y + 240.0)], Mods::default());
|
||||
let moved_board = s.doc().unwrap().doc.artboards[0].rect;
|
||||
let delta = moved_board.origin() - board.origin();
|
||||
assert!(delta.hypot() > 1.0, "the artboard actually moved");
|
||||
for (id, was) in ids.iter().zip(&before) {
|
||||
assert!(close(bounds(&s, *id), *was + delta), "{id:?} must move with the artboard");
|
||||
}
|
||||
assert_eq!(undo_len(&s), history + 1);
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
assert_eq!(s.doc().unwrap().doc.artboards[0].rect, board);
|
||||
for (id, was) in ids.iter().zip(&before) {
|
||||
assert!(close(bounds(&s, *id), *was), "Undo restores {id:?}");
|
||||
}
|
||||
s.execute("edit.redo", &json!({})).unwrap();
|
||||
for (id, was) in ids.iter().zip(&before) {
|
||||
assert!(close(bounds(&s, *id), *was + delta), "Redo moves {id:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artboard_resize_via_handle_and_move_command() {
|
||||
let mut s = session();
|
||||
|
||||
Reference in new issue
Block a user