mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Implement correct corner clipping for background color
Add one regression ref test. See also #19649
This commit is contained in:
parent
691bff86b6
commit
b3b49e3ff0
4 changed files with 104 additions and 15 deletions
|
@ -681,7 +681,7 @@ fn build_border_radius(abs_bounds: &Rect<Au>,
|
||||||
fn build_border_radius_for_inner_rect(outer_rect: &Rect<Au>,
|
fn build_border_radius_for_inner_rect(outer_rect: &Rect<Au>,
|
||||||
style: &ComputedValues)
|
style: &ComputedValues)
|
||||||
-> BorderRadii<Au> {
|
-> BorderRadii<Au> {
|
||||||
let mut radii = build_border_radius(&outer_rect, style.get_border());
|
let radii = build_border_radius(&outer_rect, style.get_border());
|
||||||
if radii.is_square() {
|
if radii.is_square() {
|
||||||
return radii;
|
return radii;
|
||||||
}
|
}
|
||||||
|
@ -690,18 +690,7 @@ fn build_border_radius_for_inner_rect(outer_rect: &Rect<Au>,
|
||||||
// border width), we need to adjust to border radius so that we are smaller
|
// border width), we need to adjust to border radius so that we are smaller
|
||||||
// rectangle with the same border curve.
|
// rectangle with the same border curve.
|
||||||
let border_widths = style.logical_border_width().to_physical(style.writing_mode);
|
let border_widths = style.logical_border_width().to_physical(style.writing_mode);
|
||||||
radii.top_left.width = cmp::max(Au(0), radii.top_left.width - border_widths.left);
|
calculate_inner_border_radii(radii, border_widths)
|
||||||
radii.bottom_left.width = cmp::max(Au(0), radii.bottom_left.width - border_widths.left);
|
|
||||||
|
|
||||||
radii.top_right.width = cmp::max(Au(0), radii.top_right.width - border_widths.right);
|
|
||||||
radii.bottom_right.width = cmp::max(Au(0), radii.bottom_right.width - border_widths.right);
|
|
||||||
|
|
||||||
radii.top_left.height = cmp::max(Au(0), radii.top_left.height - border_widths.top);
|
|
||||||
radii.top_right.height = cmp::max(Au(0), radii.top_right.height - border_widths.top);
|
|
||||||
|
|
||||||
radii.bottom_left.height = cmp::max(Au(0), radii.bottom_left.height - border_widths.bottom);
|
|
||||||
radii.bottom_right.height = cmp::max(Au(0), radii.bottom_right.height - border_widths.bottom);
|
|
||||||
radii
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_inner_border_box_for_border_rect(border_box: &Rect<Au>,
|
fn build_inner_border_box_for_border_rect(border_box: &Rect<Au>,
|
||||||
|
@ -1041,6 +1030,24 @@ fn calculate_inner_bounds(mut bounds: Rect<Au>, offsets: SideOffsets2D<Au>) -> R
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calculate_inner_border_radii(
|
||||||
|
mut radii: BorderRadii<Au>,
|
||||||
|
offsets: SideOffsets2D<Au>
|
||||||
|
) -> BorderRadii<Au> {
|
||||||
|
radii.top_left.width = cmp::max(Au(0), radii.top_left.width - offsets.left);
|
||||||
|
radii.bottom_left.width = cmp::max(Au(0), radii.bottom_left.width - offsets.left);
|
||||||
|
|
||||||
|
radii.top_right.width = cmp::max(Au(0), radii.top_right.width - offsets.right);
|
||||||
|
radii.bottom_right.width = cmp::max(Au(0), radii.bottom_right.width - offsets.right);
|
||||||
|
|
||||||
|
radii.top_left.height = cmp::max(Au(0), radii.top_left.height - offsets.top);
|
||||||
|
radii.top_right.height = cmp::max(Au(0), radii.top_right.height - offsets.top);
|
||||||
|
|
||||||
|
radii.bottom_left.height = cmp::max(Au(0), radii.bottom_left.height - offsets.bottom);
|
||||||
|
radii.bottom_right.height = cmp::max(Au(0), radii.bottom_right.height - offsets.bottom);
|
||||||
|
radii
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// For a given area and an image compute how big the
|
/// For a given area and an image compute how big the
|
||||||
/// image should be displayed on the background.
|
/// image should be displayed on the background.
|
||||||
|
@ -1272,20 +1279,23 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let color_clip = get_cyclic(&background.background_clip.0,
|
let color_clip = get_cyclic(&background.background_clip.0,
|
||||||
background.background_image.0.len() - 1);
|
background.background_image.0.len() - 1);
|
||||||
|
|
||||||
|
// Adjust the clipping region as necessary to account for `border-radius`.
|
||||||
|
let mut border_radii = build_border_radius(absolute_bounds, style.get_border());
|
||||||
|
|
||||||
match *color_clip {
|
match *color_clip {
|
||||||
BackgroundClip::BorderBox => {}
|
BackgroundClip::BorderBox => {}
|
||||||
BackgroundClip::PaddingBox => {
|
BackgroundClip::PaddingBox => {
|
||||||
let border = style.logical_border_width().to_physical(style.writing_mode);
|
let border = style.logical_border_width().to_physical(style.writing_mode);
|
||||||
bounds = calculate_inner_bounds(bounds, border);
|
bounds = calculate_inner_bounds(bounds, border);
|
||||||
|
border_radii = calculate_inner_border_radii(border_radii, border);
|
||||||
}
|
}
|
||||||
BackgroundClip::ContentBox => {
|
BackgroundClip::ContentBox => {
|
||||||
let border_padding = self.border_padding.to_physical(style.writing_mode);
|
let border_padding = self.border_padding.to_physical(style.writing_mode);
|
||||||
bounds = calculate_inner_bounds(bounds, border_padding);
|
bounds = calculate_inner_bounds(bounds, border_padding);
|
||||||
|
border_radii = calculate_inner_border_radii(border_radii, border_padding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the clipping region as necessary to account for `border-radius`.
|
|
||||||
let border_radii = build_border_radius(absolute_bounds, style.get_border());
|
|
||||||
let clip = if !border_radii.is_square() {
|
let clip = if !border_radii.is_square() {
|
||||||
LocalClip::RoundedRect(bounds.to_rectf(), ComplexClipRegion::new(
|
LocalClip::RoundedRect(bounds.to_rectf(), ComplexClipRegion::new(
|
||||||
bounds.to_rectf(),
|
bounds.to_rectf(),
|
||||||
|
|
|
@ -96489,6 +96489,18 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/background-clip/clip-rounded-corner.html": [
|
||||||
|
[
|
||||||
|
"/css/css-backgrounds/background-clip/clip-rounded-corner.html",
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/css-backgrounds/background-clip/clip-rounded-corner-ref.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"css/css-backgrounds/background-clip_padding-box.html": [
|
"css/css-backgrounds/background-clip_padding-box.html": [
|
||||||
[
|
[
|
||||||
"/css/css-backgrounds/background-clip_padding-box.html",
|
"/css/css-backgrounds/background-clip_padding-box.html",
|
||||||
|
@ -228178,6 +228190,11 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/background-clip/clip-rounded-corner-ref.html": [
|
||||||
|
[
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"css/css-backgrounds/background-clip/list.txt": [
|
"css/css-backgrounds/background-clip/list.txt": [
|
||||||
[
|
[
|
||||||
{}
|
{}
|
||||||
|
@ -463840,6 +463857,14 @@
|
||||||
"0ab3cfb39cd0348b7e28ed7b1405f0c3490808a7",
|
"0ab3cfb39cd0348b7e28ed7b1405f0c3490808a7",
|
||||||
"visual"
|
"visual"
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/background-clip/clip-rounded-corner-ref.html": [
|
||||||
|
"d58d1e2f9fed2d5331db9aaeaeb50e4b3f26a1e6",
|
||||||
|
"support"
|
||||||
|
],
|
||||||
|
"css/css-backgrounds/background-clip/clip-rounded-corner.html": [
|
||||||
|
"ea68b7be35cb2637bad30119a2d1ee9734dc63ff",
|
||||||
|
"reftest"
|
||||||
|
],
|
||||||
"css/css-backgrounds/background-clip/list.txt": [
|
"css/css-backgrounds/background-clip/list.txt": [
|
||||||
"51b104b69911943bc5469c093046d5c0eb45334a",
|
"51b104b69911943bc5469c093046d5c0eb45334a",
|
||||||
"support"
|
"support"
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Filled Background with Rounded Corner</title>
|
||||||
|
<style>
|
||||||
|
#a {
|
||||||
|
width: 100px;
|
||||||
|
height: 80px;
|
||||||
|
border: 20px blue solid;
|
||||||
|
border-top-right-radius: 20px;
|
||||||
|
background-color: green;
|
||||||
|
background-clip: border-box;
|
||||||
|
}
|
||||||
|
#shield {
|
||||||
|
position: absolute;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
left: 120px;
|
||||||
|
top: 5px;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<div id="a"></div>
|
||||||
|
<!-- Hide the curved outside border to deal with imprecise rendering. -->
|
||||||
|
<div id="shield"></div>
|
||||||
|
</body>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Filled Background with Rounded Corner</title>
|
||||||
|
<link rel="match" href="clip-rounded-corner-ref.html">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#corner-clipping">
|
||||||
|
<style>
|
||||||
|
#b {
|
||||||
|
width: 100px;
|
||||||
|
height: 80px;
|
||||||
|
border: 20px blue solid;
|
||||||
|
border-top-right-radius: 20px;
|
||||||
|
background-color: green;
|
||||||
|
background-clip: content-box;
|
||||||
|
}
|
||||||
|
#shield {
|
||||||
|
position: absolute;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
left: 120px;
|
||||||
|
top: 5px;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<div id="b"></div>
|
||||||
|
<!-- Hide the curved outside border to deal with imprecise rendering. -->
|
||||||
|
<div id="shield"></div>
|
||||||
|
</body>
|
Loading…
Add table
Add a link
Reference in a new issue