Skip to content

Commit fb41d5b

Browse files
ToBiniomrobinsonjdm
authored andcommitted
layout: Scale images in image_set by their specified resolution (servo#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 <[email protected]> Signed-off-by: Martin Robinson <[email protected]> Co-authored-by: Martin Robinson <[email protected]> Co-authored-by: Josh Matthews <[email protected]>
1 parent acf3042 commit fb41d5b

File tree

3 files changed

+30
-14
lines changed

3 files changed

+30
-14
lines changed

components/layout_2020/context.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use std::sync::Arc;
66

77
use base::id::PipelineId;
8+
use euclid::Size2D;
89
use fnv::FnvHashMap;
910
use fonts::FontContext;
1011
use fxhash::FxHashMap;
@@ -148,8 +149,7 @@ impl LayoutContext<'_> {
148149
Some(ImageOrMetadataAvailable::ImageAvailable { image, .. }) => {
149150
self.handle_animated_image(node, image.clone());
150151
let image_info = WebRenderImageInfo {
151-
width: image.width,
152-
height: image.height,
152+
size: Size2D::new(image.width, image.height),
153153
key: image.id,
154154
};
155155
if image_info.key.is_none() {
@@ -188,10 +188,29 @@ impl LayoutContext<'_> {
188188
)?;
189189
Some(ResolvedImage::Image(webrender_info))
190190
},
191-
Image::ImageSet(image_set) => image_set
192-
.items
193-
.get(image_set.selected_index)
194-
.and_then(|image| self.resolve_image(node, &image.image)),
191+
Image::ImageSet(image_set) => {
192+
image_set
193+
.items
194+
.get(image_set.selected_index)
195+
.and_then(|image| {
196+
self.resolve_image(node, &image.image)
197+
.map(|info| match info {
198+
ResolvedImage::Image(mut image_info) => {
199+
// From <https://drafts.csswg.org/css-images-4/#image-set-notation>:
200+
// > A <resolution> (optional). This is used to help the UA decide
201+
// > which <image-set-option> to choose. If the image reference is
202+
// > for a raster image, it also specifies the image’s natural
203+
// > resolution, overriding any other source of data that might
204+
// > supply a natural resolution.
205+
image_info.size = (image_info.size.to_f32() /
206+
image.resolution.dppx())
207+
.to_u32();
208+
ResolvedImage::Image(image_info)
209+
},
210+
_ => info,
211+
})
212+
})
213+
},
195214
}
196215
}
197216
}

components/layout_2020/display_list/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ pub use stacking_context::*;
6161

6262
#[derive(Clone, Copy)]
6363
pub struct WebRenderImageInfo {
64-
pub width: u32,
65-
pub height: u32,
64+
pub size: Size2D<u32, UnknownUnit>,
6665
pub key: Option<wr::ImageKey>,
6766
}
6867

@@ -817,8 +816,8 @@ impl<'a> BuilderForBoxFragment<'a> {
817816
// FIXME: https://drafts.csswg.org/css-images-4/#the-image-resolution
818817
let dppx = 1.0;
819818
let intrinsic = NaturalSizes::from_width_and_height(
820-
image_info.width as f32 / dppx,
821-
image_info.height as f32 / dppx,
819+
image_info.size.width as f32 / dppx,
820+
image_info.size.height as f32 / dppx,
822821
);
823822
let Some(image_key) = image_info.key else {
824823
continue;
@@ -1007,8 +1006,8 @@ impl<'a> BuilderForBoxFragment<'a> {
10071006
return false;
10081007
};
10091008

1010-
width = image_info.width as f32;
1011-
height = image_info.height as f32;
1009+
width = image_info.size.width as f32;
1010+
height = image_info.size.height as f32;
10121011
NinePatchBorderSource::Image(key, ImageRendering::Auto)
10131012
},
10141013
Some(ResolvedImage::Gradient(gradient)) => {

tests/wpt/meta/css/css-images/image-set/image-set-resolution-002.html.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)