<!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>[215031] releases/WebKitGTK/webkit-2.14</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/215031">215031</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2017-04-06 05:50:11 -0700 (Thu, 06 Apr 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/212431">r212431</a> - [GTK] scroll with transparent background not repainted after scrollY &gt;= 32768
https://bugs.webkit.org/show_bug.cgi?id=154283

Reviewed by Carlos Garcia Campos.

Source/WebCore:

Due to a limitation of the pixman backend, which uses 16 bits to hold signed integers, cairo is
not able to draw anything when using transformation matrices with values bigger than 32768. When
drawing patterns into large pages, the matrices values can overflow those 16 bits, so cairo doesn't
draw anything in, which causes the reported transparent backgrounds.

The patch modifies the transformation matrices both from the current context and the pattern we
are painting, to avoid them to hold values that cannot stored in 16 bits.

There's still the possibility that this happens, but it would require using a pattern with a size
bigger than 32768.

Based on a previous patch by Gwang Yoon Hwang  &lt;yoon@igalia.com&gt;.

Test: fast/backgrounds/background-repeat-long-scroll.html

* platform/graphics/cairo/CairoUtilities.cpp:
(WebCore::drawPatternToCairoContext):

LayoutTests:

Test to ensure that the background pattern of an element is properly being drawn when it's in a position
bigger than 32768.

* fast/backgrounds/background-repeat-long-scroll-expected.html: Added.
* fast/backgrounds/background-repeat-long-scroll.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit214LayoutTestsChangeLog">releases/WebKitGTK/webkit-2.14/LayoutTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit214SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit214SourceWebCoreplatformgraphicscairoCairoUtilitiescpp">releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit214LayoutTestsfastbackgroundsbackgroundrepeatlongscrollexpectedhtml">releases/WebKitGTK/webkit-2.14/LayoutTests/fast/backgrounds/background-repeat-long-scroll-expected.html</a></li>
<li><a href="#releasesWebKitGTKwebkit214LayoutTestsfastbackgroundsbackgroundrepeatlongscrollhtml">releases/WebKitGTK/webkit-2.14/LayoutTests/fast/backgrounds/background-repeat-long-scroll.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit214LayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.14/LayoutTests/ChangeLog (215030 => 215031)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/LayoutTests/ChangeLog        2017-04-06 12:48:45 UTC (rev 215030)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/ChangeLog        2017-04-06 12:50:11 UTC (rev 215031)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2017-02-16  Miguel Gomez  &lt;magomez@igalia.com&gt;
+
+        [GTK] scroll with transparent background not repainted after scrollY &gt;= 32768
+        https://bugs.webkit.org/show_bug.cgi?id=154283
+
+        Reviewed by Carlos Garcia Campos.
+
+        Test to ensure that the background pattern of an element is properly being drawn when it's in a position
+        bigger than 32768.
+
+        * fast/backgrounds/background-repeat-long-scroll-expected.html: Added.
+        * fast/backgrounds/background-repeat-long-scroll.html: Added.
+
</ins><span class="cx"> 2017-03-01  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] fast/canvas/canvas-createPattern-video-loading.html makes its subsequent test timeout
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit214LayoutTestsfastbackgroundsbackgroundrepeatlongscrollexpectedhtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.14/LayoutTests/fast/backgrounds/background-repeat-long-scroll-expected.html (0 => 215031)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/LayoutTests/fast/backgrounds/background-repeat-long-scroll-expected.html                                (rev 0)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/fast/backgrounds/background-repeat-long-scroll-expected.html        2017-04-06 12:50:11 UTC (rev 215031)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+#div1 {
+background-color: black;
+width: 100%;
+height: 35000px;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;window.scrollTo(0,34000)&quot;&gt;
+&lt;div id=&quot;div1&quot;&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit214LayoutTestsfastbackgroundsbackgroundrepeatlongscrollhtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.14/LayoutTests/fast/backgrounds/background-repeat-long-scroll.html (0 => 215031)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/LayoutTests/fast/backgrounds/background-repeat-long-scroll.html                                (rev 0)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/fast/backgrounds/background-repeat-long-scroll.html        2017-04-06 12:50:11 UTC (rev 215031)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+#div1 {
+background: url('./resources/black25x25.png') left top repeat;
+width: 100%;
+height: 35000px;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;window.scrollTo(0,34000)&quot;&gt;
+&lt;div id=&quot;div1&quot;&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit214SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog (215030 => 215031)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog        2017-04-06 12:48:45 UTC (rev 215030)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog        2017-04-06 12:50:11 UTC (rev 215031)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2017-02-16  Miguel Gomez  &lt;magomez@igalia.com&gt;
+
+        [GTK] scroll with transparent background not repainted after scrollY &gt;= 32768
+        https://bugs.webkit.org/show_bug.cgi?id=154283
+
+        Reviewed by Carlos Garcia Campos.
+
+        Due to a limitation of the pixman backend, which uses 16 bits to hold signed integers, cairo is
+        not able to draw anything when using transformation matrices with values bigger than 32768. When
+        drawing patterns into large pages, the matrices values can overflow those 16 bits, so cairo doesn't
+        draw anything in, which causes the reported transparent backgrounds.
+
+        The patch modifies the transformation matrices both from the current context and the pattern we
+        are painting, to avoid them to hold values that cannot stored in 16 bits.
+
+        There's still the possibility that this happens, but it would require using a pattern with a size
+        bigger than 32768.
+
+        Based on a previous patch by Gwang Yoon Hwang  &lt;yoon@igalia.com&gt;.
+
+        Test: fast/backgrounds/background-repeat-long-scroll.html
+
+        * platform/graphics/cairo/CairoUtilities.cpp:
+        (WebCore::drawPatternToCairoContext):
+
</ins><span class="cx"> 2017-03-07  Fujii Hironori  &lt;Hironori.Fujii@sony.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ShadowBlur::calculateLayerBoundingRect doesn't need to return the enclosingIntRect of layerRect
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit214SourceWebCoreplatformgraphicscairoCairoUtilitiescpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp (215030 => 215031)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp        2017-04-06 12:48:45 UTC (rev 215030)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp        2017-04-06 12:50:11 UTC (rev 215031)
</span><span class="lines">@@ -201,8 +201,46 @@
</span><span class="cx">     cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image);
</span><span class="cx">     cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
</span><span class="cx"> 
</span><ins>+    // Due to a limitation in pixman, cairo cannot handle transformation matrices with values bigger than 32768. If the value is
+    // bigger, cairo is not able to paint anything, and this is the reason for the missing backgrounds reported in
+    // https://bugs.webkit.org/show_bug.cgi?id=154283.
+
+    // When drawing a pattern there are 2 matrices that can overflow this limitation, and they are the current transformation
+    // matrix (which translates user space coordinates to coordinates of the output device) and the pattern matrix (which translates
+    // user space coordinates to pattern coordinates). The overflow happens only in the translation components of the matrices.
+
+    // To avoid the problem in the transformation matrix what we do is remove the translation components of the transformation matrix
+    // and perform the translation by moving the destination rectangle instead. For this, we get its translation components (which are in
+    // device coordinates) and divide them by the scale factor to take them to user space coordinates. Then we move the transformation
+    // matrix by the opposite of that amount (which will zero the translation components of the transformation matrix), and move
+    // the destination rectangle by the same amount. We also need to apply the same translation to the pattern matrix, so we get the
+    // same pattern coordinates for the new destination rectangle.
+
+    cairo_matrix_t ctm;
+    cairo_get_matrix(cr, &amp;ctm);
+    double dx = 0, dy = 0;
+    cairo_matrix_transform_point(&amp;ctm, &amp;dx, &amp;dy);
+    double xScale = 1, yScale = 1;
+    cairo_matrix_transform_distance(&amp;ctm, &amp;xScale, &amp;yScale);
+
+    dx = dx / xScale;
+    dy = dy / yScale;
+    cairo_translate(cr, -dx, -dy);
+    FloatRect adjustedDestRect(destRect);
+    adjustedDestRect.move(dx, dy);
+
+    // Regarding the pattern matrix, what we do is reduce the translation component of the matrix taking advantage of the fact that we
+    // are drawing a repeated pattern. This means that, assuming that (w, h) is the size of the pattern, samplig it at (x, y) is the same
+    // than sampling it at (x mod w, y mod h), so we transform the translation component of the pattern matrix in that way.
+
</ins><span class="cx">     cairo_matrix_t patternMatrix = cairo_matrix_t(patternTransform);
</span><del>-    cairo_matrix_t phaseMatrix = {1, 0, 0, 1, phase.x() + tileRect.x() * patternTransform.a(), phase.y() + tileRect.y() * patternTransform.d()};
</del><ins>+    // dx and dy are added here as well to compensate the previous translation of the destination rectangle.
+    double phaseOffsetX = phase.x() + tileRect.x() * patternTransform.a() + dx;
+    double phaseOffsetY = phase.y() + tileRect.y() * patternTransform.d() + dy;
+    // this is where we perform the (x mod w, y mod h) metioned above, but with floats instead of integers.
+    phaseOffsetX -= std::trunc(phaseOffsetX / (tileRect.width() * patternTransform.a())) * tileRect.width() * patternTransform.a();
+    phaseOffsetY -= std::trunc(phaseOffsetY / (tileRect.height() * patternTransform.d())) * tileRect.height() * patternTransform.d();
+    cairo_matrix_t phaseMatrix = {1, 0, 0, 1, phaseOffsetX, phaseOffsetY};
</ins><span class="cx">     cairo_matrix_t combined;
</span><span class="cx">     cairo_matrix_multiply(&amp;combined, &amp;patternMatrix, &amp;phaseMatrix);
</span><span class="cx">     cairo_matrix_invert(&amp;combined);
</span><span class="lines">@@ -211,7 +249,7 @@
</span><span class="cx">     cairo_set_operator(cr, op);
</span><span class="cx">     cairo_set_source(cr, pattern);
</span><span class="cx">     cairo_pattern_destroy(pattern);
</span><del>-    cairo_rectangle(cr, destRect.x(), destRect.y(), destRect.width(), destRect.height());
</del><ins>+    cairo_rectangle(cr, adjustedDestRect.x(), adjustedDestRect.y(), adjustedDestRect.width(), adjustedDestRect.height());
</ins><span class="cx">     cairo_fill(cr);
</span><span class="cx"> 
</span><span class="cx">     cairo_restore(cr);
</span></span></pre>
</div>
</div>

</body>
</html>