<!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>[177412] 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/177412">177412</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2014-12-16 16:50:52 -0800 (Tue, 16 Dec 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Subpixel rendering: Animating HTML elements leaves trails when embedded to a subpxiel positioned iframe.
https://bugs.webkit.org/show_bug.cgi?id=139691
rdar://problem/19078958

Reviewed by Simon Fraser.

This patch ensures that repaint rect and actual paint coordinate calculations are in sync.

Source/WebCore:

RenderWidget painting still snaps final coordinates to integral positions. We need to
mimic the same snapping behaviour when the repaint rects are being calculated so that
they are in sync with the final repaint rects. This is a workaround until after
widgets get pushed to device pixel positions.

Test: fast/repaint/hidpi-content-inside-iframe-leaves-trails.html

* rendering/RenderBox.cpp:
(WebCore::RenderBox::computeRectForRepaint):
* rendering/RenderView.cpp:
(WebCore::RenderView::repaintViewRectangle):
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::paintContents):

LayoutTests:

* fast/repaint/hidpi-content-inside-iframe-leaves-trails-expected.txt: Added.
* fast/repaint/hidpi-content-inside-iframe-leaves-trails.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="#trunkSourceWebCorerenderingRenderBoxcpp">trunk/Source/WebCore/rendering/RenderBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderViewcpp">trunk/Source/WebCore/rendering/RenderView.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderWidgetcpp">trunk/Source/WebCore/rendering/RenderWidget.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastrepainthidpicontentinsideiframeleavestrailsexpectedtxt">trunk/LayoutTests/fast/repaint/hidpi-content-inside-iframe-leaves-trails-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastrepainthidpicontentinsideiframeleavestrailshtml">trunk/LayoutTests/fast/repaint/hidpi-content-inside-iframe-leaves-trails.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (177411 => 177412)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-12-17 00:47:15 UTC (rev 177411)
+++ trunk/LayoutTests/ChangeLog        2014-12-17 00:50:52 UTC (rev 177412)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-12-16  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Subpixel rendering: Animating HTML elements leaves trails when embedded to a subpxiel positioned iframe.
+        https://bugs.webkit.org/show_bug.cgi?id=139691
+        rdar://problem/19078958
+
+        Reviewed by Simon Fraser.
+
+        This patch ensures that repaint rect and actual paint coordinate calculations are in sync.
+
+        * fast/repaint/hidpi-content-inside-iframe-leaves-trails-expected.txt: Added.
+        * fast/repaint/hidpi-content-inside-iframe-leaves-trails.html: Added.
+
</ins><span class="cx"> 2014-12-16  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rebaseline Mavericks test result after r177398
</span></span></pre></div>
<a id="trunkLayoutTestsfastrepainthidpicontentinsideiframeleavestrailsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/repaint/hidpi-content-inside-iframe-leaves-trails-expected.txt (0 => 177412)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/repaint/hidpi-content-inside-iframe-leaves-trails-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/repaint/hidpi-content-inside-iframe-leaves-trails-expected.txt        2014-12-17 00:50:52 UTC (rev 177412)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+PASS repaintRects.indexOf('rect 0 0 101 100') is not -1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastrepainthidpicontentinsideiframeleavestrailshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/repaint/hidpi-content-inside-iframe-leaves-trails.html (0 => 177412)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/repaint/hidpi-content-inside-iframe-leaves-trails.html                                (rev 0)
+++ trunk/LayoutTests/fast/repaint/hidpi-content-inside-iframe-leaves-trails.html        2014-12-17 00:50:52 UTC (rev 177412)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that subpixel positioned iframe content's repaint rect is properly calculated.&lt;/title&gt;
+&lt;script&gt;jsTestIsAsync = true;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+  if (window.testRunner &amp;&amp; window.internals) {
+    testRunner.dumpAsText(false);
+    internals.startTrackingRepaints();
+  }
+
+var repaintRects;
+function test() {
+  setTimeout(function() {
+    var iframeDocument = window.frames[&quot;embeddedFrame&quot;].document;
+    iframeDocument.getElementById(&quot;foo&quot;).style.left = &quot;50px&quot;;
+    iframeDocument.body.offsetWidth;
+    if (window.testRunner &amp;&amp; window.internals) {
+        repaintRects = internals.repaintRectsAsText();
+        shouldNotBe(&quot;repaintRects.indexOf('rect 0 0 101 100')&quot;, &quot;-1&quot;);
+        internals.stopTrackingRepaints();
+        finishJSTest();
+    }
+  }, 10);
+  }
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+  &lt;iframe onload=&quot;test()&quot; name=&quot;embeddedFrame&quot; style=&quot;position:absolute; top: 0px; left: 0.4px; width: 200px; height: 200px&quot; frameBorder=0; srcdoc='
+    &lt;!DOCTYPE html&gt;
+    &lt;html&gt;        
+    &lt;head&gt;
+    &lt;style&gt;
+      div {
+        position: absolute;
+        background: red;
+        height: 100px;
+        width: 100px;
+        top: 0px;
+        left: 0.7px;
+      }
+    &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body&gt;
+      &lt;div id=foo&gt;&lt;/div&gt;
+    &lt;/body&gt;
+    &lt;/html&gt;'&gt;
+  &lt;/iframe&gt;
+&lt;/body&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&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 (177411 => 177412)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-12-17 00:47:15 UTC (rev 177411)
+++ trunk/Source/WebCore/ChangeLog        2014-12-17 00:50:52 UTC (rev 177412)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2014-12-16  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Subpixel rendering: Animating HTML elements leaves trails when embedded to a subpxiel positioned iframe.
+        https://bugs.webkit.org/show_bug.cgi?id=139691
+        rdar://problem/19078958
+
+        Reviewed by Simon Fraser.
+
+        This patch ensures that repaint rect and actual paint coordinate calculations are in sync.
+
+        RenderWidget painting still snaps final coordinates to integral positions. We need to
+        mimic the same snapping behaviour when the repaint rects are being calculated so that
+        they are in sync with the final repaint rects. This is a workaround until after
+        widgets get pushed to device pixel positions.
+
+        Test: fast/repaint/hidpi-content-inside-iframe-leaves-trails.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::computeRectForRepaint):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::repaintViewRectangle):
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::paintContents):
+
</ins><span class="cx"> 2014-12-16  Beth Dakin  &lt;bdakin@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION: Preview popovers obscure the link, look wrong
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (177411 => 177412)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.cpp        2014-12-17 00:47:15 UTC (rev 177411)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp        2014-12-17 00:50:52 UTC (rev 177412)
</span><span class="lines">@@ -2185,8 +2185,12 @@
</span><span class="cx">     if (isWritingModeRoot() &amp;&amp; !isOutOfFlowPositioned())
</span><span class="cx">         flipForWritingMode(rect);
</span><span class="cx"> 
</span><ins>+    LayoutSize locationOffset = this-&gt;locationOffset();
+    // FIXME: This is needed as long as RenderWidget snaps to integral size/position.
+    if (isRenderReplaced() &amp;&amp; isWidget())
+        locationOffset = toIntSize(flooredIntPoint(locationOffset));
</ins><span class="cx">     LayoutPoint topLeft = rect.location();
</span><del>-    topLeft.move(locationOffset());
</del><ins>+    topLeft.move(locationOffset);
</ins><span class="cx"> 
</span><span class="cx">     // We are now in our parent container's coordinate space.  Apply our transform to obtain a bounding box
</span><span class="cx">     // in the parent's coordinate space that encloses us.
</span><span class="lines">@@ -2194,7 +2198,7 @@
</span><span class="cx">         fixed = position == FixedPosition;
</span><span class="cx">         rect = LayoutRect(encloseRectToDevicePixels(layer()-&gt;transform()-&gt;mapRect(rect), document().deviceScaleFactor()));
</span><span class="cx">         topLeft = rect.location();
</span><del>-        topLeft.move(locationOffset());
</del><ins>+        topLeft.move(locationOffset);
</ins><span class="cx">     } else if (position == FixedPosition)
</span><span class="cx">         fixed = true;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderView.cpp (177411 => 177412)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderView.cpp        2014-12-17 00:47:15 UTC (rev 177411)
+++ trunk/Source/WebCore/rendering/RenderView.cpp        2014-12-17 00:50:52 UTC (rev 177412)
</span><span class="lines">@@ -619,6 +619,8 @@
</span><span class="cx">     if (!shouldRepaint(repaintRect))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    // FIXME: enclosingRect is needed as long as we integral snap ScrollView/FrameView/RenderWidget size/position.
+    IntRect enclosingRect = enclosingIntRect(repaintRect);
</ins><span class="cx">     if (auto ownerElement = document().ownerElement()) {
</span><span class="cx">         RenderBox* ownerBox = ownerElement-&gt;renderBox();
</span><span class="cx">         if (!ownerBox)
</span><span class="lines">@@ -626,9 +628,9 @@
</span><span class="cx">         LayoutRect viewRect = this-&gt;viewRect();
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">         // Don't clip using the visible rect since clipping is handled at a higher level on iPhone.
</span><del>-        LayoutRect adjustedRect = repaintRect;
</del><ins>+        LayoutRect adjustedRect = enclosingRect;
</ins><span class="cx"> #else
</span><del>-        LayoutRect adjustedRect = intersection(repaintRect, viewRect);
</del><ins>+        LayoutRect adjustedRect = intersection(enclosingRect, viewRect);
</ins><span class="cx"> #endif
</span><span class="cx">         adjustedRect.moveBy(-viewRect.location());
</span><span class="cx">         adjustedRect.moveBy(ownerBox-&gt;contentBoxRect().location());
</span><span class="lines">@@ -637,9 +639,6 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     frameView().addTrackedRepaintRect(snapRectToDevicePixels(repaintRect, document().deviceScaleFactor()));
</span><del>-
-    // FIXME: convert all repaint rect dependencies to FloatRect.
-    IntRect enclosingRect = enclosingIntRect(repaintRect);
</del><span class="cx">     if (!m_accumulatedRepaintRegion) {
</span><span class="cx">         frameView().repaintContentRectangle(enclosingRect);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderWidgetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderWidget.cpp (177411 => 177412)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderWidget.cpp        2014-12-17 00:47:15 UTC (rev 177411)
+++ trunk/Source/WebCore/rendering/RenderWidget.cpp        2014-12-17 00:50:52 UTC (rev 177412)
</span><span class="lines">@@ -217,22 +217,20 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderWidget::paintContents(PaintInfo&amp; paintInfo, const LayoutPoint&amp; paintOffset)
</span><span class="cx"> {
</span><del>-    LayoutPoint adjustedPaintOffset = paintOffset + location();
-
</del><ins>+    IntPoint contentPaintOffset = roundedIntPoint(paintOffset + location() + contentBoxRect().location());
</ins><span class="cx">     // Tell the widget to paint now. This is the only time the widget is allowed
</span><span class="cx">     // to paint itself. That way it will composite properly with z-indexed layers.
</span><del>-    IntPoint widgetLocation = m_widget-&gt;frameRect().location();
-    IntPoint paintLocation(roundToInt(adjustedPaintOffset.x() + borderLeft() + paddingLeft()),
-        roundToInt(adjustedPaintOffset.y() + borderTop() + paddingTop()));
</del><span class="cx">     LayoutRect paintRect = paintInfo.rect;
</span><span class="cx"> 
</span><del>-    LayoutSize widgetPaintOffset = paintLocation - widgetLocation;
</del><ins>+    IntPoint widgetLocation = m_widget-&gt;frameRect().location();
+    IntSize widgetPaintOffset = contentPaintOffset - widgetLocation;
</ins><span class="cx">     // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
</span><span class="cx">     // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
</span><span class="cx">     if (!widgetPaintOffset.isZero()) {
</span><span class="cx">         paintInfo.context-&gt;translate(widgetPaintOffset);
</span><span class="cx">         paintRect.move(-widgetPaintOffset);
</span><span class="cx">     }
</span><ins>+    // FIXME: Remove repaintrect encolsing/integral snapping when RenderWidget becomes device pixel snapped.
</ins><span class="cx">     m_widget-&gt;paint(paintInfo.context, snappedIntRect(paintRect));
</span><span class="cx"> 
</span><span class="cx">     if (!widgetPaintOffset.isZero())
</span></span></pre>
</div>
</div>

</body>
</html>