Unify background placement code

Merges the implementations for background-image placement
from gradients and images. Add missing parts and fix bugs.

Now supported are the CSS properties:

* background-attachment (except for local value)
* background-clip
* background-origin
* background-position-x/y
* background-repeat
* background-size

It should be noted that backgrounds are not clipped to
rounded border corners.
This commit is contained in:
Pyfisch 2017-12-27 22:15:58 +01:00
parent d96fb89c31
commit 3b3d4a9853
9 changed files with 306 additions and 344 deletions

View file

@ -421,77 +421,6 @@ impl ImageFragmentInfo {
metadata: metadata,
}
}
pub fn tile_image_round(position: &mut Au,
size: &mut Au,
absolute_anchor_origin: Au,
image_size: &mut Au) {
if *size == Au(0) || *image_size == Au(0) {
*position = Au(0);
*size =Au(0);
return;
}
let number_of_tiles = (size.to_f32_px() / image_size.to_f32_px()).round().max(1.0);
*image_size = *size / (number_of_tiles as i32);
ImageFragmentInfo::tile_image(position, size, absolute_anchor_origin, *image_size);
}
pub fn tile_image_spaced(position: &mut Au,
size: &mut Au,
tile_spacing: &mut Au,
absolute_anchor_origin: Au,
image_size: Au) {
if *size == Au(0) || image_size == Au(0) {
*position = Au(0);
*size = Au(0);
*tile_spacing = Au(0);
return;
}
// Per the spec, if the space available is not enough for two images, just tile as
// normal but only display a single tile.
if image_size * 2 >= *size {
ImageFragmentInfo::tile_image(position,
size,
absolute_anchor_origin,
image_size);
*tile_spacing = Au(0);
*size = image_size;
return;
}
// Take the box size, remove room for two tiles on the edges, and then calculate how many
// other tiles fit in between them.
let size_remaining = *size - (image_size * 2);
let num_middle_tiles = (size_remaining.to_f32_px() / image_size.to_f32_px()).floor() as i32;
// Allocate the remaining space as padding between tiles. background-position is ignored
// as per the spec, so the position is just the box origin. We are also ignoring
// background-attachment here, which seems unspecced when combined with
// background-repeat: space.
let space_for_middle_tiles = image_size * num_middle_tiles;
*tile_spacing = (size_remaining - space_for_middle_tiles) / (num_middle_tiles + 1);
}
/// Tile an image
pub fn tile_image(position: &mut Au,
size: &mut Au,
absolute_anchor_origin: Au,
image_size: Au) {
// Avoid division by zero below!
if image_size == Au(0) {
return
}
let delta_pixels = absolute_anchor_origin - *position;
let image_size_px = image_size.to_f32_px();
let tile_count = ((delta_pixels.to_f32_px() + image_size_px - 1.0) / image_size_px).floor();
let offset = image_size * (tile_count as i32);
let new_position = absolute_anchor_origin - offset;
*size = *position - new_position + *size;
*position = new_position;
}
}
/// A fragment that represents an inline frame (iframe). This stores the frame ID so that the