WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-154283-20170216134652.patch (text/plain), 7.94 KB, created by
Miguel Gomez
on 2017-02-16 04:49:30 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Miguel Gomez
Created:
2017-02-16 04:49:30 PST
Size:
7.94 KB
patch
obsolete
>Subversion Revision: 212427 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 8c99faa29c30fe31ef0f691a496ca0efcc13a6ba..7e71294164b0a1c37f775eb26bd01135a13eb627 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,28 @@ >+2017-02-16 Miguel Gomez <magomez@igalia.com> >+ >+ [GTK] scroll with transparent background not repainted after scrollY >= 32768 >+ https://bugs.webkit.org/show_bug.cgi?id=154283 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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 <yoon@igalia.com>. >+ >+ Test: fast/backgrounds/background-repeat-long-scroll.html >+ >+ * platform/graphics/cairo/CairoUtilities.cpp: >+ (WebCore::drawPatternToCairoContext): >+ > 2017-02-15 Jer Noble <jer.noble@apple.com> > > REGRESSION (r212311): NULL-dereference in HTMLMediaElement::prepareToPlay() >diff --git a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp b/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp >index fc485894014f2d2d0baa2893989b13934ba2a7d6..1fd51d76e774f1d83b9bef4710707a4c4483c568 100644 >--- a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp >+++ b/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp >@@ -205,8 +205,46 @@ void drawPatternToCairoContext(cairo_t* cr, cairo_surface_t* image, const IntSiz > cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image); > cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); > >+ // 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, &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 = 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. >+ > 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 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}; > cairo_matrix_t combined; > cairo_matrix_multiply(&combined, &patternMatrix, &phaseMatrix); > cairo_matrix_invert(&combined); >@@ -215,7 +253,7 @@ void drawPatternToCairoContext(cairo_t* cr, cairo_surface_t* image, const IntSiz > 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); >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index d5a53e406d39d860d2c0aa69f4a5ac3a7f41fb38..b6a0cb74b5cccde3187a3b406210e264d9c746b3 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,16 @@ >+2017-02-16 Miguel Gomez <magomez@igalia.com> >+ >+ [GTK] scroll with transparent background not repainted after scrollY >= 32768 >+ https://bugs.webkit.org/show_bug.cgi?id=154283 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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. >+ > 2017-02-15 Ryan Haddad <ryanhaddad@apple.com> > > Mark inspector/debugger/search-scripts.html as flaky. >diff --git a/LayoutTests/fast/backgrounds/background-repeat-long-scroll-expected.html b/LayoutTests/fast/backgrounds/background-repeat-long-scroll-expected.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7672bd57c35eec150cf29f5df6cf5cdf467d5db8 >--- /dev/null >+++ b/LayoutTests/fast/backgrounds/background-repeat-long-scroll-expected.html >@@ -0,0 +1,16 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<style> >+#div1 { >+background-color: black; >+width: 100%; >+height: 35000px; >+} >+</style> >+</head> >+<body onload="window.scrollTo(0,34000)"> >+<div id="div1"> >+</div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/fast/backgrounds/background-repeat-long-scroll.html b/LayoutTests/fast/backgrounds/background-repeat-long-scroll.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7106447c8bd96aa823b213e267873ab993f6dda0 >--- /dev/null >+++ b/LayoutTests/fast/backgrounds/background-repeat-long-scroll.html >@@ -0,0 +1,16 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<style> >+#div1 { >+background: url('./resources/black25x25.png') left top repeat; >+width: 100%; >+height: 35000px; >+} >+</style> >+</head> >+<body onload="window.scrollTo(0,34000)"> >+<div id="div1"> >+</div> >+</body> >+</html> >\ No newline at end of file
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 154283
:
271986
|
272084
|
277862
|
301043
|
301047
|
301051
| 301744