<!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>[212082] releases/WebKitGTK/webkit-2.14/Source/WebCore</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/212082">212082</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2017-02-09 23:57:04 -0800 (Thu, 09 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/211967">r211967</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.

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;.

No new tests.

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

<h3>Modified Paths</h3>
<ul>
<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>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit214SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog (212081 => 212082)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog        2017-02-10 07:53:14 UTC (rev 212081)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog        2017-02-10 07:57:04 UTC (rev 212082)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2017-02-09  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;.
+
+        No new tests.
+
+        * platform/graphics/cairo/CairoUtilities.cpp:
+        (WebCore::drawPatternToCairoContext):
+
</ins><span class="cx"> 2017-02-08  Miguel Gomez  &lt;magomez@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Reduce TiledBackingStore tile coverage when on memory pressure state
</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 (212081 => 212082)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp        2017-02-10 07:53:14 UTC (rev 212081)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp        2017-02-10 07:57:04 UTC (rev 212082)
</span><span class="lines">@@ -201,8 +201,28 @@
</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>+    // Cairo cannot convert a cairo_matrix to a Pixman's matrix if any of its components is bigger than maximum int size of Pixman.
+    // With this condition, Cairo gives up to draw given pattern entirely. To workaround this problem, we reduce the coordinate
+    // space by translating CTM and destRect.
+    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 = std::trunc(-dx / tileRect.width()) * tileRect.width() / xScale;
+    dy = std::trunc(-dy / tileRect.height()) * tileRect.height() / yScale;
+    cairo_translate(cr, dx, dy);
+
+    FloatRect adjustedDestRect(destRect);
+    adjustedDestRect.move(-dx, -dy);
+
+    // Again, we need to reduce the coordinate of the transformation matrix we are using for the pattern.
</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 = phase.x() - std::trunc(phase.x() / tileRect.width()) * tileRect.width();
+    dy = phase.y() - std::trunc(phase.y() / tileRect.height()) * tileRect.height();
+    cairo_matrix_t phaseMatrix = {1, 0, 0, 1, dx + tileRect.x() * patternTransform.a(), dy + tileRect.y() * patternTransform.d()};
</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 +231,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>