mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-30 13:56:46 -06:00
Convert px/unitless SVG root size to mm when a viewBox is present (#1749)
Found while testing crates/io/src/svg_read.rs:576-593 (parse_length_mm), used at 605-612 (viewport) Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
7d2fbd959a
commit
f686a595e6
@@ -620,8 +620,15 @@ fn viewport(e: &BytesStart) -> Result<Mat3> {
|
||||
_ => None,
|
||||
}
|
||||
});
|
||||
let w_mm = attr(e, b"width").as_deref().and_then(parse_length_mm);
|
||||
let h_mm = attr(e, b"height").as_deref().and_then(parse_length_mm);
|
||||
// A bare or `px` root size is in CSS pixels, not millimetres.
|
||||
let root_mm = |name: &[u8]| {
|
||||
let raw = attr(e, name)?;
|
||||
let mm = parse_length_mm(&raw)?;
|
||||
let unit = raw.trim().trim_start_matches(|c: char| c.is_ascii_digit() || matches!(c, '.' | '-' | '+' | 'e' | 'E')).trim();
|
||||
Some(if matches!(unit, "" | "px") { mm * 25.4 / 96.0 } else { mm })
|
||||
};
|
||||
let w_mm = root_mm(b"width");
|
||||
let h_mm = root_mm(b"height");
|
||||
let unit = match (vb, w_mm, h_mm) {
|
||||
(Some((_, _, vw, _)), Some(w), _) if w > 0.0 => w / vw,
|
||||
(Some((_, _, _, vh)), _, Some(h)) if h > 0.0 => h / vh,
|
||||
|
||||
@@ -2274,6 +2274,18 @@ fn svg_viewbox_scaling_and_mm_units() {
|
||||
assert!((c.center.x - 10.0).abs() < 1e-9 && (c.center.y - 5.0).abs() < 1e-9, "{c:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn svg_viewbox_with_px_or_unitless_root_size_uses_reference_pixel() {
|
||||
for w in ["800", "800px"] {
|
||||
let svg = format!(
|
||||
r#"<svg xmlns="http://www.w3.org/2000/svg" width="{w}" height="600" viewBox="0 0 400 300"><line x1="0" y1="0" x2="400" y2="0"/></svg>"#
|
||||
);
|
||||
let d = read(svg.as_bytes(), "vb.svg").unwrap();
|
||||
let l = first(&d, |k| if let EntityKind::Line(l) = k { Some(l.clone()) } else { None });
|
||||
assert!((l.b.x - 800.0 * 25.4 / 96.0).abs() < 1e-9, "{w}: {l:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn svg_inkscape_layers_are_kept() {
|
||||
let svg = format!(
|
||||
|
||||
Reference in New Issue
Block a user