aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorToBinio <Tobias.frischmann1@gmail.com>2025-04-07 15:54:29 +0200
committerGitHub <noreply@github.com>2025-04-07 13:54:29 +0000
commit4f41354349bfbf0802f417ccd57d8b11b30637d9 (patch)
treeb1bf3d93570b392c6782ef47ab5fd291c5706d1e /components
parent3e249c9bc42e16963a1a3f745d9e846d0051e187 (diff)
downloadservo-4f41354349bfbf0802f417ccd57d8b11b30637d9.tar.gz
servo-4f41354349bfbf0802f417ccd57d8b11b30637d9.zip
layout: Scale images in `image_set` by their specified resolution (#36374)
This PR makes it so the `resolution` factor in `image-set` also affects the image size. For instance, in the example below: ```css background-image: image-set("./small.png" 1x, "./large.png" 2x); ``` if `large.png` is used, an image which is 32x32 will be rendered as 16x16. This is specified in <https://drafts.csswg.org/css-images-4/#image-set-notation>. Testing: - `css/css-images/image-set/image-set-resolution-002.html` --------- Signed-off-by: tobinio <Tobias.frischmann1@gmail.com> Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Josh Matthews <josh@joshmatthews.net>
Diffstat (limited to 'components')
-rw-r--r--components/layout_2020/context.rs31
-rw-r--r--components/layout_2020/display_list/mod.rs11
2 files changed, 30 insertions, 12 deletions
diff --git a/components/layout_2020/context.rs b/components/layout_2020/context.rs
index 04374849f74..71372ffe224 100644
--- a/components/layout_2020/context.rs
+++ b/components/layout_2020/context.rs
@@ -5,6 +5,7 @@
use std::sync::Arc;
use base::id::PipelineId;
+use euclid::Size2D;
use fnv::FnvHashMap;
use fonts::FontContext;
use fxhash::FxHashMap;
@@ -148,8 +149,7 @@ impl LayoutContext<'_> {
Some(ImageOrMetadataAvailable::ImageAvailable { image, .. }) => {
self.handle_animated_image(node, image.clone());
let image_info = WebRenderImageInfo {
- width: image.width,
- height: image.height,
+ size: Size2D::new(image.width, image.height),
key: image.id,
};
if image_info.key.is_none() {
@@ -188,10 +188,29 @@ impl LayoutContext<'_> {
)?;
Some(ResolvedImage::Image(webrender_info))
},
- Image::ImageSet(image_set) => image_set
- .items
- .get(image_set.selected_index)
- .and_then(|image| self.resolve_image(node, &image.image)),
+ Image::ImageSet(image_set) => {
+ image_set
+ .items
+ .get(image_set.selected_index)
+ .and_then(|image| {
+ self.resolve_image(node, &image.image)
+ .map(|info| match info {
+ ResolvedImage::Image(mut image_info) => {
+ // From <https://drafts.csswg.org/css-images-4/#image-set-notation>:
+ // > A <resolution> (optional). This is used to help the UA decide
+ // > which <image-set-option> to choose. If the image reference is
+ // > for a raster image, it also specifies the image’s natural
+ // > resolution, overriding any other source of data that might
+ // > supply a natural resolution.
+ image_info.size = (image_info.size.to_f32() /
+ image.resolution.dppx())
+ .to_u32();
+ ResolvedImage::Image(image_info)
+ },
+ _ => info,
+ })
+ })
+ },
}
}
}
diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs
index 0e71f8505dc..8a746a01184 100644
--- a/components/layout_2020/display_list/mod.rs
+++ b/components/layout_2020/display_list/mod.rs
@@ -61,8 +61,7 @@ pub use stacking_context::*;
#[derive(Clone, Copy)]
pub struct WebRenderImageInfo {
- pub width: u32,
- pub height: u32,
+ pub size: Size2D<u32, UnknownUnit>,
pub key: Option<wr::ImageKey>,
}
@@ -817,8 +816,8 @@ impl<'a> BuilderForBoxFragment<'a> {
// FIXME: https://drafts.csswg.org/css-images-4/#the-image-resolution
let dppx = 1.0;
let intrinsic = NaturalSizes::from_width_and_height(
- image_info.width as f32 / dppx,
- image_info.height as f32 / dppx,
+ image_info.size.width as f32 / dppx,
+ image_info.size.height as f32 / dppx,
);
let Some(image_key) = image_info.key else {
continue;
@@ -1007,8 +1006,8 @@ impl<'a> BuilderForBoxFragment<'a> {
return false;
};
- width = image_info.width as f32;
- height = image_info.height as f32;
+ width = image_info.size.width as f32;
+ height = image_info.size.height as f32;
NinePatchBorderSource::Image(key, ImageRendering::Auto)
},
Some(ResolvedImage::Gradient(gradient)) => {