Title: [246980] releases/WebKitGTK/webkit-2.24
Revision
246980
Author
[email protected]
Date
2019-07-01 02:21:46 -0700 (Mon, 01 Jul 2019)

Log Message

Merge r246350 - [cairo][SVG] Putting multiple path elements in clippath causes rendering artifacts
https://bugs.webkit.org/show_bug.cgi?id=198701
<rdar://problem/51620347>

Reviewed by Don Olmstead.

Source/WebCore:

We need to save the current transformation matrix at the moment the image mask is set and set it again on
restore right before applying the mask. This patch also creates a pattern for the image mask surface and set its
transformation matrix according to the mask position, so that we don't need to save the mask rectangle too.

Tests: svg/clip-path/clip-hidpi-expected.svg
       svg/clip-path/clip-hidpi.svg
       svg/clip-path/clip-opacity-translate-expected.svg
       svg/clip-path/clip-opacity-translate.svg

* platform/graphics/cairo/PlatformContextCairo.cpp:
(WebCore::PlatformContextCairo::restore):
(WebCore::PlatformContextCairo::pushImageMask):

LayoutTests:

* svg/clip-path/clip-hidpi-expected.svg: Added.
* svg/clip-path/clip-hidpi.svg: Added.
* svg/clip-path/clip-opacity-translate-expected.svg: Added.
* svg/clip-path/clip-opacity-translate.svg: Added.

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog (246979 => 246980)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog	2019-07-01 09:21:40 UTC (rev 246979)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog	2019-07-01 09:21:46 UTC (rev 246980)
@@ -1,3 +1,16 @@
+2019-06-12  Carlos Garcia Campos  <[email protected]>
+
+        [cairo][SVG] Putting multiple path elements in clippath causes rendering artifacts
+        https://bugs.webkit.org/show_bug.cgi?id=198701
+        <rdar://problem/51620347>
+
+        Reviewed by Don Olmstead.
+
+        * svg/clip-path/clip-hidpi-expected.svg: Added.
+        * svg/clip-path/clip-hidpi.svg: Added.
+        * svg/clip-path/clip-opacity-translate-expected.svg: Added.
+        * svg/clip-path/clip-opacity-translate.svg: Added.
+
 2019-06-11  Fujii Hironori  <[email protected]>
 
         [cairo][SVG] Putting multiple path elements in clippath causes rendering artifacts

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-hidpi-expected.svg (0 => 246980)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-hidpi-expected.svg	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-hidpi-expected.svg	2019-07-01 09:21:46 UTC (rev 246980)
@@ -0,0 +1,18 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<!-- The FO should be clipped with only the green half visible. -->
+<defs>
+<clipPath id="clip">
+    <rect width="200" height="50"/>
+    <rect width="200" height="50"/>
+</clipPath>
+</defs>
+<foreignObject width="200" height="100" clip-path="url(#clip)" opacity=".5">
+    <html xmlns="http://www.w3.org/1999/xhtml">
+    <body>
+        <div style="background: green; height: 50px;"></div>
+        <div style="background: red; height: 50px;"></div>
+    </body>
+    </html>
+</foreignObject>
+</svg>
+

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-hidpi.svg (0 => 246980)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-hidpi.svg	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-hidpi.svg	2019-07-01 09:21:46 UTC (rev 246980)
@@ -0,0 +1,22 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<!-- The FO should be clipped with only the green half visible. -->
+<defs>
+<clipPath id="clip">
+    <rect width="200" height="50"/>
+    <rect width="200" height="50"/>
+</clipPath>
+</defs>
+<foreignObject width="200" height="100" clip-path="url(#clip)" opacity=".5">
+    <html xmlns="http://www.w3.org/1999/xhtml">
+    <body>
+        <div style="background: green; height: 50px;"></div>
+        <div style="background: red; height: 50px;"></div>
+    </body>
+    </html>
+</foreignObject>
+<script>
+  testRunner.setBackingScaleFactor(2, function() { testRunner.notifyDone() });
+  testRunner.waitUntilDone();
+</script>
+</svg>
+

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-opacity-translate-expected.svg (0 => 246980)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-opacity-translate-expected.svg	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-opacity-translate-expected.svg	2019-07-01 09:21:46 UTC (rev 246980)
@@ -0,0 +1,18 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="350">
+<g>
+  <circle cx="50" cy="50" r="50" fill="green"/>
+  <circle cx="100" cy="50" r="50" fill="red" />
+  <g opacity=".5">
+    <circle cx="50" cy="100" r="50" fill="green"/>
+    <circle cx="100" cy="100" r="50" fill="red" />
+  </g>
+</g>
+<g transform="translate(200,0)">
+  <circle cx="50" cy="50" r="50" fill="green"/>
+  <circle cx="100" cy="50" r="50" fill="red" />
+  <g opacity=".5">
+    <circle cx="50" cy="100" r="50" fill="green"/>
+    <circle cx="100" cy="100" r="50" fill="red" />
+  </g>
+</g>
+</svg>

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-opacity-translate.svg (0 => 246980)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-opacity-translate.svg	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/svg/clip-path/clip-opacity-translate.svg	2019-07-01 09:21:46 UTC (rev 246980)
@@ -0,0 +1,27 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="350">
+<defs>
+<clipPath id="clip1">
+    <rect width="200" height="200"/>
+</clipPath>
+<clipPath id="clip2">
+    <rect width="200" height="200"/>
+    <rect width="200" height="200"/>
+</clipPath>
+</defs>
+<g>
+  <circle cx="50" cy="50" r="50" fill="green"/>
+  <circle cx="100" cy="50" r="50" fill="red" />
+  <g clip-path="url(#clip1)" opacity=".5">
+    <circle cx="50" cy="100" r="50" fill="green"/>
+    <circle cx="100" cy="100" r="50" fill="red" />
+  </g>
+</g>
+<g transform="translate(200,0)">
+  <circle cx="50" cy="50" r="50" fill="green"/>
+  <circle cx="100" cy="50" r="50" fill="red" />
+  <g clip-path="url(#clip2)" opacity=".5">
+    <circle cx="50" cy="100" r="50" fill="green"/>
+    <circle cx="100" cy="100" r="50" fill="red" />
+  </g>
+</g>
+</svg>

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog (246979 => 246980)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog	2019-07-01 09:21:40 UTC (rev 246979)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog	2019-07-01 09:21:46 UTC (rev 246980)
@@ -1,3 +1,24 @@
+2019-06-12  Carlos Garcia Campos  <[email protected]>
+
+        [cairo][SVG] Putting multiple path elements in clippath causes rendering artifacts
+        https://bugs.webkit.org/show_bug.cgi?id=198701
+        <rdar://problem/51620347>
+
+        Reviewed by Don Olmstead.
+
+        We need to save the current transformation matrix at the moment the image mask is set and set it again on
+        restore right before applying the mask. This patch also creates a pattern for the image mask surface and set its
+        transformation matrix according to the mask position, so that we don't need to save the mask rectangle too.
+
+        Tests: svg/clip-path/clip-hidpi-expected.svg
+               svg/clip-path/clip-hidpi.svg
+               svg/clip-path/clip-opacity-translate-expected.svg
+               svg/clip-path/clip-opacity-translate.svg
+
+        * platform/graphics/cairo/PlatformContextCairo.cpp:
+        (WebCore::PlatformContextCairo::restore):
+        (WebCore::PlatformContextCairo::pushImageMask):
+
 2019-06-11  Fujii Hironori  <[email protected]>
 
         [cairo][SVG] Putting multiple path elements in clippath causes rendering artifacts

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp (246979 => 246980)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp	2019-07-01 09:21:40 UTC (rev 246979)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp	2019-07-01 09:21:46 UTC (rev 246980)
@@ -30,34 +30,10 @@
 
 #if USE(CAIRO)
 
-#include "CairoUtilities.h"
-#include "Gradient.h"
-#include "GraphicsContext.h"
-#include "Pattern.h"
 #include <cairo.h>
 
 namespace WebCore {
 
-// In Cairo image masking is immediate, so to emulate image clipping we must save masking
-// details as part of the context state and apply them during platform restore.
-class ImageMaskInformation {
-public:
-    void update(cairo_surface_t* maskSurface, const FloatRect& maskRect)
-    {
-        m_maskSurface = maskSurface;
-        m_maskRect = maskRect;
-    }
-
-    bool isValid() const { return m_maskSurface; }
-    cairo_surface_t* maskSurface() const { return m_maskSurface.get(); }
-    const FloatRect& maskRect() const { return m_maskRect; }
-
-private:
-    RefPtr<cairo_surface_t> m_maskSurface;
-    FloatRect m_maskRect;
-};
-
-
 // Encapsulates the additional painting state information we store for each
 // pushed graphics state.
 class PlatformContextCairo::State {
@@ -64,7 +40,10 @@
 public:
     State() = default;
 
-    ImageMaskInformation m_imageMaskInformation;
+    struct {
+        RefPtr<cairo_pattern_t> pattern;
+        cairo_matrix_t matrix;
+    } m_mask;
 };
 
 PlatformContextCairo::PlatformContextCairo(cairo_t* cr)
@@ -76,11 +55,14 @@
 
 void PlatformContextCairo::restore()
 {
-    const ImageMaskInformation& maskInformation = m_state->m_imageMaskInformation;
-    if (maskInformation.isValid()) {
-        const FloatRect& maskRect = maskInformation.maskRect();
+    if (m_state->m_mask.pattern) {
         cairo_pop_group_to_source(m_cr.get());
-        cairo_mask_surface(m_cr.get(), maskInformation.maskSurface(), maskRect.x(), maskRect.y());
+
+        cairo_matrix_t matrix;
+        cairo_get_matrix(m_cr.get(), &matrix);
+        cairo_set_matrix(m_cr.get(), &m_state->m_mask.matrix);
+        cairo_mask(m_cr.get(), m_state->m_mask.pattern.get());
+        cairo_set_matrix(m_cr.get(), &matrix);
     }
 
     m_stateStack.removeLast();
@@ -105,11 +87,13 @@
     // We must call savePlatformState at least once before we can use image masking,
     // since we actually apply the mask in restorePlatformState.
     ASSERT(!m_stateStack.isEmpty());
-    m_state->m_imageMaskInformation.update(surface, rect);
+    m_state->m_mask.pattern = adoptRef(cairo_pattern_create_for_surface(surface));
+    cairo_get_matrix(m_cr.get(), &m_state->m_mask.matrix);
 
-    // Cairo doesn't support the notion of an image clip, so we push a group here
-    // and then paint it to the surface with an image mask (which is an immediate
-    // operation) during restorePlatformState.
+    cairo_matrix_t matrix;
+    cairo_matrix_init_translate(&matrix, -rect.x(), -rect.y());
+    cairo_pattern_set_matrix(m_state->m_mask.pattern.get(), &matrix);
+
     cairo_push_group(m_cr.get());
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to