Properly handle degenerate aspect ratios (#30245)

When a replaced element has a degenerate aspect ratio, it should be
handled as if that element did not have an aspect ratio according to
https://drafts.csswg.org/css-images/#natural-aspect-ratio.
This commit is contained in:
Martin Robinson 2023-08-30 11:00:18 +02:00 committed by GitHub
parent 5e60088276
commit f25ab59406
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 29 deletions

View file

@ -566,11 +566,7 @@ impl<'a> BuilderForBoxFragment<'a> {
match image { match image {
Image::None => {}, Image::None => {},
Image::Gradient(ref gradient) => { Image::Gradient(ref gradient) => {
let intrinsic = IntrinsicSizes { let intrinsic = IntrinsicSizes::empty();
width: None,
height: None,
ratio: None,
};
if let Some(layer) = if let Some(layer) =
&background::layout_layer(self, &source, builder, index, intrinsic) &background::layout_layer(self, &source, builder, index, intrinsic)
{ {
@ -607,13 +603,10 @@ impl<'a> BuilderForBoxFragment<'a> {
// FIXME: https://drafts.csswg.org/css-images-4/#the-image-resolution // FIXME: https://drafts.csswg.org/css-images-4/#the-image-resolution
let dppx = 1.0; let dppx = 1.0;
let intrinsic = IntrinsicSizes::from_width_and_height(
let intrinsic = IntrinsicSizes { width as f32 / dppx,
width: Some(Length::new(width as f32 / dppx)), height as f32 / dppx,
height: Some(Length::new(height as f32 / dppx)), );
// FIXME https://github.com/w3c/csswg-drafts/issues/4572
ratio: Some(width as f32 / height as f32),
};
if let Some(layer) = if let Some(layer) =
background::layout_layer(self, &source, builder, index, intrinsic) background::layout_layer(self, &source, builder, index, intrinsic)

View file

@ -54,6 +54,33 @@ pub(crate) struct IntrinsicSizes {
pub ratio: Option<CSSFloat>, pub ratio: Option<CSSFloat>,
} }
impl IntrinsicSizes {
pub(crate) fn from_width_and_height(width: f32, height: f32) -> Self {
// https://drafts.csswg.org/css-images/#natural-aspect-ratio:
// "If an object has a degenerate natural aspect ratio (at least one part being
// zero or infinity), it is treated as having no natural aspect ratio.""
let ratio = if width.is_normal() && height.is_normal() {
Some(width / height)
} else {
None
};
Self {
width: Some(Length::new(width)),
height: Some(Length::new(height)),
ratio,
}
}
pub(crate) fn empty() -> Self {
Self {
width: None,
height: None,
ratio: None,
}
}
}
#[derive(Serialize)] #[derive(Serialize)]
pub(crate) enum CanvasSource { pub(crate) enum CanvasSource {
WebGL(ImageKey), WebGL(ImageKey),
@ -121,11 +148,7 @@ impl ReplacedContent {
}; };
let intrinsic = intrinsic_size_in_dots.map_or_else( let intrinsic = intrinsic_size_in_dots.map_or_else(
|| IntrinsicSizes { || IntrinsicSizes::empty(),
width: None,
height: None,
ratio: None,
},
|intrinsic_size_in_dots| { |intrinsic_size_in_dots| {
// FIXME: should 'image-resolution' (when implemented) be used *instead* of // FIXME: should 'image-resolution' (when implemented) be used *instead* of
// `script::dom::htmlimageelement::ImageRequest::current_pixel_density`? // `script::dom::htmlimageelement::ImageRequest::current_pixel_density`?
@ -133,12 +156,7 @@ impl ReplacedContent {
let dppx = 1.0; let dppx = 1.0;
let width = (intrinsic_size_in_dots.width as CSSFloat) / dppx; let width = (intrinsic_size_in_dots.width as CSSFloat) / dppx;
let height = (intrinsic_size_in_dots.height as CSSFloat) / dppx; let height = (intrinsic_size_in_dots.height as CSSFloat) / dppx;
IntrinsicSizes { IntrinsicSizes::from_width_and_height(width, height)
width: Some(Length::new(width)),
height: Some(Length::new(height)),
// FIXME https://github.com/w3c/csswg-drafts/issues/4572
ratio: Some(width / height),
}
}, },
); );
@ -172,12 +190,7 @@ impl ReplacedContent {
return Some(Self { return Some(Self {
kind: ReplacedContentKind::Image(image), kind: ReplacedContentKind::Image(image),
intrinsic: IntrinsicSizes { intrinsic: IntrinsicSizes::from_width_and_height(width, height),
width: Some(Length::new(width)),
height: Some(Length::new(height)),
// FIXME https://github.com/w3c/csswg-drafts/issues/4572
ratio: Some(width / height),
},
base_fragment_info: BaseFragmentInfo::new_for_node(element.opaque()), base_fragment_info: BaseFragmentInfo::new_for_node(element.opaque()),
}); });
} }