Keep significant digits in SVG matrix scale coefficients

Found while testing crates/svg/src/lib.rs:97 (num, used by matrix at :129 for the image pattern's patternTransform at :243-254)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilverandClaude Haiku 5.5 committed 2026-10-25 06:07:08 +00:00
1 parent 92682728e9
commit 283c6de2b1
2 files changed
+29 -1

No files matched your search

+16 -1
View File
@@ -126,9 +126,24 @@ fn path_d(p: &BezPath) -> String {
s
}
/// A matrix scale/shear coefficient to 6 significant digits (unlike [`num`], small values survive).
fn coeff(v: f64) -> String {
if !v.is_finite() || v == 0.0 {
return "0".into();
}
let digits = 5 - v.abs().log10().floor() as i32;
let p = 10f64.powi(digits);
let r = (v * p).round() / p;
format!("{r}")
}
fn matrix(a: Affine) -> String {
let c = a.as_coeffs();
format!("matrix({} {} {} {} {} {})", num(c[0]), num(c[1]), num(c[2]), num(c[3]), num(c[4]), num(c[5]))
// Snap float noise (e.g. 6e-17 from a 90 degree rotation) to zero, relative to the largest term.
let eps = c[..4].iter().fold(0.0f64, |m, v| m.max(v.abs())) * 1e-12;
let eps = eps.max(1e-12);
let k = |v: f64| if v.abs() <= eps { "0".to_string() } else { coeff(v) };
format!("matrix({} {} {} {} {} {})", k(c[0]), k(c[1]), k(c[2]), k(c[3]), num(c[4]), num(c[5]))
}
/// A view of page area `b` at `k` device pixels per unit (fewer when that makes it larger than
+13
View File
@@ -264,3 +264,16 @@ fn a_filled_open_curve_is_closed_for_its_fill() {
};
assert_eq!(d.nodes().map(loops).sum::<usize>(), 1);
}
#[test]
fn matrix_keeps_small_scale_precision() {
assert_eq!(matrix(Affine::scale(0.0375)), "matrix(0.0375 0 0 0.0375 0 0)");
assert_eq!(matrix(Affine::scale(0.0001)), "matrix(0.0001 0 0 0.0001 0 0)");
}
#[test]
fn matrix_snaps_rotation_noise_and_tiny_values() {
let r = Affine::rotate(std::f64::consts::FRAC_PI_2);
assert_eq!(matrix(r), "matrix(0 1 -1 0 0 0)");
assert_eq!(matrix(Affine::scale(1e-320)), "matrix(0 0 0 0 0 0)");
}