mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
Merge pull request #969 from webdevtodayjason/fix/nested-svg-viewport
SVG: percentages inside a nested <svg> resolve against its own viewport # Conflicts: # contributors/people.toml
This commit is contained in:
commit
8dc91891e9
3 files changed
+40
-4
No files matched your search
@@ -59,3 +59,6 @@ sync_github_name = false
|
||||
real_name = "Valentin Klein"
|
||||
display_name = "Valentin Klein"
|
||||
sync_github_name = true
|
||||
|
||||
[people.webdevtodayjason]
|
||||
display_name = "Jason Brashear"
|
||||
@@ -794,10 +794,10 @@ impl<'a, 'i> Parser<'a, 'i> {
|
||||
let vb = viewbox_transform(n, w, h);
|
||||
let mut children = vec![];
|
||||
let saved = (self.vw, self.vh);
|
||||
if let Some((_, vw, vh)) = viewbox(n) {
|
||||
self.vw = vw;
|
||||
self.vh = vh;
|
||||
}
|
||||
// Percentages use this viewport's user space, even without a viewBox.
|
||||
let (vw, vh) = viewbox(n).map_or((w, h), |(_, vw, vh)| (vw, vh));
|
||||
self.vw = vw;
|
||||
self.vh = vh;
|
||||
for c in n.children() {
|
||||
self.node(c, &st, &mut children, depth + 1);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,39 @@ fn paths_gradients_css_use() {
|
||||
assert!(c[0] > 0.9 && c[3] > 0.9, "{c:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_svg_percentages_use_the_nearest_viewport() {
|
||||
let d = parse(
|
||||
br#"<svg xmlns="http://www.w3.org/2000/svg" width="100" height="80" viewBox="0 0 100 80">
|
||||
<svg x="10" y="10" width="40" height="20">
|
||||
<rect id="inner" width="50%" height="50%" fill="red"/>
|
||||
<svg x="50%" width="50%" height="50%">
|
||||
<rect id="deep" width="50%" height="50%" fill="blue"/>
|
||||
</svg>
|
||||
</svg>
|
||||
<rect id="outer" y="60" width="50%" height="10" fill="green"/>
|
||||
<svg x="60" width="40" height="20" viewBox="0 0 200 100">
|
||||
<rect id="viewbox" width="50%" height="50%"/>
|
||||
</svg>
|
||||
</svg>"#,
|
||||
)
|
||||
.unwrap();
|
||||
let shapes = d.flatten();
|
||||
assert_eq!(shapes.len(), 4);
|
||||
for ((_, _, shape), (name, width, height)) in
|
||||
shapes.iter().zip([("inner", 20.0, 10.0), ("deep", 10.0, 5.0), ("outer", 50.0, 10.0), ("viewbox", 100.0, 50.0)])
|
||||
{
|
||||
assert_eq!(shape.name, name);
|
||||
assert!(matches!(shape.geom, Geom::Rect { w, h, .. } if w == width && h == height), "{name}: {:?}", shape.geom);
|
||||
}
|
||||
let img = rasterize(&d, 100, 80, 1.0);
|
||||
assert_eq!(px(&img, 15, 15), [1.0, 0.0, 0.0, 1.0]);
|
||||
assert_eq!(px(&img, 35, 12), [0.0, 0.0, 1.0, 1.0]);
|
||||
assert_eq!(px(&img, 35, 17)[3], 0.0);
|
||||
assert_eq!(px(&img, 45, 65)[3], 1.0);
|
||||
assert_eq!(px(&img, 55, 65)[3], 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn malformed_input() {
|
||||
assert!(parse(b"<html/>").is_err());
|
||||
|
||||
Reference in new issue
Block a user