Merge pull request #1082 from webdevtodayjason/fix/root-svg-viewport

This commit is contained in:
Brandon Thomas committed 2026-10-13 04:29:13 -04:00
commit 3d2c4a67a1
2 files changed
+26

No files matched your search

+4
View File
@@ -1147,6 +1147,10 @@ pub fn parse(bytes: &[u8]) -> Result<Doc, Error> {
}
None => (pct_or("width", 'x', 300.0), pct_or("height", 'y', 150.0)),
};
// Percentages use the root viewport's user space, even without a viewBox. A size that is not
// a finite positive number keeps the 300x150 default, so it cannot produce NaN geometry.
let usable = |v: f64, d: f64| if v.is_finite() && v > 0.0 { v } else { d };
(p.vw, p.vh) = vb.map_or((usable(dw, 300.0), usable(dh, 150.0)), |(_, w, h)| (w, h));
let mut rst = st.clone();
let (opacity, _) = p.cascade(root, &mut rst);
let mut children = vec![];
+22
View File
@@ -86,6 +86,28 @@ fn paths_gradients_css_use() {
assert!(c[0] > 0.9 && c[3] > 0.9, "{c:?}");
}
#[test]
fn root_svg_percentages_use_the_document_viewport() {
for (attrs, width, height) in [
("width=\"100\" height=\"80\"", 100.0, 80.0),
("width=\"50%\" height=\"200%\"", 150.0, 300.0),
("", 300.0, 150.0),
("width=\"100\" height=\"80\" viewBox=\"0 0 200 160\"", 200.0, 160.0),
("width=\"NaN%\" height=\"1e400\"", 300.0, 150.0),
] {
let svg = format!(r#"<svg xmlns="http://www.w3.org/2000/svg" {attrs}><rect x="25%" y="25%" width="50%" height="50%"/></svg>"#);
let d = parse(svg.as_bytes()).unwrap();
let shapes = d.flatten();
assert_eq!(shapes.len(), 1);
assert!(
matches!(shapes[0].2.geom, Geom::Rect { x, y, w, h, .. }
if x == width / 4.0 && y == height / 4.0 && w == width / 2.0 && h == height / 2.0),
"{attrs}: {:?}",
shapes[0].2.geom
);
}
}
#[test]
fn nested_svg_percentages_use_the_nearest_viewport() {
let d = parse(