mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
layout: background-origin attribute for gradients
Fixes the glitches mentioned in #19554. Now gradient tiles are placed in the whole bounding box.
This commit is contained in:
parent
7897bd15d7
commit
b0492f53af
8 changed files with 202 additions and 25 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -47,7 +47,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "app_units"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1049,7 +1049,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
name = "gfx"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1454,7 +1454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
name = "layout"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"canvas_traits 0.0.1",
|
||||
|
@ -1504,7 +1504,7 @@ dependencies = [
|
|||
name = "layout_thread"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1679,7 +1679,7 @@ dependencies = [
|
|||
name = "malloc_size_of"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashglobe 0.1.0",
|
||||
|
@ -2530,7 +2530,7 @@ name = "script"
|
|||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"angle 0.5.0 (git+https://github.com/servo/angle?branch=servo)",
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"audio-video-metadata 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2613,7 +2613,7 @@ dependencies = [
|
|||
name = "script_layout_interface"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"canvas_traits 0.0.1",
|
||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2954,7 +2954,7 @@ dependencies = [
|
|||
name = "servo_geometry"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"malloc_size_of 0.0.1",
|
||||
"malloc_size_of_derive 0.0.1",
|
||||
|
@ -3104,7 +3104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
name = "style"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bindgen 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3168,7 +3168,7 @@ dependencies = [
|
|||
name = "style_tests"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3190,7 +3190,7 @@ dependencies = [
|
|||
name = "style_traits"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3561,7 +3561,7 @@ name = "webrender"
|
|||
version = "0.56.1"
|
||||
source = "git+https://github.com/servo/webrender#67f7e0edeabba6861250922d47f8c6a1b2232d4b"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3589,7 +3589,7 @@ name = "webrender_api"
|
|||
version = "0.56.1"
|
||||
source = "git+https://github.com/servo/webrender#67f7e0edeabba6861250922d47f8c6a1b2232d4b"
|
||||
dependencies = [
|
||||
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3745,7 +3745,7 @@ dependencies = [
|
|||
"checksum angle 0.5.0 (git+https://github.com/servo/angle?branch=servo)" = "<none>"
|
||||
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
|
||||
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
||||
"checksum app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29069a9b483f7780aebb55dafb360c6225eefdc1f98c8d336a65148fd10c37b1"
|
||||
"checksum app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4720c83543de184d9f6add2fdb8e8031543497b8506620884c16e125b493c09"
|
||||
"checksum arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0ef4a9820019a0c91d918918c93dc71d469f581a49b47ddc1d285d4270bbe2"
|
||||
"checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
|
||||
"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860"
|
||||
|
|
|
@ -10,7 +10,7 @@ name = "layout"
|
|||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
app_units = "0.6"
|
||||
app_units = "0.6.1"
|
||||
atomic_refcell = "0.1"
|
||||
bitflags = "1.0"
|
||||
canvas_traits = {path = "../canvas_traits"}
|
||||
|
|
|
@ -58,6 +58,7 @@ use style::computed_values::position::T as StylePosition;
|
|||
use style::computed_values::visibility::T as Visibility;
|
||||
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode};
|
||||
use style::properties::ComputedValues;
|
||||
use style::properties::longhands::background_origin::single_value::computed_value::T as BackgroundOrigin;
|
||||
use style::properties::longhands::border_image_repeat::computed_value::RepeatKeyword;
|
||||
use style::properties::style_structs;
|
||||
use style::servo::restyle_damage::ServoRestyleDamage;
|
||||
|
@ -508,7 +509,7 @@ pub trait FragmentDisplayListBuilding {
|
|||
fn build_display_list_for_background_gradient(&self,
|
||||
state: &mut DisplayListBuildState,
|
||||
display_list_section: DisplayListSection,
|
||||
absolute_bounds: &Rect<Au>,
|
||||
absolute_bounds: Rect<Au>,
|
||||
clip: &LocalClip,
|
||||
gradient: &Gradient,
|
||||
style: &ComputedValues,
|
||||
|
@ -1123,7 +1124,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
Either::Second(Image::Gradient(ref gradient)) => {
|
||||
self.build_display_list_for_background_gradient(state,
|
||||
display_list_section,
|
||||
&absolute_bounds,
|
||||
*absolute_bounds,
|
||||
&clip,
|
||||
gradient,
|
||||
style,
|
||||
|
@ -1414,22 +1415,56 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
fn build_display_list_for_background_gradient(&self,
|
||||
state: &mut DisplayListBuildState,
|
||||
display_list_section: DisplayListSection,
|
||||
absolute_bounds: &Rect<Au>,
|
||||
absolute_bounds: Rect<Au>,
|
||||
clip: &LocalClip,
|
||||
gradient: &Gradient,
|
||||
style: &ComputedValues,
|
||||
index: usize) {
|
||||
// Calculate where the first "tile" needs to be placed on one axis.
|
||||
// * base is the beginning of the visible area
|
||||
// * start is the current "tile" position
|
||||
// * tile is the length of the "tile"
|
||||
// Returns a difference between start and new start.
|
||||
// It holds that base - tile < start - diff <= base
|
||||
fn get_first_tile(base: Au, start: Au, tile: Au) -> Au {
|
||||
if tile == Au(0) {
|
||||
return Au(0);
|
||||
}
|
||||
if start > base {
|
||||
((start - base) / tile + 1) * tile
|
||||
} else {
|
||||
((base - start) / tile) * tile
|
||||
}
|
||||
}
|
||||
|
||||
let bg = style.get_background();
|
||||
let bg_origin = get_cyclic(&bg.background_origin.0, index).clone();
|
||||
let bg_size = get_cyclic(&bg.background_size.0, index).clone();
|
||||
let bg_position_x = get_cyclic(&bg.background_position_x.0, index).clone();
|
||||
let bg_position_y = get_cyclic(&bg.background_position_y.0, index).clone();
|
||||
let border = self.border_width().to_physical(style.writing_mode);
|
||||
|
||||
let mut bounds = *absolute_bounds;
|
||||
bounds.origin.x = bounds.origin.x + border.left + bg_position_x.to_used_value(bounds.size.width);
|
||||
bounds.origin.y = bounds.origin.y + border.top + bg_position_y.to_used_value(bounds.size.height);
|
||||
bounds.size.width = bounds.size.width - border.horizontal();
|
||||
bounds.size.height = bounds.size.height - border.vertical();
|
||||
let mut bounds = absolute_bounds;
|
||||
|
||||
match bg_origin {
|
||||
BackgroundOrigin::BorderBox => {}
|
||||
BackgroundOrigin::PaddingBox => {
|
||||
let border = style.logical_border_width().to_physical(style.writing_mode);
|
||||
bounds.origin.x += border.left;
|
||||
bounds.origin.y += border.top;
|
||||
bounds.size.width -= border.horizontal();
|
||||
bounds.size.height -= border.vertical();
|
||||
}
|
||||
BackgroundOrigin::ContentBox => {
|
||||
let border_padding = self.border_padding.to_physical(style.writing_mode);
|
||||
bounds.origin.x += border_padding.left;
|
||||
bounds.origin.y += border_padding.top;
|
||||
bounds.size.width -= border_padding.horizontal();
|
||||
bounds.size.height -= border_padding.vertical();
|
||||
}
|
||||
}
|
||||
|
||||
bounds.origin.x += bg_position_x.to_used_value(bounds.size.width);
|
||||
bounds.origin.y += bg_position_y.to_used_value(bounds.size.height);
|
||||
|
||||
let tile = match bg_size {
|
||||
BackgroundSize::Cover | BackgroundSize::Contain => bounds.size,
|
||||
|
@ -1442,7 +1477,18 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
}
|
||||
};
|
||||
|
||||
let base = state.create_base_display_item(&bounds,
|
||||
let diff_x = get_first_tile(absolute_bounds.origin.x,
|
||||
bounds.origin.x,
|
||||
tile.width);
|
||||
let diff_y = get_first_tile(absolute_bounds.origin.y,
|
||||
bounds.origin.y,
|
||||
tile.height);
|
||||
let tiled_bounds = Rect::new(
|
||||
Point2D::new(bounds.origin.x - diff_x, bounds.origin.y - diff_y),
|
||||
Size2D::new(absolute_bounds.size.width + diff_x,
|
||||
absolute_bounds.size.height + diff_y));
|
||||
|
||||
let base = state.create_base_display_item(&tiled_bounds,
|
||||
*clip,
|
||||
self.node,
|
||||
style.get_cursor(Cursor::Default),
|
||||
|
|
|
@ -112737,6 +112737,18 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/gradient-border-box.html": [
|
||||
[
|
||||
"/css/css-images/gradient-border-box.html",
|
||||
[
|
||||
[
|
||||
"/css/css-images/gradient-border-box-ref.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/gradient-button.html": [
|
||||
[
|
||||
"/css/css-images/gradient-button.html",
|
||||
|
@ -112749,6 +112761,18 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/gradient-content-box.html": [
|
||||
[
|
||||
"/css/css-images/gradient-content-box.html",
|
||||
[
|
||||
[
|
||||
"/css/css-images/gradient-content-box-ref.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/gradient-move-stops.html": [
|
||||
[
|
||||
"/css/css-images/gradient-move-stops.html",
|
||||
|
@ -239550,11 +239574,21 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/gradient-border-box-ref.html": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/gradient-button-ref.html": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/gradient-content-box-ref.html": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/gradient-move-stops-ref.html": [
|
||||
[
|
||||
{}
|
||||
|
@ -481656,6 +481690,14 @@
|
|||
"94471f5d29319241d0d25b8391430778f668ff4f",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-images/gradient-border-box-ref.html": [
|
||||
"ccf241348a131e495269e8bcc108a0253fd3fc7e",
|
||||
"support"
|
||||
],
|
||||
"css/css-images/gradient-border-box.html": [
|
||||
"fe78a2c52e0a89e788edf339c0d8d75c9522ad5a",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-images/gradient-button-ref.html": [
|
||||
"17a42eca5cfb86e29bfb5e20a65f0585d9727e30",
|
||||
"support"
|
||||
|
@ -481664,6 +481706,14 @@
|
|||
"41dc276e1c60a3fbf7920f44b8032fc2b0d7114e",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-images/gradient-content-box-ref.html": [
|
||||
"a030609470853d73ca1363840c4b94da6d49bb43",
|
||||
"support"
|
||||
],
|
||||
"css/css-images/gradient-content-box.html": [
|
||||
"5e74191a82ee45a5441d595c79b2a41b34748038",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-images/gradient-move-stops-ref.html": [
|
||||
"bb2fca5aaeb7fe1abf30620695ad3fd832c0d089",
|
||||
"support"
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
#x {
|
||||
width: 280px;
|
||||
height: 280px;
|
||||
background-image: repeating-linear-gradient(to bottom right, white, black, white 30px);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="x"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Gradient Background aligned to Content Box</title>
|
||||
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-background-origin">
|
||||
<link rel="match" href="gradient-border-box-ref.html">
|
||||
<meta name="assert" content="The background-origin: border-box; statement is understood.">
|
||||
<style>
|
||||
#x {
|
||||
background-origin: border-box;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-style: solid;
|
||||
border-width: 40px;
|
||||
border-color: transparent;
|
||||
background-image: repeating-linear-gradient(to bottom right, white, black, white 30px);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="x"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
#x {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 40px;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
background-image: repeating-linear-gradient(to bottom right, white, black, white 30px);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="x"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Gradient Background aligned to Content Box</title>
|
||||
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-background-origin">
|
||||
<link rel="match" href="gradient-content-box-ref.html">
|
||||
<meta name="assert" content="The background-origin: content-box; statement is understood.">
|
||||
<style>
|
||||
#x {
|
||||
background-origin: content-box;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 40px;
|
||||
background-image: repeating-linear-gradient(to bottom right, white, black, white 30px);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="x"></div>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue