Commit a7b04f8f authored by Stefan Zager's avatar Stefan Zager Committed by Commit Bot

Fix rounding of very large and very small LayoutUnits.

Previously, LayoutUnit's between NearlyMax() and Max() would round
down, even though their fractional parts are > 0.5.  Similarly,
LayoutUnit's between Min() and NearlyMin() would round up (toward
zero), even though their fractional parts are < -0.5.

Change-Id: I824db066f6f45b58512a30ed32c1d280604bfefe
Reviewed-on: https://chromium-review.googlesource.com/592854Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Stefan Zager <szager@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491071}
parent b300a0cc
<!DOCTYPE html> <!DOCTYPE html>
<style> #float { float:left; height: 33554431px; width: 83866px; }</style> <style> #float { float:left; height: 33554432px; width: 83866px; }</style>
<script src="../../../resources/check-layout.js"></script> <script src="../../../resources/check-layout.js"></script>
<body onload="checkLayout('#table')"> <body onload="checkLayout('#table')">
Elements should avoid floats even if they are as high as LayoutUnit::max() Elements should avoid floats even if they are as high as LayoutUnit::max()
<div id="float"> </div> <div id="float"> </div>
<table data-offset-y=33554431 id="table"> <table data-offset-y=33554432 id="table">
<td>a</td> <td>a</td>
</table> </table>
</body> </body>
PASS successfullyParsed is true PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
PASS imgWidth is 33554431 PASS imgWidth is 33554432
This test passes if the image is displayed with infinite dimensions. This test passes if the image is displayed with infinite dimensions.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
var imgWidth; var imgWidth;
addEventListener("load", function() { addEventListener("load", function() {
imgWidth = document.getElementById("foo").clientWidth; imgWidth = document.getElementById("foo").clientWidth;
var expected = 33554431; // blink::intMaxForLayoutUnit var expected = 33554432; // blink::intMaxForLayoutUnit
if (sessionStorage.useZoomForDsfEnabled === 'true') if (sessionStorage.useZoomForDsfEnabled === 'true')
expected = Math.round(expected / window.devicePixelRatio); expected = Math.round(expected / window.devicePixelRatio);
shouldBe('imgWidth', '' + expected); shouldBe('imgWidth', '' + expected);
......
...@@ -154,8 +154,8 @@ class LayoutUnit { ...@@ -154,8 +154,8 @@ class LayoutUnit {
return ToInt(); return ToInt();
} }
ALWAYS_INLINE int Round() const { ALWAYS_INLINE int Round() const {
return ClampAdd(RawValue(), kFixedPointDenominator / 2) >> return ToInt() + ((Fraction().RawValue() + (kFixedPointDenominator / 2)) >>
kLayoutUnitFractionalBits; kLayoutUnitFractionalBits);
} }
int Floor() const { int Floor() const {
......
...@@ -100,6 +100,15 @@ TEST(LayoutUnitTest, LayoutUnitRounding) { ...@@ -100,6 +100,15 @@ TEST(LayoutUnitTest, LayoutUnitRounding) {
EXPECT_EQ(1, LayoutUnit::FromFloatRound(1.49f).Round()); EXPECT_EQ(1, LayoutUnit::FromFloatRound(1.49f).Round());
EXPECT_EQ(2, LayoutUnit::FromFloatRound(1.5f).Round()); EXPECT_EQ(2, LayoutUnit::FromFloatRound(1.5f).Round());
EXPECT_EQ(2, LayoutUnit::FromFloatRound(1.51f).Round()); EXPECT_EQ(2, LayoutUnit::FromFloatRound(1.51f).Round());
// The fractional part of LayoutUnit::Max() is 0x3f, so it should round up.
EXPECT_EQ(((std::numeric_limits<int>::max() / kFixedPointDenominator) + 1),
LayoutUnit::Max().Round());
// The fractional part of LayoutUnit::Min() is 0, so the next bigger possible
// value should round down.
LayoutUnit epsilon;
epsilon.SetRawValue(1);
EXPECT_EQ(((std::numeric_limits<int>::min() / kFixedPointDenominator)),
(LayoutUnit::Min() + epsilon).Round());
} }
TEST(LayoutUnitTest, LayoutUnitSnapSizeToPixel) { TEST(LayoutUnitTest, LayoutUnitSnapSizeToPixel) {
......
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