diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 191283603b9..32532003f6e 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -719,44 +719,78 @@ impl Fragment { let vertical_position = model::specified(background.background_position.vertical, bounds.size.height); - let clip_display_item; + // TODO: These are some situations below where it is possible + // to determine that clipping is not necessary - this is an + // optimization to make in the future. + let clip_display_item = Some(box ClipDisplayItem { + base: BaseDisplayItem::new(bounds, self.node, level), + children: DisplayList::new(), + }); + + let image_width = Au::from_px(image.width as int); + let image_height = Au::from_px(image.height as int); + match background.background_attachment { background_attachment::scroll => { - clip_display_item = None; bounds.origin.x = bounds.origin.x + horizontal_position; bounds.origin.y = bounds.origin.y + vertical_position; - bounds.size.width = bounds.size.width - horizontal_position; - bounds.size.height = bounds.size.height - vertical_position; + + // Adjust sizes for `background-repeat`. + match background.background_repeat { + background_repeat::no_repeat => { + bounds.size.width = Au::min(bounds.size.width - horizontal_position, image_width); + bounds.size.height = Au::min(bounds.size.height - vertical_position, image_height); + } + background_repeat::repeat_x => { + bounds.size.height = Au::min(bounds.size.height - vertical_position, image_height); + if horizontal_position > Au(0) { + bounds.origin.x = bounds.origin.x - image_width; + bounds.size.width = bounds.size.width + image_width; + } + } + background_repeat::repeat_y => { + bounds.size.width = Au::min(bounds.size.width - horizontal_position, image_width); + if vertical_position > Au(0) { + bounds.origin.y = bounds.origin.y - image_height; + bounds.size.height = bounds.size.height + image_height; + } + } + background_repeat::repeat => { + if horizontal_position > Au(0) { + bounds.origin.x = bounds.origin.x - image_width; + bounds.size.width = bounds.size.width + image_width; + } + if vertical_position > Au(0) { + bounds.origin.y = bounds.origin.y - image_height; + bounds.size.height = bounds.size.height + image_height; + } + } + }; } background_attachment::fixed => { - clip_display_item = Some(box ClipDisplayItem { - base: BaseDisplayItem::new(bounds, self.node, level), - children: DisplayList::new(), - }); - bounds = Rect { origin: Point2D(horizontal_position, vertical_position), size: Size2D(bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height), - } + }; + + // Adjust sizes for `background-repeat`. + match background.background_repeat { + background_repeat::no_repeat => { + bounds.size.width = image_width; + bounds.size.height = image_height; + } + background_repeat::repeat_x => { + bounds.size.height = image_height; + } + background_repeat::repeat_y => { + bounds.size.width = image_width; + } + background_repeat::repeat => {} + }; } } - // Adjust sizes for `background-repeat`. - match background.background_repeat { - background_repeat::no_repeat => { - bounds.size.width = Au::from_px(image.width as int); - bounds.size.height = Au::from_px(image.height as int) - } - background_repeat::repeat_x => { - bounds.size.height = Au::from_px(image.height as int) - } - background_repeat::repeat_y => { - bounds.size.width = Au::from_px(image.width as int) - } - background_repeat::repeat => {} - }; - // Create the image display item. let image_display_item = ImageDisplayItemClass(box ImageDisplayItem { base: BaseDisplayItem::new(bounds, self.node, level), diff --git a/tests/ref/background_image_position_a.html b/tests/ref/background_image_position_a.html new file mode 100644 index 00000000000..292c7eedd9c --- /dev/null +++ b/tests/ref/background_image_position_a.html @@ -0,0 +1,24 @@ + + +
+ + + + X + + diff --git a/tests/ref/background_image_position_ref.html b/tests/ref/background_image_position_ref.html new file mode 100644 index 00000000000..fe2f332aa29 --- /dev/null +++ b/tests/ref/background_image_position_ref.html @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/tests/ref/background_repeat_none_b.html b/tests/ref/background_repeat_none_b.html index 4448cf19eb9..d1865048891 100644 --- a/tests/ref/background_repeat_none_b.html +++ b/tests/ref/background_repeat_none_b.html @@ -4,8 +4,8 @@