Commit 0eb24038 authored by Chris Harrelson's avatar Chris Harrelson Committed by Commit Bot

Differentiate pixel-snapped vs non-snapped inner-border=radius clips

This is a follow-on to [1]. In addition to the added unittest,
this fixes a failure in a test [2] when trying to land [3].

[1] https://chromium-review.googlesource.com/c/chromium/src/+/2092698
[2] http/tests/lazyload/image-subpixel-position.html
[3] https://chromium-review.googlesource.com/c/chromium/src/+/2103708

Bug: 992765

Change-Id: I32b28ff0ab4cd4f9f527c6601413a16d2a1d703c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2106418Reviewed-by: default avatarStefan Zager <szager@chromium.org>
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751067}
parent 30a9f9dd
...@@ -1543,10 +1543,12 @@ void FragmentPaintPropertyTreeBuilder::UpdateInnerBorderRadiusClip() { ...@@ -1543,10 +1543,12 @@ void FragmentPaintPropertyTreeBuilder::UpdateInnerBorderRadiusClip() {
if (NeedsPaintPropertyUpdate()) { if (NeedsPaintPropertyUpdate()) {
if (NeedsInnerBorderRadiusClip(object_)) { if (NeedsInnerBorderRadiusClip(object_)) {
const LayoutBox& box = ToLayoutBox(object_); const LayoutBox& box = ToLayoutBox(object_);
LayoutRect box_rect(context_.current.paint_offset.ToLayoutPoint(),
box.Size());
ClipPaintPropertyNode::State state( ClipPaintPropertyNode::State state(
context_.current.transform, context_.current.transform,
box.StyleRef().GetRoundedInnerBorderFor(LayoutRect( box.StyleRef().GetInnerBorderFor(box_rect),
context_.current.paint_offset.ToLayoutPoint(), box.Size()))); box.StyleRef().GetRoundedInnerBorderFor(box_rect));
OnUpdateClip(properties_->UpdateInnerBorderRadiusClip( OnUpdateClip(properties_->UpdateInnerBorderRadiusClip(
*context_.current.clip, std::move(state))); *context_.current.clip, std::move(state)));
} else { } else {
......
...@@ -1718,6 +1718,38 @@ TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) { ...@@ -1718,6 +1718,38 @@ TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) {
GetDocument().View()->GetLayoutView()); GetDocument().View()->GetLayoutView());
} }
TEST_P(PaintPropertyTreeBuilderTest, SubpixelBorderRadiusClip) {
SetBodyInnerHTML(R"HTML(
<style>
body {
margin: 0px;
}
#div {
margin-top: 0.5px;
width: 100px;
height: 100px;
overflow: hidden;
border-radius: 50%;
}
</style>
<div id='div'></div>
)HTML");
LayoutObject& div = *GetLayoutObjectByElementId("div");
const ObjectPaintProperties* div_properties =
div.FirstFragment().PaintProperties();
const ClipPaintPropertyNode* border_radius_clip =
div_properties->InnerBorderRadiusClip();
FloatSize corner(50, 50);
EXPECT_EQ(FloatRoundedRect(FloatRect(0, 0.5, 100, 100), corner, corner,
corner, corner),
border_radius_clip->UnsnappedClipRect());
EXPECT_EQ(FloatRoundedRect(FloatRect(0, 1, 100, 100), corner, corner, corner,
corner),
border_radius_clip->PixelSnappedClipRect());
}
TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) { TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) {
SetBodyInnerHTML(R"HTML( SetBodyInnerHTML(R"HTML(
<style> <style>
......
...@@ -1367,6 +1367,20 @@ static FloatRoundedRect::Radii CalcRadiiFor(const LengthSize& top_left, ...@@ -1367,6 +1367,20 @@ static FloatRoundedRect::Radii CalcRadiiFor(const LengthSize& top_left,
FloatSizeForLengthSize(bottom_right, size)); FloatSizeForLengthSize(bottom_right, size));
} }
FloatRoundedRect ComputedStyle::GetBorderFor(
const LayoutRect& border_rect) const {
FloatRoundedRect rounded_rect((FloatRect(border_rect)));
if (HasBorderRadius()) {
FloatRoundedRect::Radii radii = CalcRadiiFor(
BorderTopLeftRadius(), BorderTopRightRadius(), BorderBottomLeftRadius(),
BorderBottomRightRadius(), FloatSize(border_rect.Size()));
rounded_rect.IncludeLogicalEdges(radii, IsHorizontalWritingMode(), true,
true);
rounded_rect.ConstrainRadii();
}
return rounded_rect;
}
FloatRoundedRect ComputedStyle::GetRoundedBorderFor( FloatRoundedRect ComputedStyle::GetRoundedBorderFor(
const LayoutRect& border_rect, const LayoutRect& border_rect,
bool include_logical_left_edge, bool include_logical_left_edge,
...@@ -1384,6 +1398,36 @@ FloatRoundedRect ComputedStyle::GetRoundedBorderFor( ...@@ -1384,6 +1398,36 @@ FloatRoundedRect ComputedStyle::GetRoundedBorderFor(
return rounded_rect; return rounded_rect;
} }
FloatRoundedRect ComputedStyle::GetInnerBorderFor(
const LayoutRect& border_rect) const {
int left_width = BorderLeftWidth();
int right_width = BorderRightWidth();
int top_width = BorderTopWidth();
int bottom_width = BorderBottomWidth();
LayoutRectOutsets insets(-top_width, -right_width, -bottom_width,
-left_width);
LayoutRect inner_rect(border_rect);
inner_rect.Expand(insets);
LayoutSize inner_rect_size = inner_rect.Size();
inner_rect_size.ClampNegativeToZero();
inner_rect.SetSize(inner_rect_size);
FloatRoundedRect float_inner_rect((FloatRect(inner_rect)));
if (HasBorderRadius()) {
FloatRoundedRect::Radii radii = GetBorderFor(border_rect).GetRadii();
// Insets use negative values.
radii.Shrink(-insets.Top().ToFloat(), -insets.Bottom().ToFloat(),
-insets.Left().ToFloat(), -insets.Right().ToFloat());
float_inner_rect.IncludeLogicalEdges(radii, IsHorizontalWritingMode(), true,
true);
}
return float_inner_rect;
}
FloatRoundedRect ComputedStyle::GetRoundedInnerBorderFor( FloatRoundedRect ComputedStyle::GetRoundedInnerBorderFor(
const LayoutRect& border_rect, const LayoutRect& border_rect,
bool include_logical_left_edge, bool include_logical_left_edge,
......
...@@ -1944,10 +1944,15 @@ class ComputedStyle : public ComputedStyleBase, ...@@ -1944,10 +1944,15 @@ class ComputedStyle : public ComputedStyleBase,
LengthSize(Length::Fixed(s.Width()), Length::Fixed(s.Height()))); LengthSize(Length::Fixed(s.Width()), Length::Fixed(s.Height())));
} }
FloatRoundedRect GetBorderFor(const LayoutRect& border_rect) const;
FloatRoundedRect GetRoundedBorderFor( FloatRoundedRect GetRoundedBorderFor(
const LayoutRect& border_rect, const LayoutRect& border_rect,
bool include_logical_left_edge = true, bool include_logical_left_edge = true,
bool include_logical_right_edge = true) const; bool include_logical_right_edge = true) const;
FloatRoundedRect GetInnerBorderFor(const LayoutRect& border_rect) const;
FloatRoundedRect GetRoundedInnerBorderFor( FloatRoundedRect GetRoundedInnerBorderFor(
const LayoutRect& border_rect, const LayoutRect& border_rect,
bool include_logical_left_edge = true, bool include_logical_left_edge = true,
......
...@@ -51,8 +51,6 @@ class PLATFORM_EXPORT ClipPaintPropertyNode ...@@ -51,8 +51,6 @@ class PLATFORM_EXPORT ClipPaintPropertyNode
void SetClipRect(const FloatRoundedRect& clip_rect_arg, void SetClipRect(const FloatRoundedRect& clip_rect_arg,
const FloatRoundedRect& pixel_snapped_clip_rect_arg) { const FloatRoundedRect& pixel_snapped_clip_rect_arg) {
DCHECK(clip_rect_arg.GetRadii() ==
pixel_snapped_clip_rect_arg.GetRadii());
clip_rect = clip_rect_arg; clip_rect = clip_rect_arg;
pixel_snapped_clip_rect = pixel_snapped_clip_rect_arg; pixel_snapped_clip_rect = pixel_snapped_clip_rect_arg;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment