diff --git a/crates/ui-egui/src/canvas/page_decor.rs b/crates/ui-egui/src/canvas/page_decor.rs index 90119659b..0271b4bcd 100644 --- a/crates/ui-egui/src/canvas/page_decor.rs +++ b/crates/ui-egui/src/canvas/page_decor.rs @@ -82,8 +82,11 @@ fn draw_bleed_and_slug(painter: &egui::Painter, xf: &Xf, doc: &Document, slot: & fn draw_spine(painter: &egui::Painter, xf: &Xf, slot: &SpreadSlot, sp: &designcraft_doc::Spread, t: &Tokens) { let pt = |p: Point| xf.to_screen(slot.xf * p); for pair in sp.pages.windows(2) { + // Bound right to left, a spread lists its right page first: take the two edges that + // meet, whichever page comes first. let (a, b) = (pair[0].bounds(), pair[1].bounds()); - let x = (a.x1 + b.x0) / 2.0; + let (left, right) = if a.x0 <= b.x0 { (a, b) } else { (b, a) }; + let x = (left.x1 + right.x0) / 2.0; let (y0, y1) = (a.y0.min(b.y0), a.y1.max(b.y1)); painter.line_segment([pt(Point::new(x, y0)), pt(Point::new(x, y1))], Stroke::new(hair(painter), t.text_dim)); } diff --git a/crates/ui-egui/src/canvas/tests.rs b/crates/ui-egui/src/canvas/tests.rs index cdb73f3c2..584dd7ba5 100644 --- a/crates/ui-egui/src/canvas/tests.rs +++ b/crates/ui-egui/src/canvas/tests.rs @@ -78,6 +78,25 @@ fn a_spread_shows_a_spine_line_between_its_pages() { assert!(pairs > 0, "the document has a spread with two pages"); } +#[test] +fn the_spine_sits_where_the_pages_of_a_right_to_left_spread_meet() { + // Bound right to left, the spread lists its right page first. With pages of different + // widths, the line must be at their shared edge, not halfway between the outer ones. + let mut app = DesignApp::new(designcraft_engine::Session::new(), crate::Services::default()); + app.run("file.new", serde_json::json!({"pages": 3, "facingPages": true})).unwrap(); + app.run("layout.documentSetup", serde_json::json!({"binding": "rightToLeft"})).unwrap(); + let w = app.session.active().unwrap().doc.settings.page_width; + app.run("layout.pageSize", serde_json::json!({"pages": [2], "width": w * 0.6})).unwrap(); + let shapes = canvas_shapes(&mut app); + let st = app.session.active().unwrap(); + let layout = CanvasLayout::new(&st.doc, false); + let xf = Xf::new(app.canvas_rect.unwrap(), app.view().unwrap()); + let (right, left) = (xf.rect(layout.page_rect(&st.doc, 1).unwrap()), xf.rect(layout.page_rect(&st.doc, 2).unwrap())); + assert!((left.max.x - right.min.x).abs() < 0.01, "page 3 is the left page, page 2 the right"); + assert!((left.width() - right.width()).abs() > 1.0, "the pages differ in width"); + assert_eq!(vertical_lines_at(&shapes, left.max.x, left), 1); +} + #[test] fn the_spine_line_hides_with_the_other_guides() { for (guides, mode) in [(false, ScreenMode::Normal), (true, ScreenMode::Preview), (true, ScreenMode::Presentation)] {