From 58060a58040729a38b8e1846dd096804f26dad77 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sun, 25 Oct 2026 07:04:03 +0100 Subject: [PATCH] Fix ruler major tick spacing skipping the 10x step Found while testing crates/geom/src/units.rs:~147 (Unit::ruler_ticks, the `while major * zoom < 50.0` loop) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/geom/src/units.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/geom/src/units.rs b/crates/geom/src/units.rs index f1077ffce..cc47fadb2 100644 --- a/crates/geom/src/units.rs +++ b/crates/geom/src/units.rs @@ -127,7 +127,10 @@ impl Unit { // Choose a major spacing (base × 1, 2, 5, 10…) at least ~60 px apart, or base / 2^n when zoomed in. let mut major = base; while major * zoom < 50.0 { - major *= if (major / base).log10().fract().abs() < 1e-9 { 2.0 } else { 2.5 }; + let ratio = major / base; + let mantissa = ratio / 10f64.powf(ratio.log10().floor()); + // 1 -> 2 -> 5 -> 10: double at mantissa 1 or 5, ×2.5 at mantissa 2. + major *= if (mantissa - 2.0).abs() < 1e-6 { 2.5 } else { 2.0 }; } while major * zoom > 160.0 && major > base / 64.0 { major /= 2.0; @@ -299,6 +302,12 @@ pub fn format_measure_prec(pt: f64, unit: Unit, decimals: usize) -> String { mod tests { use super::*; + #[test] + fn ruler_major_spacing_steps_1_2_5_10() { + assert!(close(Unit::Points.ruler_ticks(0.1).0, 720.0)); + assert!(close(Unit::Points.ruler_ticks(0.01).0, 7200.0)); + } + fn p(s: &str) -> f64 { parse_measure(s, Unit::Points).unwrap() }