Title: [142638] trunk
Revision
142638
Author
[email protected]
Date
2013-02-12 09:40:28 -0800 (Tue, 12 Feb 2013)

Log Message

TransformState::move should not round offset to int
https://bugs.webkit.org/show_bug.cgi?id=108266

Source/WebCore:

Reviewed by Simon Fraser.

Currently TransformState::move rounds the offset to the nearest
integer values, this results in operations using TransformState
to compute a position to misreport the location, specifically
Element:getBoundingClientRect and repaint rects. Sizes are
handled correctly and do not have the same problem.

Tests: fast/sub-pixel/boundingclientrect-subpixel-margin.html
       fast/sub-pixel/clip-rect-box-consistent-rounding.html

* page/FrameView.cpp:
(WebCore::FrameView::convertFromRenderer):
Change to use pixel snapping instead of enclosing box. All other
code paths use pixelSnappedIntRect to align the rects to device
pixels however this used enclosingIntRect (indirectly through
the FloatQuad::enclosingBoundingBox call).
Without the rounding in TransformState this causes repaint rects
for elements on subpixel bounds to be too large by up to one
pixel on each axis. For normal repaints this isn't really a
problem but in scrollContentsSlowPath it can result in moving
too large a rect.

* platform/graphics/transforms/TransformState.cpp:
(WebCore::TransformState::translateTransform):
(WebCore::TransformState::translateMappedCoordinates):
Change to take a LayoutSize instead of an IntSize.

(WebCore::TransformState::move):
(WebCore::TransformState::applyAccumulatedOffset):
* platform/graphics/transforms/TransformState.h:
Remove rounding logic and use original, more precise, value.

* rendering/RenderGeometryMap.cpp:
(WebCore::RenderGeometryMap::mapToContainer):
Remove rounding logic and use original, more precise, value.

LayoutTests:

Reviewed by Simon Fraser.

Add new tests for Element::boundingClientRect and clip rects for
elements on subpixel boundaries.

* fast/dom/Window/webkitConvertPoint.html:
* platform/chromium-linux/fast/dom/Window/webkitConvertPoint-expected.txt:
Update test and expectations to take new rounding into account.

* fast/sub-pixel/boundingclientrect-subpixel-margin-expected.txt: Added.
* fast/sub-pixel/boundingclientrect-subpixel-margin.html: Added.
Add test ensuring that boundingClientRect returns accurate and
precise (as opposed to rounded) metrics.

* fast/sub-pixel/clip-rect-box-consistent-rounding-expected.html: Added.
* fast/sub-pixel/clip-rect-box-consistent-rounding.html: Added.
Add test ensuring that clip rects and elements use consistent rounding.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (142637 => 142638)


--- trunk/LayoutTests/ChangeLog	2013-02-12 17:37:39 UTC (rev 142637)
+++ trunk/LayoutTests/ChangeLog	2013-02-12 17:40:28 UTC (rev 142638)
@@ -1,3 +1,27 @@
+2013-02-12  Emil A Eklund  <[email protected]>
+
+        TransformState::move should not round offset to int
+        https://bugs.webkit.org/show_bug.cgi?id=108266
+
+        Reviewed by Simon Fraser.
+        
+        Add new tests for Element::boundingClientRect and clip rects for
+        elements on subpixel boundaries.
+
+        * fast/dom/Window/webkitConvertPoint.html:
+        * platform/chromium-linux/fast/dom/Window/webkitConvertPoint-expected.txt:
+        Update test and expectations to take new rounding into account.
+        
+        * fast/sub-pixel/boundingclientrect-subpixel-margin-expected.txt: Added.
+        * fast/sub-pixel/boundingclientrect-subpixel-margin.html: Added.
+        Add test ensuring that boundingClientRect returns accurate and
+        precise (as opposed to rounded) metrics.
+        
+        * fast/sub-pixel/clip-rect-box-consistent-rounding-expected.html: Added.
+        * fast/sub-pixel/clip-rect-box-consistent-rounding.html: Added.
+        Add test ensuring that clip rects and elements use consistent rounding.
+
+
 2013-02-12  Rafael Weinstein  <[email protected]>
 
         [HTMLTemplateElement] <template> inside of <head> may not create <body> if EOF is hit

Modified: trunk/LayoutTests/fast/dom/Window/webkitConvertPoint.html (142637 => 142638)


--- trunk/LayoutTests/fast/dom/Window/webkitConvertPoint.html	2013-02-12 17:37:39 UTC (rev 142637)
+++ trunk/LayoutTests/fast/dom/Window/webkitConvertPoint.html	2013-02-12 17:40:28 UTC (rev 142638)
@@ -145,8 +145,8 @@
                 runTest("Test 8",  "test8",  8, 273, 13, 313);
                 runTest("Test 9",  "test9",  28, 291, 33, 331);
                 runTest("Test 10", "test10", 28, 309, 33, 349);
-                runTest("Test 11", "test11", 158, 356, 174, 374);
-                runTest("Test 12", "test12", 168, 429, 184, 447);
+                runTest("Test 11", "test11", 158, 376, 174, 394);
+                runTest("Test 12", "test12", 168, 451, 184, 469);
                 runTest("Test 13", "test13", 28, 487, 33, 527);
             } else {
                 runTest("Test 1",  "test1",  8, 12, 13, 52);

Added: trunk/LayoutTests/fast/sub-pixel/boundingclientrect-subpixel-margin-expected.txt (0 => 142638)


--- trunk/LayoutTests/fast/sub-pixel/boundingclientrect-subpixel-margin-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/sub-pixel/boundingclientrect-subpixel-margin-expected.txt	2013-02-12 17:40:28 UTC (rev 142638)
@@ -0,0 +1,3 @@
+PASS testRect.left - parentRect.left is 1.5
+PASS parentRect.right - testRect.right is 1.5
+

Added: trunk/LayoutTests/fast/sub-pixel/boundingclientrect-subpixel-margin.html (0 => 142638)


--- trunk/LayoutTests/fast/sub-pixel/boundingclientrect-subpixel-margin.html	                        (rev 0)
+++ trunk/LayoutTests/fast/sub-pixel/boundingclientrect-subpixel-margin.html	2013-02-12 17:40:28 UTC (rev 142638)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script src=""
+    </head>
+    <body style="margin: 0; padding: 0;">
+        <div style="margin: 0; width: 700px; margin: 10px; background: black; overflow: hidden;">
+            <div id="test" style="width: 697px; height: 200px; background-color: red; margin: 0 auto"></div>
+        </div>
+        <script>
+            var testEl = document.getElementById('test');
+            var testRect = testEl.getBoundingClientRect();
+            var parentRect = testEl.parentElement.getBoundingClientRect();
+
+            var expectedMarginWidth = String((parentRect.width - testRect.width) / 2);
+            shouldBe('testRect.left - parentRect.left', expectedMarginWidth);
+            shouldBe('parentRect.right - testRect.right', expectedMarginWidth);
+        </script>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/sub-pixel/clip-rect-box-consistent-rounding-expected.html (0 => 142638)


--- trunk/LayoutTests/fast/sub-pixel/clip-rect-box-consistent-rounding-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/sub-pixel/clip-rect-box-consistent-rounding-expected.html	2013-02-12 17:40:28 UTC (rev 142638)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<style type="text/css">
+			body {
+				margin: 10px;
+			}
+			.main {
+				margin: 0 auto;
+				width: 625px;
+				height: 125px;
+				background: black;
+				position: relative;
+			}
+			.site {
+				top: 5px;
+				left: 5px;
+				width: 232px;
+				height: 115px;
+				position: absolute;
+				overflow: hidden;
+			}
+			.desaturated {
+				position: absolute;
+				width: 250px;
+				height: 125px;
+				background: white;
+			}
+			.infobox {
+				position: absolute;
+				top: 0;
+				left: 0;
+				width: 232px;
+				height: 63px;
+				background: red;
+			}
+		</style>
+	</head>
+
+	<body>
+		<div class="main">
+			<div class="site">
+				<div class="desaturated"></div>
+				<div class="infobox"></div>
+			</div>
+		</div>
+	</body>
+</html>

Added: trunk/LayoutTests/fast/sub-pixel/clip-rect-box-consistent-rounding.html (0 => 142638)


--- trunk/LayoutTests/fast/sub-pixel/clip-rect-box-consistent-rounding.html	                        (rev 0)
+++ trunk/LayoutTests/fast/sub-pixel/clip-rect-box-consistent-rounding.html	2013-02-12 17:40:28 UTC (rev 142638)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<style type="text/css">
+			body {
+				margin: 8px;
+				zoom: 1.25;
+			}
+			.main {
+				margin: 0 auto;
+				width: 500px;
+				height: 100px;
+				background: black;
+				position: relative;
+			}
+			.site {
+				top: 4px;
+				left: 4px;
+				width: 186px;
+				height: 92px;
+				position: absolute;
+				overflow: hidden;
+			}
+			.desaturated {
+				position: absolute;
+				width: 200px;
+				height: 100px;
+				background: white;
+			}
+			.infobox {
+				position: absolute;
+				top: 0;
+				left: 0;
+				width: 186px;
+				height: 50px;
+				background: red;
+			}
+		</style>
+	</head>
+
+	<body>
+		<div class="main">
+			<div class="site">
+				<div class="desaturated"></div>
+				<div class="infobox"></div>
+			</div>
+		</div>
+	</body>
+</html>

Modified: trunk/LayoutTests/platform/chromium/TestExpectations (142637 => 142638)


--- trunk/LayoutTests/platform/chromium/TestExpectations	2013-02-12 17:37:39 UTC (rev 142637)
+++ trunk/LayoutTests/platform/chromium/TestExpectations	2013-02-12 17:40:28 UTC (rev 142638)
@@ -954,6 +954,11 @@
 webkit.org/b/109272 platform/chromium/fast/forms/suggestion-picker/datetime-suggestion-picker-appearance.html [ Skip ]
 webkit.org/b/109272 platform/chromium/fast/forms/suggestion-picker/datetime-suggestion-picker-mouse-operations.html [ Skip ]
 
+# Skip until 109528 is fixed.
+webkit.org/b/109528 platform/chromium/fast/forms/suggestion-picker/date-suggestion-picker-appearance-with-scroll-bar.html [ Skip ]
+webkit.org/b/109528 platform/chromium/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar.html [ Skip ]
+webkit.org/b/109528 platform/chromium/fast/forms/suggestion-picker/week-suggestion-picker-appearance-with-scroll-bar.html [ Skip ]
+
 # Skipping rules for ANDROID are in platform/chromium-android/TestExpectations.
 
 # -----------------------------------------------------------------

Modified: trunk/LayoutTests/platform/chromium-linux/fast/dom/Window/webkitConvertPoint-expected.txt (142637 => 142638)


--- trunk/LayoutTests/platform/chromium-linux/fast/dom/Window/webkitConvertPoint-expected.txt	2013-02-12 17:37:39 UTC (rev 142637)
+++ trunk/LayoutTests/platform/chromium-linux/fast/dom/Window/webkitConvertPoint-expected.txt	2013-02-12 17:40:28 UTC (rev 142638)
@@ -158,24 +158,24 @@
 
 Test 11
 PASS x is 158
-FAIL y should be 356. Was 377.
+PASS y is 376
 Round Trip of (0,0)
 PASS x is 0
 PASS y is 0
 PASS x is 174
-FAIL y should be 374. Was 395.
+PASS y is 394
 Round Trip of (5,40)
 PASS x is 5
 PASS y is 40
 
 Test 12
 PASS x is 168
-FAIL y should be 429. Was 452.
+PASS y is 451
 Round Trip of (0,0)
 PASS x is 0
 PASS y is 0
 PASS x is 184
-FAIL y should be 447. Was 470.
+PASS y is 469
 Round Trip of (5,40)
 PASS x is 5
 PASS y is 40

Modified: trunk/Source/WebCore/ChangeLog (142637 => 142638)


--- trunk/Source/WebCore/ChangeLog	2013-02-12 17:37:39 UTC (rev 142637)
+++ trunk/Source/WebCore/ChangeLog	2013-02-12 17:40:28 UTC (rev 142638)
@@ -1,3 +1,45 @@
+2013-02-12  Emil A Eklund  <[email protected]>
+
+        TransformState::move should not round offset to int
+        https://bugs.webkit.org/show_bug.cgi?id=108266
+
+        Reviewed by Simon Fraser.
+        
+        Currently TransformState::move rounds the offset to the nearest
+        integer values, this results in operations using TransformState
+        to compute a position to misreport the location, specifically
+        Element:getBoundingClientRect and repaint rects. Sizes are
+        handled correctly and do not have the same problem.
+
+        Tests: fast/sub-pixel/boundingclientrect-subpixel-margin.html
+               fast/sub-pixel/clip-rect-box-consistent-rounding.html
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::convertFromRenderer):
+        Change to use pixel snapping instead of enclosing box. All other
+        code paths use pixelSnappedIntRect to align the rects to device
+        pixels however this used enclosingIntRect (indirectly through
+        the FloatQuad::enclosingBoundingBox call).
+        Without the rounding in TransformState this causes repaint rects
+        for elements on subpixel bounds to be too large by up to one
+        pixel on each axis. For normal repaints this isn't really a
+        problem but in scrollContentsSlowPath it can result in moving
+        too large a rect.
+
+        * platform/graphics/transforms/TransformState.cpp:
+        (WebCore::TransformState::translateTransform):
+        (WebCore::TransformState::translateMappedCoordinates):
+        Change to take a LayoutSize instead of an IntSize.
+
+        (WebCore::TransformState::move):
+        (WebCore::TransformState::applyAccumulatedOffset):
+        * platform/graphics/transforms/TransformState.h:
+        Remove rounding logic and use original, more precise, value.
+
+        * rendering/RenderGeometryMap.cpp:
+        (WebCore::RenderGeometryMap::mapToContainer):
+        Remove rounding logic and use original, more precise, value.
+
 2013-02-12  Jessie Berlin  <[email protected]>
 
         Rollout r142618, it broke all the Mac builds.

Modified: trunk/Source/WebCore/page/FrameView.cpp (142637 => 142638)


--- trunk/Source/WebCore/page/FrameView.cpp	2013-02-12 17:37:39 UTC (rev 142637)
+++ trunk/Source/WebCore/page/FrameView.cpp	2013-02-12 17:40:28 UTC (rev 142638)
@@ -3587,7 +3587,7 @@
 
 IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
 {
-    IntRect rect = renderer->localToAbsoluteQuad(FloatRect(rendererRect)).enclosingBoundingBox();
+    IntRect rect = pixelSnappedIntRect(enclosingLayoutRect(renderer->localToAbsoluteQuad(FloatRect(rendererRect)).boundingBox()));
 
     // Convert from page ("absolute") to FrameView coordinates.
     if (!delegatesScrolling())

Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformState.cpp (142637 => 142638)


--- trunk/Source/WebCore/platform/graphics/transforms/TransformState.cpp	2013-02-12 17:37:39 UTC (rev 142637)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformState.cpp	2013-02-12 17:40:28 UTC (rev 142638)
@@ -50,7 +50,7 @@
     return *this;
 }
 
-void TransformState::translateTransform(const IntSize& offset)
+void TransformState::translateTransform(const LayoutSize& offset)
 {
     if (m_direction == ApplyTransformDirection)
         m_accumulatedTransform->translateRight(offset.width(), offset.height());
@@ -58,9 +58,9 @@
         m_accumulatedTransform->translate(offset.width(), offset.height());
 }
 
-void TransformState::translateMappedCoordinates(const IntSize& offset)
+void TransformState::translateMappedCoordinates(const LayoutSize& offset)
 {
-    IntSize adjustedOffset = (m_direction == ApplyTransformDirection) ? offset : -offset;
+    LayoutSize adjustedOffset = (m_direction == ApplyTransformDirection) ? offset : -offset;
     if (m_mapPoint)
         m_lastPlanarPoint.move(adjustedOffset);
     if (m_mapQuad)
@@ -75,21 +75,21 @@
         applyAccumulatedOffset();
         if (m_accumulatingTransform && m_accumulatedTransform) {
             // If we're accumulating into an existing transform, apply the translation.
-            translateTransform(roundedIntSize(offset));
+            translateTransform(offset);
 
             // Then flatten if necessary.
             if (accumulate == FlattenTransform)
                 flatten();
         } else
             // Just move the point and/or quad.
-            translateMappedCoordinates(roundedIntSize(offset));
+            translateMappedCoordinates(offset);
     }
     m_accumulatingTransform = accumulate == AccumulateTransform;
 }
 
 void TransformState::applyAccumulatedOffset()
 {
-    IntSize offset = roundedIntSize(m_accumulatedOffset);
+    LayoutSize offset = m_accumulatedOffset;
     m_accumulatedOffset = LayoutSize();
     if (!offset.isZero()) {
         if (m_accumulatedTransform) {

Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformState.h (142637 => 142638)


--- trunk/Source/WebCore/platform/graphics/transforms/TransformState.h	2013-02-12 17:37:39 UTC (rev 142637)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformState.h	2013-02-12 17:40:28 UTC (rev 142638)
@@ -101,8 +101,8 @@
     FloatQuad mappedQuad(bool* wasClamped = 0) const;
 
 private:
-    void translateTransform(const IntSize&);
-    void translateMappedCoordinates(const IntSize&);
+    void translateTransform(const LayoutSize&);
+    void translateMappedCoordinates(const LayoutSize&);
     void flattenWithTransform(const TransformationMatrix&, bool* wasClamped);
     void applyAccumulatedOffset();
     

Modified: trunk/Source/WebCore/rendering/RenderGeometryMap.cpp (142637 => 142638)


--- trunk/Source/WebCore/rendering/RenderGeometryMap.cpp	2013-02-12 17:37:39 UTC (rev 142637)
+++ trunk/Source/WebCore/rendering/RenderGeometryMap.cpp	2013-02-12 17:40:28 UTC (rev 142638)
@@ -128,7 +128,7 @@
     
     if (!hasFixedPositionStep() && !hasTransformStep() && !hasNonUniformStep() && (!container || (m_mapping.size() && container == m_mapping[0].m_renderer))) {
         result = rect;
-        result.move(roundedIntSize(m_accumulatedOffset));
+        result.move(m_accumulatedOffset);
     } else {
         TransformState transformState(TransformState::ApplyTransformDirection, rect.center(), rect);
         mapToContainer(transformState, container);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to