<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[165127] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/165127">165127</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2014-03-05 13:56:51 -0800 (Wed, 05 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Subpixel rendering: Device pixel round accumulated subpixel value when the RenderLayer with transform paints its content.
https://bugs.webkit.org/show_bug.cgi?id=129079

Reviewed by Simon Fraser.

Snap the content to the device pixel position (as opposed to integral position) before
applying the transform. Recalculate the remaining subpixels that need offsetting at painting time.

Source/WebCore:

Test: compositing/hidpi-absolute-subpixel-positioned-transformed-elements.html

* platform/graphics/LayoutPoint.h:
(WebCore::roundedForPainting):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayerByApplyingTransform):

LayoutTests:

* compositing/hidpi-absolute-subpixel-positioned-transformed-elements-expected.html: Added.
* compositing/hidpi-absolute-subpixel-positioned-transformed-elements.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsLayoutPointh">trunk/Source/WebCore/platform/graphics/LayoutPoint.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayercpp">trunk/Source/WebCore/rendering/RenderLayer.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscompositinghidpiabsolutesubpixelpositionedtransformedelementsexpectedhtml">trunk/LayoutTests/compositing/hidpi-absolute-subpixel-positioned-transformed-elements-expected.html</a></li>
<li><a href="#trunkLayoutTestscompositinghidpiabsolutesubpixelpositionedtransformedelementshtml">trunk/LayoutTests/compositing/hidpi-absolute-subpixel-positioned-transformed-elements.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (165126 => 165127)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-03-05 21:40:30 UTC (rev 165126)
+++ trunk/LayoutTests/ChangeLog        2014-03-05 21:56:51 UTC (rev 165127)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-03-05  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Subpixel rendering: Device pixel round accumulated subpixel value when the RenderLayer with transform paints its content.
+        https://bugs.webkit.org/show_bug.cgi?id=129079
+
+        Reviewed by Simon Fraser.
+
+        Snap the content to the device pixel position (as opposed to integral position) before
+        applying the transform. Recalculate the remaining subpixels that need offsetting at painting time.
+
+        * compositing/hidpi-absolute-subpixel-positioned-transformed-elements-expected.html: Added.
+        * compositing/hidpi-absolute-subpixel-positioned-transformed-elements.html: Added.
+
</ins><span class="cx"> 2014-03-05  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         JSDataViewPrototype::getData() and setData() crash on platforms that don't allow unaligned accesses
</span></span></pre></div>
<a id="trunkLayoutTestscompositinghidpiabsolutesubpixelpositionedtransformedelementsexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/hidpi-absolute-subpixel-positioned-transformed-elements-expected.html (0 => 165127)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/hidpi-absolute-subpixel-positioned-transformed-elements-expected.html                                (rev 0)
+++ trunk/LayoutTests/compositing/hidpi-absolute-subpixel-positioned-transformed-elements-expected.html        2014-03-05 21:56:51 UTC (rev 165127)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that applying rotation on a subpixel (absolute)positioned box does not change its position/size.&lt;/title&gt;
+&lt;head&gt;
+&lt;style&gt;
+  div {
+    background: green;
+    width: 9px;
+    height: 9px;
+    position: absolute;
+  }
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;container&quot;&gt;&lt;/p&gt;
+&lt;script&gt;
+  var container = document.getElementById(&quot;container&quot;);
+  adjustment = 0.1;
+  for (i = 0; i &lt; 10; ++i) {
+    adjustment+=0.1;
+    for (j = 0; j &lt; 10; ++j) {
+      var e = document.createElement(&quot;div&quot;);
+      e.style.top = (11 * i + j * adjustment) + &quot;px&quot;;
+      e.style.left = (11 * j + i * adjustment) + &quot;px&quot;;
+      container.appendChild(e);
+    }
+  }
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestscompositinghidpiabsolutesubpixelpositionedtransformedelementshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/hidpi-absolute-subpixel-positioned-transformed-elements.html (0 => 165127)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/hidpi-absolute-subpixel-positioned-transformed-elements.html                                (rev 0)
+++ trunk/LayoutTests/compositing/hidpi-absolute-subpixel-positioned-transformed-elements.html        2014-03-05 21:56:51 UTC (rev 165127)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that applying rotation on a subpixel (absolute)positioned box does not change its position/size.&lt;/title&gt;
+&lt;head&gt;
+&lt;style&gt;
+  div {
+    background: green;
+    width: 9px;
+    height: 9px;
+    position: absolute;
+  }
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;container&quot;&gt;&lt;/p&gt;
+&lt;script&gt;
+  var container = document.getElementById(&quot;container&quot;);
+  adjustment = 0.1;
+  for (i = 0; i &lt; 10; ++i) {
+    adjustment+=0.1;
+    for (j = 0; j &lt; 10; ++j) {
+      var e = document.createElement(&quot;div&quot;);
+      e.style.top = (11 * i + j * adjustment) + &quot;px&quot;;
+      e.style.left = (11 * j + i * adjustment) + &quot;px&quot;;
+      container.appendChild(e);
+    }
+  }
+  
+  function rotate() {
+     divs = document.getElementsByTagName(&quot;div&quot;);
+     for (i = 0; i &lt; divs.length; ++i)
+       divs[i].style.webkitTransform = &quot;rotate(90deg)&quot;;
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+  }
+
+  if (window.testRunner)
+    testRunner.waitUntilDone();
+
+  setTimeout(rotate, 0);
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (165126 => 165127)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-05 21:40:30 UTC (rev 165126)
+++ trunk/Source/WebCore/ChangeLog        2014-03-05 21:56:51 UTC (rev 165127)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2014-03-05  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Subpixel rendering: Device pixel round accumulated subpixel value when the RenderLayer with transform paints its content.
+        https://bugs.webkit.org/show_bug.cgi?id=129079
+
+        Reviewed by Simon Fraser.
+
+        Snap the content to the device pixel position (as opposed to integral position) before
+        applying the transform. Recalculate the remaining subpixels that need offsetting at painting time.
+
+        Test: compositing/hidpi-absolute-subpixel-positioned-transformed-elements.html
+
+        * platform/graphics/LayoutPoint.h:
+        (WebCore::roundedForPainting):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintLayerByApplyingTransform):
+
</ins><span class="cx"> 2014-03-05  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Show external device name/type in placeholder
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsLayoutPointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/LayoutPoint.h (165126 => 165127)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/LayoutPoint.h        2014-03-05 21:40:30 UTC (rev 165126)
+++ trunk/Source/WebCore/platform/graphics/LayoutPoint.h        2014-03-05 21:56:51 UTC (rev 165127)
</span><span class="lines">@@ -185,6 +185,16 @@
</span><span class="cx">     return IntSize(snapSizeToPixel(s.width(), p.x()), snapSizeToPixel(s.height(), p.y()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline FloatPoint roundedForPainting(const LayoutPoint&amp; point, float pixelSnappingFactor)
+{
+#if ENABLE(SUBPIXEL_LAYOUT)
+    return FloatPoint(roundToDevicePixel(point.x(), pixelSnappingFactor), roundToDevicePixel(point.y(), pixelSnappingFactor));
+#else
+    UNUSED_PARAM(pixelSnappingFactor);
+    return FloatPoint(point);
+#endif
+}
+
</ins><span class="cx"> inline FloatPoint flooredForPainting(const LayoutPoint&amp; point, float pixelSnappingFactor)
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(SUBPIXEL_LAYOUT)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (165126 => 165127)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.cpp        2014-03-05 21:40:30 UTC (rev 165126)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp        2014-03-05 21:56:51 UTC (rev 165127)
</span><span class="lines">@@ -4167,20 +4167,21 @@
</span><span class="cx"> {
</span><span class="cx">     // This involves subtracting out the position of the layer in our current coordinate space, but preserving
</span><span class="cx">     // the accumulated error for sub-pixel layout.
</span><ins>+    float deviceScaleFactor = renderer().document().deviceScaleFactor();
</ins><span class="cx">     LayoutPoint delta;
</span><span class="cx">     convertToLayerCoords(paintingInfo.rootLayer, delta);
</span><span class="cx">     delta.moveBy(translationOffset);
</span><span class="cx">     TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior));
</span><del>-    IntPoint roundedDelta = roundedIntPoint(delta);
</del><ins>+    FloatPoint roundedDelta = roundedForPainting(delta, deviceScaleFactor);
</ins><span class="cx">     transform.translateRight(roundedDelta.x(), roundedDelta.y());
</span><del>-    LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta);
</del><ins>+    LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - LayoutPoint(roundedDelta));
</ins><span class="cx"> 
</span><span class="cx">     // Apply the transform.
</span><span class="cx">     GraphicsContextStateSaver stateSaver(*context);
</span><span class="cx">     context-&gt;concatCTM(transform.toAffineTransform());
</span><span class="cx"> 
</span><span class="cx">     // Now do a paint with the root layer shifted to be us.
</span><del>-    LayerPaintingInfo transformedPaintingInfo(this, enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect)), paintingInfo.paintBehavior,
</del><ins>+    LayerPaintingInfo transformedPaintingInfo(this, LayoutRect(enclosingRectForPainting(transform.inverse().mapRect(paintingInfo.paintDirtyRect), deviceScaleFactor)), paintingInfo.paintBehavior,
</ins><span class="cx">         adjustedSubPixelAccumulation, paintingInfo.subtreePaintRoot, paintingInfo.renderNamedFlowFragment, paintingInfo.overlapTestRequests);
</span><span class="cx">     paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>