mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-10 20:42:05 +00:00
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:
1 parent
92682728e9
commit
283c6de2b1
2 files changed
+29
-1
No files matched your search
+16
-1
@@ -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
|
||||
|
||||
@@ -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)");
|
||||
}
|
||||
Reference in new issue
Block a user