From b3b49e3ff0398a5cb3373828baaca9480507f21b Mon Sep 17 00:00:00 2001 From: Pyfisch Date: Fri, 29 Dec 2017 21:27:58 +0100 Subject: [PATCH] Implement correct corner clipping for background color Add one regression ref test. See also #19649 --- components/layout/display_list_builder.rs | 40 ++++++++++++------- tests/wpt/metadata/MANIFEST.json | 25 ++++++++++++ .../clip-rounded-corner-ref.html | 26 ++++++++++++ .../background-clip/clip-rounded-corner.html | 28 +++++++++++++ 4 files changed, 104 insertions(+), 15 deletions(-) create mode 100644 tests/wpt/web-platform-tests/css/css-backgrounds/background-clip/clip-rounded-corner-ref.html create mode 100644 tests/wpt/web-platform-tests/css/css-backgrounds/background-clip/clip-rounded-corner.html diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 09f4485313e..370ebcdf22f 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -681,7 +681,7 @@ fn build_border_radius(abs_bounds: &Rect, fn build_border_radius_for_inner_rect(outer_rect: &Rect, style: &ComputedValues) -> BorderRadii { - 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() { return radii; } @@ -690,18 +690,7 @@ fn build_border_radius_for_inner_rect(outer_rect: &Rect, // border width), we need to adjust to border radius so that we are smaller // rectangle with the same border curve. 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); - 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 + calculate_inner_border_radii(radii, border_widths) } fn build_inner_border_box_for_border_rect(border_box: &Rect, @@ -1041,6 +1030,24 @@ fn calculate_inner_bounds(mut bounds: Rect, offsets: SideOffsets2D) -> R bounds } +fn calculate_inner_border_radii( + mut radii: BorderRadii, + offsets: SideOffsets2D +) -> BorderRadii { + 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 /// image should be displayed on the background. @@ -1272,20 +1279,23 @@ impl FragmentDisplayListBuilding for Fragment { let color_clip = get_cyclic(&background.background_clip.0, 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 { BackgroundClip::BorderBox => {} BackgroundClip::PaddingBox => { let border = style.logical_border_width().to_physical(style.writing_mode); bounds = calculate_inner_bounds(bounds, border); + border_radii = calculate_inner_border_radii(border_radii, border); } BackgroundClip::ContentBox => { let border_padding = self.border_padding.to_physical(style.writing_mode); 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() { LocalClip::RoundedRect(bounds.to_rectf(), ComplexClipRegion::new( bounds.to_rectf(), diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index d2c58a59a96..a1f61f548ea 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -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", @@ -228178,6 +228190,11 @@ {} ] ], + "css/css-backgrounds/background-clip/clip-rounded-corner-ref.html": [ + [ + {} + ] + ], "css/css-backgrounds/background-clip/list.txt": [ [ {} @@ -463840,6 +463857,14 @@ "0ab3cfb39cd0348b7e28ed7b1405f0c3490808a7", "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": [ "51b104b69911943bc5469c093046d5c0eb45334a", "support" diff --git a/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip/clip-rounded-corner-ref.html b/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip/clip-rounded-corner-ref.html new file mode 100644 index 00000000000..379ad36992a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip/clip-rounded-corner-ref.html @@ -0,0 +1,26 @@ + + +Filled Background with Rounded Corner + + +
+ +
+ diff --git a/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip/clip-rounded-corner.html b/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip/clip-rounded-corner.html new file mode 100644 index 00000000000..3453c5bc8f5 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-backgrounds/background-clip/clip-rounded-corner.html @@ -0,0 +1,28 @@ + + +Filled Background with Rounded Corner + + + + +
+ +
+