Title: [212082] releases/WebKitGTK/webkit-2.14/Source/WebCore
Revision
212082
Author
carlo...@webkit.org
Date
2017-02-09 23:57:04 -0800 (Thu, 09 Feb 2017)

Log Message

Merge r211967 - [GTK] scroll with transparent background not repainted after scrollY >= 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  <y...@igalia.com>.

No new tests.

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

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog (212081 => 212082)


--- 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)
@@ -1,3 +1,28 @@
+2017-02-09  Miguel Gomez  <mago...@igalia.com>
+
+        [GTK] scroll with transparent background not repainted after scrollY >= 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  <y...@igalia.com>.
+
+        No new tests.
+
+        * platform/graphics/cairo/CairoUtilities.cpp:
+        (WebCore::drawPatternToCairoContext):
+
 2017-02-08  Miguel Gomez  <mago...@igalia.com>
 
         [GTK] Reduce TiledBackingStore tile coverage when on memory pressure state

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp (212081 => 212082)


--- 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)
@@ -201,8 +201,28 @@
     cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image);
     cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
 
+    // 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, &ctm);
+    double dx = 0, dy = 0;
+    cairo_matrix_transform_point(&ctm, &dx, &dy);
+    double xScale = 1, yScale = 1;
+    cairo_matrix_transform_distance(&ctm, &xScale, &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.
     cairo_matrix_t patternMatrix = cairo_matrix_t(patternTransform);
-    cairo_matrix_t phaseMatrix = {1, 0, 0, 1, phase.x() + tileRect.x() * patternTransform.a(), phase.y() + tileRect.y() * patternTransform.d()};
+    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()};
     cairo_matrix_t combined;
     cairo_matrix_multiply(&combined, &patternMatrix, &phaseMatrix);
     cairo_matrix_invert(&combined);
@@ -211,7 +231,7 @@
     cairo_set_operator(cr, op);
     cairo_set_source(cr, pattern);
     cairo_pattern_destroy(pattern);
-    cairo_rectangle(cr, destRect.x(), destRect.y(), destRect.width(), destRect.height());
+    cairo_rectangle(cr, adjustedDestRect.x(), adjustedDestRect.y(), adjustedDestRect.width(), adjustedDestRect.height());
     cairo_fill(cr);
 
     cairo_restore(cr);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to