| Differences between
and this patch
- a/Source/WebCore/ChangeLog +25 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2017-02-16  Miguel Gomez  <magomez@igalia.com>
2
3
        [GTK] scroll with transparent background not repainted after scrollY >= 32768
4
        https://bugs.webkit.org/show_bug.cgi?id=154283
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Due to a limitation of the pixman backend, which uses 16 bits to hold signed integers, cairo is
9
        not able to draw anything when using transformation matrices with values bigger than 32768. When
10
        drawing patterns into large pages, the matrices values can overflow those 16 bits, so cairo doesn't
11
        draw anything in, which causes the reported transparent backgrounds.
12
13
        The patch modifies the transformation matrices both from the current context and the pattern we
14
        are painting, to avoid them to hold values that cannot stored in 16 bits.
15
16
        There's still the possibility that this happens, but it would require using a pattern with a size
17
        bigger than 32768.
18
19
        Based on a previous patch by Gwang Yoon Hwang  <yoon@igalia.com>.
20
21
        Test: fast/backgrounds/background-repeat-long-scroll.html
22
23
        * platform/graphics/cairo/CairoUtilities.cpp:
24
        (WebCore::drawPatternToCairoContext):
25
1
2017-02-15  Jer Noble  <jer.noble@apple.com>
26
2017-02-15  Jer Noble  <jer.noble@apple.com>
2
27
3
        REGRESSION (r212311): NULL-dereference in HTMLMediaElement::prepareToPlay()
28
        REGRESSION (r212311): NULL-dereference in HTMLMediaElement::prepareToPlay()
- a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp -2 / +40 lines
Lines 205-212 void drawPatternToCairoContext(cairo_t* cr, cairo_surface_t* image, const IntSiz a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp_sec1
205
    cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image);
205
    cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image);
206
    cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
206
    cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
207
207
208
    // Due to a limitation in pixman, cairo cannot handle transformation matrices with values bigger than 32768. If the value is
209
    // bigger, cairo is not able to paint anything, and this is the reason for the missing backgrounds reported in
210
    // https://bugs.webkit.org/show_bug.cgi?id=154283.
211
212
    // When drawing a pattern there are 2 matrices that can overflow this limitation, and they are the current transformation
213
    // matrix (which translates user space coordinates to coordinates of the output device) and the pattern matrix (which translates
214
    // user space coordinates to pattern coordinates). The overflow happens only in the translation components of the matrices.
215
216
    // To avoid the problem in the transformation matrix what we do is remove the translation components of the transformation matrix
217
    // and perform the translation by moving the destination rectangle instead. For this, we get its translation components (which are in
218
    // device coordinates) and divide them by the scale factor to take them to user space coordinates. Then we move the transformation
219
    // matrix by the opposite of that amount (which will zero the translation components of the transformation matrix), and move
220
    // the destination rectangle by the same amount. We also need to apply the same translation to the pattern matrix, so we get the
221
    // same pattern coordinates for the new destination rectangle.
222
223
    cairo_matrix_t ctm;
224
    cairo_get_matrix(cr, &ctm);
225
    double dx = 0, dy = 0;
226
    cairo_matrix_transform_point(&ctm, &dx, &dy);
227
    double xScale = 1, yScale = 1;
228
    cairo_matrix_transform_distance(&ctm, &xScale, &yScale);
229
230
    dx = dx / xScale;
231
    dy = dy / yScale;
232
    cairo_translate(cr, -dx, -dy);
233
    FloatRect adjustedDestRect(destRect);
234
    adjustedDestRect.move(dx, dy);
235
236
    // Regarding the pattern matrix, what we do is reduce the translation component of the matrix taking advantage of the fact that we
237
    // 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
238
    // than sampling it at (x mod w, y mod h), so we transform the translation component of the pattern matrix in that way.
239
208
    cairo_matrix_t patternMatrix = cairo_matrix_t(patternTransform);
240
    cairo_matrix_t patternMatrix = cairo_matrix_t(patternTransform);
209
    cairo_matrix_t phaseMatrix = {1, 0, 0, 1, phase.x() + tileRect.x() * patternTransform.a(), phase.y() + tileRect.y() * patternTransform.d()};
241
    // dx and dy are added here as well to compensate the previous translation of the destination rectangle.
242
    double phaseOffsetX = phase.x() + tileRect.x() * patternTransform.a() + dx;
243
    double phaseOffsetY = phase.y() + tileRect.y() * patternTransform.d() + dy;
244
    // this is where we perform the (x mod w, y mod h) metioned above, but with floats instead of integers.
245
    phaseOffsetX -= std::trunc(phaseOffsetX / (tileRect.width() * patternTransform.a())) * tileRect.width() * patternTransform.a();
246
    phaseOffsetY -= std::trunc(phaseOffsetY / (tileRect.height() * patternTransform.d())) * tileRect.height() * patternTransform.d();
247
    cairo_matrix_t phaseMatrix = {1, 0, 0, 1, phaseOffsetX, phaseOffsetY};
210
    cairo_matrix_t combined;
248
    cairo_matrix_t combined;
211
    cairo_matrix_multiply(&combined, &patternMatrix, &phaseMatrix);
249
    cairo_matrix_multiply(&combined, &patternMatrix, &phaseMatrix);
212
    cairo_matrix_invert(&combined);
250
    cairo_matrix_invert(&combined);
Lines 215-221 void drawPatternToCairoContext(cairo_t* cr, cairo_surface_t* image, const IntSiz a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp_sec2
215
    cairo_set_operator(cr, op);
253
    cairo_set_operator(cr, op);
216
    cairo_set_source(cr, pattern);
254
    cairo_set_source(cr, pattern);
217
    cairo_pattern_destroy(pattern);
255
    cairo_pattern_destroy(pattern);
218
    cairo_rectangle(cr, destRect.x(), destRect.y(), destRect.width(), destRect.height());
256
    cairo_rectangle(cr, adjustedDestRect.x(), adjustedDestRect.y(), adjustedDestRect.width(), adjustedDestRect.height());
219
    cairo_fill(cr);
257
    cairo_fill(cr);
220
258
221
    cairo_restore(cr);
259
    cairo_restore(cr);
- a/LayoutTests/ChangeLog +13 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2017-02-16  Miguel Gomez  <magomez@igalia.com>
2
3
        [GTK] scroll with transparent background not repainted after scrollY >= 32768
4
        https://bugs.webkit.org/show_bug.cgi?id=154283
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Test to ensure that the background pattern of an element is properly being drawn when it's in a position
9
        bigger than 32768.
10
11
        * fast/backgrounds/background-repeat-long-scroll-expected.html: Added.
12
        * fast/backgrounds/background-repeat-long-scroll.html: Added.
13
1
2017-02-15  Ryan Haddad  <ryanhaddad@apple.com>
14
2017-02-15  Ryan Haddad  <ryanhaddad@apple.com>
2
15
3
        Mark inspector/debugger/search-scripts.html as flaky.
16
        Mark inspector/debugger/search-scripts.html as flaky.
- a/LayoutTests/fast/backgrounds/background-repeat-long-scroll-expected.html +16 lines
Line 0 a/LayoutTests/fast/backgrounds/background-repeat-long-scroll-expected.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<style>
5
#div1 {
6
background-color: black;
7
width: 100%;
8
height: 35000px;
9
}
10
</style>
11
</head>
12
<body onload="window.scrollTo(0,34000)">
13
<div id="div1">
14
</div>
15
</body>
16
</html>
- a/LayoutTests/fast/backgrounds/background-repeat-long-scroll.html +16 lines
Line 0 a/LayoutTests/fast/backgrounds/background-repeat-long-scroll.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<style>
5
#div1 {
6
background: url('./resources/black25x25.png') left top repeat;
7
width: 100%;
8
height: 35000px;
9
}
10
</style>
11
</head>
12
<body onload="window.scrollTo(0,34000)">
13
<div id="div1">
14
</div>
15
</body>
16
</html>

Return to Bug 154283