Commit a2aaa284 authored by Stephen Chenney's avatar Stephen Chenney Committed by Commit Bot

Never let a non-zero-size pixel snap to zero size

The logic for LayoutUnit::SnapSizeToPixel maps the size to
the closest pixel align edge given a location. When a size of
width less than 1 happens to straddle a pixel aligned edge this
forces the size to zero.

Force the size to always be non-zero if the input size is non-zero,
and change PhysicalRect to use the LayoutRect snapping to get
correct cull rects.

Bug: 793785
Change-Id: Ia4c30d10c389fb4677006441aac9ee380a7c2f41
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1948057
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726516}
parent 5e0ff7a0
...@@ -723,7 +723,12 @@ inline float& operator/=(float& a, const LayoutUnit& b) { ...@@ -723,7 +723,12 @@ inline float& operator/=(float& a, const LayoutUnit& b) {
inline int SnapSizeToPixel(LayoutUnit size, LayoutUnit location) { inline int SnapSizeToPixel(LayoutUnit size, LayoutUnit location) {
LayoutUnit fraction = location.Fraction(); LayoutUnit fraction = location.Fraction();
return (fraction + size).Round() - fraction.Round(); int result = (fraction + size).Round() - fraction.Round();
if (UNLIKELY(result == 0 &&
std::abs(size.ToFloat()) > LayoutUnit::Epsilon() * 4)) {
return size > 0 ? 1 : -1;
}
return result;
} }
inline int RoundToInt(LayoutUnit value) { inline int RoundToInt(LayoutUnit value) {
......
...@@ -155,8 +155,20 @@ TEST(LayoutUnitTest, LayoutUnitSnapSizeToPixel) { ...@@ -155,8 +155,20 @@ TEST(LayoutUnitTest, LayoutUnitSnapSizeToPixel) {
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(0.99))); EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(0.99)));
EXPECT_EQ(2, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1))); EXPECT_EQ(2, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1)));
EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(0.5), LayoutUnit(1.5))); // 0.046875 is 3/64, lower than 4 * LayoutUnit::Epsilon()
EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(0.99), LayoutUnit(1.5))); EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(0.046875), LayoutUnit(0)));
// 0.078125 is 5/64, higher than 4 * LayoutUnit::Epsilon()
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(0.078125), LayoutUnit(0)));
// Negative versions
EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(-0.046875), LayoutUnit(0)));
EXPECT_EQ(-1, SnapSizeToPixel(LayoutUnit(-0.078125), LayoutUnit(0)));
// The next 2 would snap to zero but for the requirement that we not snap
// sizes greater than 4 * LayoutUnit::Epsilon() to 0.
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(0.5), LayoutUnit(1.5)));
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(0.99), LayoutUnit(1.5)));
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.0), LayoutUnit(1.5))); EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.0), LayoutUnit(1.5)));
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.49), LayoutUnit(1.5))); EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.49), LayoutUnit(1.5)));
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1.5))); EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1.5)));
......
<!DOCTYPE html>
<title>Reference: Thin elements should paint even at small size</title>
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<html>
<head>
<style>
.disappearing-border {
height:1px;
width:100%;
border-top:1px solid black;
}
.disappearing-box {
height:1px;
width:100%;
background-color: black;
}
body {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="disappearing-border"></div>
<div style="height:6.5px;"></div>
<div class="disappearing-box"></div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<title>Thin elements should still paint even at small size.</title>
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#width-height-keywords">
<link rel="match" href="thin-element-render-ref.html">
<html>
<head>
<style>
.disappearing-border {
height:0.25px;
width:100%;
border-top: 0.25px solid black;
}
.disappearing-box {
height:0.25px;
width:100%;
background-color: black;
}
body {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="disappearing-border"></div>
<div style="height:8px;"></div>
<div class="disappearing-box"></div>
</body>
</html>
\ No newline at end of file
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