Add support for background-repeat: space and round

This adds support for more background-repeat modes using the legacy
rendering backend.
This commit is contained in:
Martin Robinson 2016-09-20 11:51:51 +02:00
parent 821797d6f7
commit 68ae97fd0e
14 changed files with 193 additions and 105 deletions

View file

@ -425,18 +425,73 @@ impl ImageFragmentInfo {
}
}
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, virtual_position: Au, image_size: u32) {
pub fn tile_image(position: &mut Au,
size: &mut Au,
absolute_anchor_origin: Au,
image_size: Au) {
// Avoid division by zero below!
let image_size = image_size as i32;
if image_size == 0 {
if image_size == Au(0) {
return
}
let delta_pixels = (virtual_position - *position).to_px();
let tile_count = (delta_pixels + image_size - 1) / image_size;
let offset = Au::from_px(image_size * tile_count);
let new_position = virtual_position - offset;
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;
}