mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Auto merge of #19651 - pyfisch:background-placement, r=emilio
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, see #19650) * 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 was done before but worked only in simple cases) See: #19649 This solves the following issues: closes #19626 closes #16657 closes #19482 (examples from http://lea.verou.me/css3patterns/ are rendered perfectly but the round border is completely ignored now) closes #19577 - `./mach build -d` does not report any errors - `./mach test-tidy` does not report any errors I enabled a few tests with the first commit but I have written about a dozen manual tests I will try to turn into ref tests either before or after this patch lands. @bors-servo try The relationship between the different inputs is visualized in this flowchart:  <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/19651) <!-- Reviewable:end -->
This commit is contained in:
commit
691bff86b6
24 changed files with 396 additions and 380 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue