From 8f87ad53dd9276c0acc11873651c1be8f823fe49 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Fri, 16 Oct 2026 22:21:25 -0700 Subject: [PATCH 1/2] Artboards: art centered on an artboard's right or bottom edge is on that artboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rearrange All Artboards, Select › All on Active Artboard (for objects with no area), Copy's source artboard for Paste in Place, Align to Artboard without an index, Crop Image, the Crop Image tool, Place with `at`, CSS positions and a filter plug-in's artboard decided whether a point or an object's center is on an artboard with Rect::contains, which leaves out the right and bottom edges. A line along an artboard's right or bottom edge was on no artboard: Rearrange left it behind, and All on Active Artboard did not select it. Document::art_on_artboard counts art flush with those edges (#890). They now count the edges as art_on_artboard does, within a millionth of a point. On an edge two artboards share, the artboard to the right of it or below it still holds the point. All on Active Artboard selects a line on a shared edge from either artboard. A press exactly on a right or bottom edge now picks that artboard, and the Artboard tool's cursor shows Move there. --- crates/doc/src/lib.rs | 60 ++++++++++++++++++++++++++- crates/engine/src/cmd/menucmds.rs | 2 +- crates/engine/src/cmd/place/mod.rs | 4 +- crates/engine/src/cmd/select.rs | 5 ++- crates/engine/src/tests_clipboard.rs | 19 +++++++++ crates/engine/src/tests_menucmds.rs | 17 ++++++++ crates/engine/src/tests_newdoc.rs | 17 ++++++++ crates/engine/src/tests_textimport.rs | 16 +++++++ crates/svg/src/css.rs | 4 +- crates/svg/tests/css_rules.rs | 20 +++++++++ crates/tools/src/xform/artboard.rs | 18 +++++++- 11 files changed, 173 insertions(+), 9 deletions(-) diff --git a/crates/doc/src/lib.rs b/crates/doc/src/lib.rs index c6a137e93..1d1b5452b 100644 --- a/crates/doc/src/lib.rs +++ b/crates/doc/src/lib.rs @@ -786,6 +786,14 @@ fn yes() -> bool { true } +/// Is point `p` on the artboard at `rect`, its edges included, within a millionth of a point? This +/// is the rule [`Document::art_on_artboard`] applies to art flush with an edge (#890), where +/// `Rect::contains` leaves out the right and bottom edges. +pub fn artboard_holds(rect: Rect, p: Point) -> bool { + let r = rect.inflate(1e-6, 1e-6); + r.x0 <= p.x && p.x <= r.x1 && r.y0 <= p.y && p.y <= r.y1 +} + /// Listed nodes by parent: the parent's index path (empty for the top-level layers), then the index /// of each listed child in it, in order, with the child's place in the list. type Places = BTreeMap, Vec<(usize, usize)>>; @@ -1356,9 +1364,23 @@ impl Document { let symbols = self.symbol_boxes(); self.layers.iter().fold(None, |acc, l| vectorcraft_geom::union_opt(acc, l.visual_bounds_with(&symbols))) } - /// Artboard index containing point `p` (topmost = last). + /// Artboard index containing point `p` (topmost = last), its edges included + /// ([`Document::artboard_holding`]). pub fn artboard_at(&self, p: Point) -> Option { - self.artboards.iter().rposition(|a| a.rect.contains(p)) + self.artboard_holding(p, true) + } + /// Index of the artboard that holds point `p`: the first (the last when `topmost`) that holds it + /// inside or on its left or top edge, else the first (the last) that holds it by + /// [`artboard_holds`]: on its right or bottom edge, or within a millionth of a point outside an + /// edge. On an edge two artboards share, the artboard to the right of it or below it holds the + /// point. + pub fn artboard_holding(&self, p: Point, topmost: bool) -> Option { + let pick = |on: &dyn Fn(Rect) -> bool| { + let on = |i: &usize| self.artboards.get(*i).is_some_and(|a| on(a.rect)); + let mut all = 0..self.artboards.len(); + if topmost { all.rfind(on) } else { all.find(on) } + }; + pick(&|r| r.contains(p)).or_else(|| pick(&|r| artboard_holds(r, p))) } /// The art that moves with an artboard at `rect`: top-level objects (children of layers and /// sublayers) lying entirely inside it, with symbol instances measured by their art. Locked and @@ -1839,6 +1861,40 @@ mod tests { assert_eq!(d.art_on_artboard(Rect::new(0.0, 0.0, 15.0, 15.0), false), vec![id]); } + #[test] + fn artboard_at_counts_the_right_and_bottom_edges() { + // Artboard 0 is (0, 0) to (100, 100), artboard 1 is to its right and artboard 2 below it. + let mut d = Document::new(100.0, 100.0); + for rect in [Rect::new(100.0, 0.0, 200.0, 100.0), Rect::new(0.0, 100.0, 100.0, 200.0)] { + let mut a = d.artboards[0].clone(); + a.rect = rect; + d.artboards.push(a); + } + let held = |d: &Document, x: f64, y: f64| (d.artboard_at(Point::new(x, y)), d.artboard_holding(Point::new(x, y), false)); + // Each artboard's own right and bottom edges, edges with roundoff, and points beyond them. + assert_eq!(held(&d, 200.0, 50.0), (Some(1), Some(1)), "right edge"); + assert_eq!(held(&d, 150.0, 100.0), (Some(1), Some(1)), "bottom edge"); + assert_eq!(held(&d, 200.0, 100.0), (Some(1), Some(1)), "bottom right corner"); + assert_eq!(held(&d, 100.0, 150.0), (Some(2), Some(2)), "right edge"); + assert_eq!(held(&d, 50.0, 200.0 + 1e-9), (Some(2), Some(2)), "roundoff past the bottom edge"); + assert_eq!(held(&d, -1e-9, 50.0), (Some(0), Some(0)), "roundoff past the left edge"); + assert_eq!(held(&d, 200.001, 50.0), (None, None)); + assert_eq!(held(&d, 50.0, 200.001), (None, None)); + // On an edge two artboards share, the artboard to the right of it or below it holds the + // point, in either list order. + assert_eq!(held(&d, 100.0, 50.0), (Some(1), Some(1))); + assert_eq!(held(&d, 50.0, 100.0), (Some(2), Some(2))); + d.artboards.swap(0, 1); + assert_eq!(held(&d, 100.0, 50.0), (Some(0), Some(0))); + // Where two artboards overlap, the topmost holds the point, or the first one when not + // `topmost`. + let mut inner = d.artboards[1].clone(); + inner.rect = Rect::new(10.0, 10.0, 90.0, 90.0); + d.artboards.push(inner); + assert_eq!(held(&d, 50.0, 50.0), (Some(3), Some(1))); + assert_eq!(held(&d, 90.0, 50.0), (Some(1), Some(1)), "inside artboard 1, on the right edge of artboard 3"); + } + #[test] fn find_and_paths() { let (d, a, b) = doc_with_rects(); diff --git a/crates/engine/src/cmd/menucmds.rs b/crates/engine/src/cmd/menucmds.rs index 4d4193326..b22ad5ffb 100644 --- a/crates/engine/src/cmd/menucmds.rs +++ b/crates/engine/src/cmd/menucmds.rs @@ -982,7 +982,7 @@ fn rearrange_artboards(s: &mut Session, p: &Value) -> Result { .filter(|n| n.rides_with_artboard(locked_and_hidden)) .filter_map(|n| { let c = n.geometric_bounds_with(&symbols)?.center(); - let dl = *rects.iter().position(|r| r.contains(c)).and_then(|i| deltas.get(i))?; + let dl = *d.artboard_holding(c, false).and_then(|i| deltas.get(i))?; (dl != Vec2::ZERO).then_some((n.id, dl)) }) .collect() diff --git a/crates/engine/src/cmd/place/mod.rs b/crates/engine/src/cmd/place/mod.rs index c4a8fe18c..fd6e31859 100644 --- a/crates/engine/src/cmd/place/mod.rs +++ b/crates/engine/src/cmd/place/mod.rs @@ -448,9 +448,9 @@ fn place(s: &mut Session, p: &Value) -> Result { ) } -/// The artboard under `at`, else the first. +/// The artboard under `at` (its edges included, [`Document::artboard_holding`]), else the first. fn board_at(d: &Document, at: Option) -> Option { - at.and_then(|c| d.artboards.iter().find(|a| a.rect.contains(c))).or(d.artboards.first()).map(|a| a.rect) + at.and_then(|c| d.artboard_holding(c, false)).and_then(|i| d.artboards.get(i)).or(d.artboards.first()).map(|a| a.rect) } /// Placed type's frame without `rect` or Replace: the artboard under `at` (else the first) less a diff --git a/crates/engine/src/cmd/select.rs b/crates/engine/src/cmd/select.rs index 7735b7522..eadd37680 100644 --- a/crates/engine/src/cmd/select.rs +++ b/crates/engine/src/cmd/select.rs @@ -264,7 +264,10 @@ fn all_on_artboard(s: &mut Session, p: &Value) -> Result { let ids: Vec = selectable(&st.doc, st.isolation) .into_iter() .filter(|id| { - st.doc.node(*id).and_then(|n| n.geometric_bounds_with(&symbols)).is_some_and(|b| b.intersect(r).area() > 0.0 || r.contains(b.center())) + st.doc + .node(*id) + .and_then(|n| n.geometric_bounds_with(&symbols)) + .is_some_and(|b| b.intersect(r).area() > 0.0 || vectorcraft_doc::artboard_holds(r, b.center())) }) .collect(); s.select(|_, sel| sel.set(ids.iter().copied()))?; diff --git a/crates/engine/src/tests_clipboard.rs b/crates/engine/src/tests_clipboard.rs index 589d28b05..b373a7973 100644 --- a/crates/engine/src/tests_clipboard.rs +++ b/crates/engine/src/tests_clipboard.rs @@ -585,6 +585,25 @@ fn in_place_pastes_of_art_off_the_artboards_stay_where_it_was() { } } +/// Art centered on an artboard's right or bottom edge is copied from that artboard: Paste in Place +/// puts it on the active artboard where it was on that one. +#[test] +fn in_place_pastes_of_art_on_an_artboard_edge_go_onto_the_artboard_named() { + let mut s = Session::new(); + s.execute("file.new", &json!({"width": 200, "height": 100, "artboards": 2})).unwrap(); + let boards: Vec = doc(&s).artboards.iter().map(|a| a.rect).collect(); + let b = boards[1]; + // A line along the right edge of artboard 2, then one along its bottom edge. + for (x1, y1, x2, y2) in [(b.x1, b.y0 + 10.0, b.x1, b.y0 + 40.0), (b.x0 + 10.0, b.y1, b.x0 + 40.0, b.y1)] { + let line = id_of(&s.execute("shape.line", &json!({"x1": x1, "y1": y1, "x2": x2, "y2": y2})).unwrap()); + copy(&mut s, &[line]); + assert_eq!(s.clipboard.source_artboard, Some(b)); + let ids = ids_of(&s.execute("edit.pasteInPlace", &json!({"artboard": 0})).unwrap()); + let moved = doc(&s).bounds_of(&ids, false).unwrap().origin() - doc(&s).bounds_of(&[line], false).unwrap().origin(); + assert_eq!(moved, boards[0].origin() - b.origin()); + } +} + #[test] fn paste_remembers_layers_restores_the_source_layers() { let mut s = session(); diff --git a/crates/engine/src/tests_menucmds.rs b/crates/engine/src/tests_menucmds.rs index 9b6912bd8..9af6d3c1e 100644 --- a/crates/engine/src/tests_menucmds.rs +++ b/crates/engine/src/tests_menucmds.rs @@ -1300,6 +1300,23 @@ fn select_all_in_pattern_and_mask_editing_selects_the_art_being_edited() { } } +/// All on Active Artboard takes a line on the artboard's right or bottom edge, as it takes one on +/// the left or top edge. A line on the edge two artboards share is on both. +#[test] +fn select_all_on_artboard_takes_lines_on_its_right_and_bottom_edges() { + let mut s = Session::new(); + s.execute("file.new", &json!({"width": 100, "height": 50, "artboards": 2, "artboardLayout": {"layout": "row", "spacing": 0}})).unwrap(); + let mut line = |x1: f64, y1: f64, x2: f64, y2: f64| id_of(&s.execute("shape.line", &json!({"x1": x1, "y1": y1, "x2": x2, "y2": y2})).unwrap()); + let (bottom, right, shared) = (line(10.0, 50.0, 40.0, 50.0), line(200.0, 10.0, 200.0, 40.0), line(100.0, 10.0, 100.0, 40.0)); + line(200.5, 10.0, 200.5, 40.0); + let mut on = |i: u64| { + s.execute("select.allOnArtboard", &json!({"artboard": i})).unwrap(); + selected(&s) + }; + assert_eq!(on(0), vec![bottom, shared]); + assert_eq!(on(1), vec![right, shared]); +} + #[test] fn save_and_recall_selection() { let mut s = session(); diff --git a/crates/engine/src/tests_newdoc.rs b/crates/engine/src/tests_newdoc.rs index 80978a2d3..82ca009d6 100644 --- a/crates/engine/src/tests_newdoc.rs +++ b/crates/engine/src/tests_newdoc.rs @@ -330,6 +330,23 @@ fn rearrange_lays_out_by_layout_and_order() { } } +/// Art centered on an artboard's right or bottom edge moves with that artboard, and art on the edge +/// two artboards share moves with the artboard to the right of it. +#[test] +fn rearrange_moves_art_centered_on_an_artboard_edge() { + let mut s = new_doc(json!({"width": 100, "height": 50, "artboards": 2, "artboardLayout": {"layout": "row", "spacing": 0}})); + assert_eq!(boards(&s), [Rect::new(0.0, 0.0, 100.0, 50.0), Rect::new(100.0, 0.0, 200.0, 50.0)]); + let mut line = |x1: f64, y1: f64, x2: f64, y2: f64| { + NodeId(s.execute("shape.line", &json!({"x1": x1, "y1": y1, "x2": x2, "y2": y2})).unwrap()["id"].as_u64().unwrap()) + }; + let (bottom, right, shared) = (line(10.0, 50.0, 40.0, 50.0), line(200.0, 10.0, 200.0, 40.0), line(100.0, 10.0, 100.0, 40.0)); + // Right to left, artboard 0 moves 100 pt right and artboard 1 moves 100 pt left. + s.execute("artboard.rearrange", &json!({"layout": "row", "order": "rightToLeft", "spacing": 0})).unwrap(); + assert_eq!(boards(&s), [Rect::new(100.0, 0.0, 200.0, 50.0), Rect::new(0.0, 0.0, 100.0, 50.0)]); + let x0 = |id: NodeId| s.doc().unwrap().doc.node(id).unwrap().geometric_bounds().unwrap().x0; + assert_eq!((x0(bottom), x0(right), x0(shared)), (110.0, 100.0, 0.0)); +} + /// `byColumn: true` is Grid by Column; without `moveArtwork` the art stays; bad values are errors. #[test] fn rearrange_aliases_and_rejects_bad_values() { diff --git a/crates/engine/src/tests_textimport.rs b/crates/engine/src/tests_textimport.rs index ba87bc65c..780983750 100644 --- a/crates/engine/src/tests_textimport.rs +++ b/crates/engine/src/tests_textimport.rs @@ -51,6 +51,22 @@ fn crlf_with_returns_removed_places_one_paragraph_per_block_as_area_type() { assert!(close(frame, Rect::new(10.0, 20.0, 110.0, 70.0)), "{frame:?}"); } +/// Placed at a point on an artboard's right or bottom edge, the frame takes that artboard's size less +/// a 36 pt margin on each side; on the edge two artboards share, it takes the size of the artboard to +/// the right of it. +#[test] +fn type_placed_on_an_artboard_edge_takes_that_artboards_frame() { + let mut s = session(); + let mut wide = s.doc().unwrap().doc.artboards[0].clone(); + wide.rect = Rect::new(400.0, 0.0, 600.0, 200.0); + std::sync::Arc::make_mut(&mut s.doc_mut().unwrap().doc).artboards.push(wide); + for at in [[600.0, 100.0], [500.0, 200.0], [400.0, 100.0]] { + let r = place_text(&mut s, b"Edge", json!({ "at": at })); + let frame = placed(&s, &r).1; + assert!(close(frame, Rect::from_center_size((at[0], at[1]), (128.0, 128.0))), "{at:?}: {frame:?}"); + } +} + #[test] fn text_files_report_and_queue_with_their_options() { let mut s = session(); diff --git a/crates/svg/src/css.rs b/crates/svg/src/css.rs index ca4b5d8ca..e835f4def 100644 --- a/crates/svg/src/css.rs +++ b/crates/svg/src/css.rs @@ -199,7 +199,7 @@ impl CssUnits { pub struct CssOptions { pub units: CssUnits, /// `position: absolute` with `left` and `top` from the top-left corner of the object's - /// artboard (the one its centre is on, else the first). + /// artboard (the one its centre is on, its edges included, else the first). pub position: bool, /// `width` and `height`. pub dimensions: bool, @@ -381,7 +381,7 @@ impl Rules<'_> { let Some(b) = b else { return p }; if self.opts.position { let c = b.center(); - let ab = self.doc.artboards.iter().find(|a| a.rect.contains(c)).or_else(|| self.doc.artboards.first()); + let ab = self.doc.artboard_holding(c, false).and_then(|i| self.doc.artboards.get(i)).or_else(|| self.doc.artboards.first()); let origin = ab.map_or(Point::ZERO, |a| Point::new(a.rect.x0, a.rect.y0)); p.push(("position", "absolute".into())); p.push(("left", self.len(b.x0 - origin.x))); diff --git a/crates/svg/tests/css_rules.rs b/crates/svg/tests/css_rules.rs index 9e088b6d4..5ac99c596 100644 --- a/crates/svg/tests/css_rules.rs +++ b/crates/svg/tests/css_rules.rs @@ -70,6 +70,26 @@ fn rectangle_gives_background_border_and_radius() { ); } +/// An object centered on an artboard's right or bottom edge is positioned from that artboard's +/// top-left corner; on the edge two artboards share, from the one to the right of it. +#[test] +fn position_is_from_the_artboard_whose_edge_holds_the_center() { + let mut d = doc(); + // Artboard 2 is (500, 0) to (900, 300); artboard 3 starts at its right edge. + for rect in [Rect::new(500.0, 0.0, 900.0, 300.0), Rect::new(900.0, 0.0, 1000.0, 300.0)] { + let mut a = d.artboards[0].clone(); + a.rect = rect; + d.artboards.push(a); + } + let opts = CssOptions { position: true, ..CssOptions::default() }; + for ((x, y), want) in [((980.0, 100.0), ("80px", "100px")), ((600.0, 280.0), ("100px", "280px")), ((880.0, 100.0), ("-20px", "100px"))] { + let n = rect(&mut d, (x, y, 40.0, 40.0), 0.0); + let id = add(&mut d, n); + let r = one(&d, id, &opts); + assert_eq!((prop(&r, "left"), prop(&r, "top")), (Some(want.0), Some(want.1)), "at ({x}, {y})"); + } +} + #[test] fn live_corners_give_per_corner_radii_and_only_round_ones() { let mut d = doc(); diff --git a/crates/tools/src/xform/artboard.rs b/crates/tools/src/xform/artboard.rs index ed5c06c52..104ccc814 100644 --- a/crates/tools/src/xform/artboard.rs +++ b/crates/tools/src/xform/artboard.rs @@ -484,7 +484,7 @@ impl Tool for ArtboardTool { } .turned(cx.view_angle()); } - if cx.doc.artboards.iter().any(|a| a.rect.contains(p)) { Cursor::Move } else { Cursor::Crosshair } + if cx.doc.artboard_at(p).is_some() { Cursor::Move } else { Cursor::Crosshair } } fn options(&self) -> Value { @@ -729,6 +729,22 @@ mod tests { assert!((v["height"].as_f64().unwrap() - 113.0).abs() < 1e-9); } + /// Over an artboard's right or bottom edge the cursor shows Move and a click selects that + /// artboard, as on its left or top edge. + #[test] + fn a_click_on_an_artboards_right_or_bottom_edge_selects_it() { + let d = two_boards(); + let (s, p) = (Selection::default(), paint()); + let c = cx(&d, &s, &p); + for at in [Point::new(800.0, 100.0), Point::new(700.0, 200.0)] { + let mut t = ArtboardTool::default(); + assert_eq!(t.cursor(&c, at, Mods::default()), Cursor::Move, "{at:?}"); + t.pointer(&c, &ev(PointerKind::Down, at.x, at.y)); + t.pointer(&c, &ev(PointerKind::Up, at.x, at.y)); + assert_eq!(t.options()["selected"], json!([1]), "{at:?}"); + } + } + /// A proportional resize never asks for a side under 1 pt, which the command would lengthen /// alone (scaling the art unevenly): both sides grow by one factor instead. #[test] From 24b6486ebd1070d115dca3f6a26b0f19df6b952c Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sat, 17 Oct 2026 01:54:27 -0700 Subject: [PATCH 2/2] Artboards: the doc comment names the shared corner the first artboard holds On an edge two artboards share, the artboard to the right of it or below it holds a point, except at the end of the edge that lies on that artboard's bottom or right edge, such as where both artboards' bottom edges meet. There the first artboard holds it, or the last when topmost. The doc comment and the test comments now say so, and the test asserts that corner. --- crates/doc/src/lib.rs | 9 +++++++-- crates/engine/src/tests_newdoc.rs | 4 ++-- crates/engine/src/tests_textimport.rs | 4 ++-- crates/svg/tests/css_rules.rs | 3 ++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/doc/src/lib.rs b/crates/doc/src/lib.rs index 1d1b5452b..6ad1973c9 100644 --- a/crates/doc/src/lib.rs +++ b/crates/doc/src/lib.rs @@ -1373,7 +1373,8 @@ impl Document { /// inside or on its left or top edge, else the first (the last) that holds it by /// [`artboard_holds`]: on its right or bottom edge, or within a millionth of a point outside an /// edge. On an edge two artboards share, the artboard to the right of it or below it holds the - /// point. + /// point, except at the end of the edge that lies on that artboard's bottom or right edge, such + /// as the point where both artboards' bottom edges meet; there the first (the last) holds it. pub fn artboard_holding(&self, p: Point, topmost: bool) -> Option { let pick = |on: &dyn Fn(Rect) -> bool| { let on = |i: &usize| self.artboards.get(*i).is_some_and(|a| on(a.rect)); @@ -1881,9 +1882,13 @@ mod tests { assert_eq!(held(&d, 200.001, 50.0), (None, None)); assert_eq!(held(&d, 50.0, 200.001), (None, None)); // On an edge two artboards share, the artboard to the right of it or below it holds the - // point, in either list order. + // point, in either list order, except at the end of the edge that lies on that artboard's + // bottom or right edge. assert_eq!(held(&d, 100.0, 50.0), (Some(1), Some(1))); assert_eq!(held(&d, 50.0, 100.0), (Some(2), Some(2))); + // The bottom edges of artboards 0 and 1 meet at (100, 100), which is also artboard 2's top + // right corner: the first holds the point, or the last when `topmost`. + assert_eq!(held(&d, 100.0, 100.0), (Some(2), Some(0)), "shared corner"); d.artboards.swap(0, 1); assert_eq!(held(&d, 100.0, 50.0), (Some(0), Some(0))); // Where two artboards overlap, the topmost holds the point, or the first one when not diff --git a/crates/engine/src/tests_newdoc.rs b/crates/engine/src/tests_newdoc.rs index 82ca009d6..bada2ebba 100644 --- a/crates/engine/src/tests_newdoc.rs +++ b/crates/engine/src/tests_newdoc.rs @@ -330,8 +330,8 @@ fn rearrange_lays_out_by_layout_and_order() { } } -/// Art centered on an artboard's right or bottom edge moves with that artboard, and art on the edge -/// two artboards share moves with the artboard to the right of it. +/// Art centered on an artboard's right or bottom edge moves with that artboard, and art centered on +/// the edge two artboards share, away from its ends, moves with the artboard to the right of it. #[test] fn rearrange_moves_art_centered_on_an_artboard_edge() { let mut s = new_doc(json!({"width": 100, "height": 50, "artboards": 2, "artboardLayout": {"layout": "row", "spacing": 0}})); diff --git a/crates/engine/src/tests_textimport.rs b/crates/engine/src/tests_textimport.rs index 780983750..244b1d3d5 100644 --- a/crates/engine/src/tests_textimport.rs +++ b/crates/engine/src/tests_textimport.rs @@ -52,8 +52,8 @@ fn crlf_with_returns_removed_places_one_paragraph_per_block_as_area_type() { } /// Placed at a point on an artboard's right or bottom edge, the frame takes that artboard's size less -/// a 36 pt margin on each side; on the edge two artboards share, it takes the size of the artboard to -/// the right of it. +/// a 36 pt margin on each side; on the edge two artboards share, away from its ends, it takes the +/// size of the artboard to the right of it. #[test] fn type_placed_on_an_artboard_edge_takes_that_artboards_frame() { let mut s = session(); diff --git a/crates/svg/tests/css_rules.rs b/crates/svg/tests/css_rules.rs index 5ac99c596..036f1bd91 100644 --- a/crates/svg/tests/css_rules.rs +++ b/crates/svg/tests/css_rules.rs @@ -71,7 +71,8 @@ fn rectangle_gives_background_border_and_radius() { } /// An object centered on an artboard's right or bottom edge is positioned from that artboard's -/// top-left corner; on the edge two artboards share, from the one to the right of it. +/// top-left corner; on the edge two artboards share, away from its ends, from the one to the right +/// of it. #[test] fn position_is_from_the_artboard_whose_edge_holds_the_center() { let mut d = doc();