diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 31567398..31f63e28 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -138,7 +138,7 @@ pub fn fit(app: &mut VectorcraftApp, how: &str) { }; let Some(target) = target else { return }; let zoom = if how == "view.actualSize" { - actual_size_zoom(app.session.prefs.display_print_size, app.screen_ppi, app.pixels_per_point) + actual_size_zoom(app.session.prefs.display_print_size) } else { let zx = (rect.width() as f64 - 60.0) / target.width().max(1.0); let zy = (rect.height() as f64 - 60.0) / target.height().max(1.0); @@ -151,7 +151,6 @@ pub fn fit(app: &mut VectorcraftApp, how: &str) { } pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) { - app.pixels_per_point = f64::from(ui.ctx().pixels_per_point()); let t = Tokens::get(ui.ctx()); let full = ui.available_rect_before_wrap(); // A document that opened, closed or became active since Home was chosen replaces it. @@ -749,25 +748,12 @@ pub(crate) fn animated_zoom(p: &vectorcraft_engine::Prefs) -> bool { p.animated_zoom && p.gpu_performance } -/// Zoom for View → Actual Size (`view.actualSize`). -/// -/// With Preferences › General › Display Print Size at 100% Zoom off, one document point is one -/// screen point (zoom 1). With it on, one document inch (72 pt) fills one physical inch on the -/// screen: `screen_ppi / (72 × pixels_per_point)`, clamped to the zoom range. -/// -/// `screen_ppi` is the assumed monitor density (CSS reference 96 by default; tests may inject a -/// measured value). `pixels_per_point` is egui's scale factor. -/// -/// Public behaviour matches Adobe's preference of the same name -/// ( and the CC 2019 notes on -/// Actual Size / Display Print Size). -pub(crate) fn actual_size_zoom(display_print_size: bool, screen_ppi: f64, pixels_per_point: f64) -> f64 { - if !display_print_size { - return 1.0; - } - let ppp = if pixels_per_point.is_finite() && pixels_per_point > 0.0 { pixels_per_point } else { 1.0 }; - let ppi = if screen_ppi.is_finite() && screen_ppi > 0.0 { screen_ppi } else { 96.0 }; - (ppi / (72.0 * ppp)).clamp(0.0313, 640.0) +/// Zoom for View → Actual Size (`view.actualSize`). With Preferences › General › Display Print +/// Size at 100% Zoom off, one document point is one screen point. On, one document inch (72 pt) +/// fills an inch of the screen as the system counts it: 96 screen points, the reference density +/// that display scaling is set against (a CSS inch), whatever the scale factor. +pub(crate) fn actual_size_zoom(display_print_size: bool) -> f64 { + if display_print_size { 96.0 / 72.0 } else { 1.0 } } /// Zoom view `vm` of the canvas `rect` to `zoom` (clamped to the zoom range), keeping the document @@ -2980,36 +2966,19 @@ mod tests { } } - /// General › Display Print Size at 100% Zoom (#394): off, Actual Size is 1 document point per - /// screen point; on, one document inch fills one physical inch (`screen_ppi / (72 × ppp)`). - #[test] - fn actual_size_zoom_follows_display_print_size() { - assert_eq!(actual_size_zoom(false, 96.0, 1.0), 1.0); - assert_eq!(actual_size_zoom(false, 220.0, 2.0), 1.0); - assert!((actual_size_zoom(true, 96.0, 1.0) - 96.0 / 72.0).abs() < 1e-12); - assert!((actual_size_zoom(true, 220.0, 2.0) - 220.0 / (72.0 * 2.0)).abs() < 1e-12); - assert_eq!(actual_size_zoom(true, f64::NAN, 0.0), actual_size_zoom(true, 96.0, 1.0)); - } - - /// `view.actualSize` reads Preferences › Display Print Size at 100% Zoom and the host's screen - /// density (#394). + /// General › Display Print Size at 100% Zoom (#394): `view.actualSize` is one document point per + /// screen point with it off, and 96 screen points per document inch with it on. #[test] fn view_actual_size_follows_display_print_size() { let mut app = VectorcraftApp::new(Session::new(), Default::default()); app.session.execute("file.new", &json!({"width": 200, "height": 100})).unwrap(); app.canvas_rect = Some(egui::Rect::from_min_size(Pos2::ZERO, vec2(460.0, 260.0))); - app.screen_ppi = 96.0; - app.pixels_per_point = 1.0; app.run("view.setZoom", json!({"zoom": 250})).unwrap(); app.run("view.actualSize", json!({})).unwrap(); - assert!((app.view().unwrap().zoom - 1.0).abs() < 1e-12, "default pref keeps 100% = 1:1"); + assert!((app.view().unwrap().zoom - 1.0).abs() < 1e-12, "off by default: 100% is 1:1"); app.session.execute("prefs.set", &json!({"key": "displayPrintSize", "value": true})).unwrap(); app.run("view.actualSize", json!({})).unwrap(); - assert!((app.view().unwrap().zoom - 96.0 / 72.0).abs() < 1e-12, "print size uses screen PPI"); - app.pixels_per_point = 2.0; - app.screen_ppi = 220.0; - app.run("view.actualSize", json!({})).unwrap(); - assert!((app.view().unwrap().zoom - 220.0 / 144.0).abs() < 1e-12); + assert!((app.view().unwrap().zoom - 96.0 / 72.0).abs() < 1e-12, "an inch is 96 screen points"); } /// Performance › Animated Zoom (#394): the Zoom tool dragged sideways zooms about where it was diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 36edc28e..b5a71ba7 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -336,13 +336,6 @@ pub struct VectorcraftApp { last_time: f64, /// Canvas rect of the last frame (screen points), for control-channel coordinate mapping. pub canvas_rect: Option, - /// Physical pixels per inch assumed for View → Actual Size when Preferences › Display Print - /// Size at 100% Zoom is on. Defaults to the CSS reference density (96). Tests (and a future - /// safe host probe) may set a measured value. - pub screen_ppi: f64, - /// Last canvas `pixels_per_point` (egui's scale factor). Paired with [`Self::screen_ppi`] for - /// Actual Size under Display Print Size. - pub pixels_per_point: f64, /// Hover position in document coordinates. pub hover_doc: Option, /// System clipboard: SVG to publish next frame, the last SVG we published (so pasting it back @@ -444,8 +437,6 @@ impl VectorcraftApp { frame: 0, last_time: 0.0, canvas_rect: None, - screen_ppi: 96.0, - pixels_per_point: 1.0, hover_doc: None, custom_titlebar: false, graphics_adapter: None, diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index 61688302..598f070d 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -209,7 +209,7 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[ "view.actualSize", "Actual Size", "Cmd+1", - "{} 100%: with Display Print Size at 100% Zoom off, one document point per screen point; on, one document inch fills one physical inch on the screen (screen PPI / (72 × pixels_per_point))", + "{} 100%: with Display Print Size at 100% Zoom off, one document point per screen point; on, one document inch fills 96 screen points (an inch at the system's reference density, whatever the display scaling)", ), ("view.setZoom", "Set Zoom", "", "{zoom: percent, center?: [x,y]}"), ( diff --git a/docs/mcp.md b/docs/mcp.md index 024b2ac8..47d5f8b8 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -1433,7 +1433,7 @@ control channel's `ui.drag` scrubs), `showHomeScreen` (on by default: the Home s off, an empty window, and the Home button or `app.home` still shows the screen), `autoCollapseIconPanels` (off by default: on, a click away from a panel popped out of the icon column puts it away) and `displayPrintSize` (off by default: View › Actual Size / `view.actualSize` is one document point per screen point; on, one document inch fills -one physical inch using the CSS reference density of 96 ppi). +96 screen points, an inch at the system's reference density whatever the display scaling). The Smart Guides preferences (Preferences › Smart Guides) apply to `pointer_gesture` with Smart Guides on (the default view) and to the mouse; they change what the tools show and how far a target pulls, and only Construction