layout: Replace SVG base fragment rect conditionally to support viewBox (#44420)

As titled.

Testing: Manually tested with multiple real websites with viewbox in
svg.
It looked terrible before, but now looking good!
New passing in WPT.

Partially addresses: #38985

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
This commit is contained in:
Euclid Ye
2026-04-22 15:53:59 +08:00
committed by GitHub
parent 97c08a6f95
commit 6592e8512b
6 changed files with 32 additions and 25 deletions

View File

@@ -141,7 +141,10 @@ pub(crate) enum ReplacedContentKind {
IFrame(IFrameInfo),
Canvas(CanvasInfo),
Video(VideoInfo),
SVGElement(Option<VectorImage>),
SVGElement {
vector_image: Option<VectorImage>,
has_viewbox: bool,
},
Audio,
}
@@ -301,7 +304,13 @@ impl ReplacedContents {
_ => unreachable!("SVG element can't contain a raster image."),
});
(ReplacedContentKind::SVGElement(vector_image), natural_size)
(
ReplacedContentKind::SVGElement {
vector_image,
has_viewbox: svg_data.view_box.is_some(),
},
natural_size,
)
}
fn from_content_property(node: ServoLayoutNode<'_>, context: &LayoutContext) -> Option<Self> {
@@ -563,25 +572,29 @@ impl ReplacedContents {
url: None,
}))]
},
ReplacedContentKind::SVGElement(vector_image) => {
ReplacedContentKind::SVGElement {
vector_image,
has_viewbox,
} => {
let Some(vector_image) = vector_image else {
return vec![];
};
// TODO: This is incorrect if the SVG has a viewBox.
base.rect = PhysicalSize::new(
vector_image
.metadata
.width
.try_into()
.map_or(MAX_AU, Au::from_px),
vector_image
.metadata
.height
.try_into()
.map_or(MAX_AU, Au::from_px),
)
.into();
if !has_viewbox {
base.rect = PhysicalSize::new(
vector_image
.metadata
.width
.try_into()
.map_or(MAX_AU, Au::from_px),
vector_image
.metadata
.height
.try_into()
.map_or(MAX_AU, Au::from_px),
)
.into();
}
let scale = layout_context.style_context.device_pixel_ratio();
let raster_size = Size2D::new(

View File

@@ -1,2 +0,0 @@
[inline-svg-100-percent-in-body.html]
expected: FAIL

View File

@@ -0,0 +1,2 @@
[viewBox-baseVal-change-invalid.html]
expected: FAIL

View File

@@ -1,2 +0,0 @@
[viewBox-change-repaint-001.html]
expected: FAIL

View File

@@ -1,2 +0,0 @@
[non-scaling-stroke-006.html]
expected: FAIL

View File

@@ -1,2 +0,0 @@
[small-nested-viewbox.html]
expected: FAIL