Changeset 246350 in webkit


Ignore:
Timestamp:
Jun 12, 2019 6:43:37 AM (5 years ago)
Author:
Carlos Garcia Campos
Message:

[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.
Location:
trunk
Files:
4 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r246349 r246350  
     12019-06-12  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [cairo][SVG] Putting multiple path elements in clippath causes rendering artifacts
     4        https://bugs.webkit.org/show_bug.cgi?id=198701
     5        <rdar://problem/51620347>
     6
     7        Reviewed by Don Olmstead.
     8
     9        * svg/clip-path/clip-hidpi-expected.svg: Added.
     10        * svg/clip-path/clip-hidpi.svg: Added.
     11        * svg/clip-path/clip-opacity-translate-expected.svg: Added.
     12        * svg/clip-path/clip-opacity-translate.svg: Added.
     13
    1142019-06-12  Fujii Hironori  <Hironori.Fujii@sony.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r246348 r246350  
     12019-06-12  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [cairo][SVG] Putting multiple path elements in clippath causes rendering artifacts
     4        https://bugs.webkit.org/show_bug.cgi?id=198701
     5        <rdar://problem/51620347>
     6
     7        Reviewed by Don Olmstead.
     8
     9        We need to save the current transformation matrix at the moment the image mask is set and set it again on
     10        restore right before applying the mask. This patch also creates a pattern for the image mask surface and set its
     11        transformation matrix according to the mask position, so that we don't need to save the mask rectangle too.
     12
     13        Tests: svg/clip-path/clip-hidpi-expected.svg
     14               svg/clip-path/clip-hidpi.svg
     15               svg/clip-path/clip-opacity-translate-expected.svg
     16               svg/clip-path/clip-opacity-translate.svg
     17
     18        * platform/graphics/cairo/PlatformContextCairo.cpp:
     19        (WebCore::PlatformContextCairo::restore):
     20        (WebCore::PlatformContextCairo::pushImageMask):
     21
    1222019-06-11  Wenson Hsieh  <wenson_hsieh@apple.com>
    223
  • trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp

    r246309 r246350  
    3131#if USE(CAIRO)
    3232
    33 #include "CairoUtilities.h"
    34 #include "Gradient.h"
    35 #include "GraphicsContext.h"
    36 #include "Pattern.h"
    3733#include <cairo.h>
    3834
    3935namespace WebCore {
    40 
    41 // In Cairo image masking is immediate, so to emulate image clipping we must save masking
    42 // details as part of the context state and apply them during platform restore.
    43 class ImageMaskInformation {
    44 public:
    45     void update(cairo_surface_t* maskSurface, const FloatRect& maskRect)
    46     {
    47         m_maskSurface = maskSurface;
    48         m_maskRect = maskRect;
    49     }
    50 
    51     bool isValid() const { return m_maskSurface; }
    52     cairo_surface_t* maskSurface() const { return m_maskSurface.get(); }
    53     const FloatRect& maskRect() const { return m_maskRect; }
    54 
    55 private:
    56     RefPtr<cairo_surface_t> m_maskSurface;
    57     FloatRect m_maskRect;
    58 };
    59 
    6036
    6137// Encapsulates the additional painting state information we store for each
     
    6541    State() = default;
    6642
    67     ImageMaskInformation m_imageMaskInformation;
     43    struct {
     44        RefPtr<cairo_pattern_t> pattern;
     45        cairo_matrix_t matrix;
     46    } m_mask;
    6847};
    6948
     
    7756void PlatformContextCairo::restore()
    7857{
    79     const ImageMaskInformation& maskInformation = m_state->m_imageMaskInformation;
    80     if (maskInformation.isValid()) {
    81         const FloatRect& maskRect = maskInformation.maskRect();
     58    if (m_state->m_mask.pattern) {
    8259        cairo_pop_group_to_source(m_cr.get());
    83         cairo_mask_surface(m_cr.get(), maskInformation.maskSurface(), maskRect.x(), maskRect.y());
     60
     61        cairo_matrix_t matrix;
     62        cairo_get_matrix(m_cr.get(), &matrix);
     63        cairo_set_matrix(m_cr.get(), &m_state->m_mask.matrix);
     64        cairo_mask(m_cr.get(), m_state->m_mask.pattern.get());
     65        cairo_set_matrix(m_cr.get(), &matrix);
    8466    }
    8567
     
    10688    // since we actually apply the mask in restorePlatformState.
    10789    ASSERT(!m_stateStack.isEmpty());
    108     m_state->m_imageMaskInformation.update(surface, rect);
     90    m_state->m_mask.pattern = adoptRef(cairo_pattern_create_for_surface(surface));
     91    cairo_get_matrix(m_cr.get(), &m_state->m_mask.matrix);
    10992
    110     // Cairo doesn't support the notion of an image clip, so we push a group here
    111     // and then paint it to the surface with an image mask (which is an immediate
    112     // operation) during restorePlatformState.
     93    cairo_matrix_t matrix;
     94    cairo_matrix_init_translate(&matrix, -rect.x(), -rect.y());
     95    cairo_pattern_set_matrix(m_state->m_mask.pattern.get(), &matrix);
     96
    11397    cairo_push_group(m_cr.get());
    11498}
Note: See TracChangeset for help on using the changeset viewer.