Implement background-position keyword values

Also fixes calculation of background-position percentages:

Rather than multiplying the container size by a percent and aligning the top
left of the image at the resulting width, we also need to subtract a
corresponding percent of the image size, per
http://dev.w3.org/csswg/css2/colors.html#propdef-background-position

"A value pair of '100% 100%' places the lower right corner of the image in the
lower right corner of the padding box. With a value pair of '14% 84%', the
point 14% across and 84% down the image is to be placed at the point 14%
across and 84% down the padding box."
This commit is contained in:
Matt Brubeck 2014-09-11 17:12:25 -07:00
parent 66a7de750c
commit 6c9524b687
9 changed files with 258 additions and 50 deletions

View file

@ -728,12 +728,15 @@ impl Fragment {
};
debug!("(building display list) building background image");
let image_width = Au::from_px(image.width as int);
let image_height = Au::from_px(image.height as int);
// Adjust bounds for `background-position` and `background-attachment`.
let mut bounds = *absolute_bounds;
let horizontal_position = model::specified(background.background_position.horizontal,
bounds.size.width);
bounds.size.width - image_width);
let vertical_position = model::specified(background.background_position.vertical,
bounds.size.height);
bounds.size.height - image_height);
// TODO: These are some situations below where it is possible
// to determine that clipping is not necessary - this is an
@ -743,9 +746,6 @@ impl Fragment {
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 => {
bounds.origin.x = bounds.origin.x + horizontal_position;
@ -759,25 +759,21 @@ impl Fragment {
}
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;
if horizontal_position != Au(0) {
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;
if vertical_position != Au(0) {
bounds.size.height = bounds.size.height + image_height;
}
}
background_repeat::repeat => {
if horizontal_position > Au(0) {
bounds.origin.x = bounds.origin.x - image_width;
if horizontal_position != Au(0) {
bounds.size.width = bounds.size.width + image_width;
}
if vertical_position > Au(0) {
bounds.origin.y = bounds.origin.y - image_height;
if vertical_position != Au(0) {
bounds.size.height = bounds.size.height + image_height;
}
}