Changeset 288183 in webkit


Ignore:
Timestamp:
Jan 19, 2022 12:37:08 AM (6 months ago)
Author:
Said Abou-Hallawa
Message:

filterRegion and outsets of referenced SVG filter are calculated incorrectly
https://bugs.webkit.org/show_bug.cgi?id=235338

Reviewed by Darin Adler.

Source/WebCore:

Calculate the filterRegion of the referenced SVGFilter by calling
SVGLengthContext::resolveRectangle() given the targetBoundingBox of the
CSSFilter.

There is no need to set the filterRegion of the referenced SVG filter
from CSSFilter::setFilterRegion() since its filterRegion is the union
of the filterRegions all its referenced SVGFilters.

Calculate the outsets of the SVGFilter by looping through its expression
of FilterEffects.

Test: css3/filters/reference-filter-outsets.html

  • platform/graphics/filters/FEDropShadow.cpp:

(WebCore::FEDropShadow::outsets const):

  • platform/graphics/filters/FEDropShadow.h:
  • platform/graphics/filters/FEGaussianBlur.cpp:

(WebCore::FEGaussianBlur::outsets const):

  • platform/graphics/filters/FEGaussianBlur.h:
  • platform/graphics/filters/FEOffset.cpp:

(WebCore::FEOffset::outsets const):

  • platform/graphics/filters/FEOffset.h:
  • platform/graphics/filters/Filter.h:
  • platform/graphics/filters/FilterFunction.h:

(WebCore::FilterFunction::outsets const):

  • rendering/CSSFilter.cpp:

(WebCore::createSVGFilter):
(WebCore::CSSFilter::setFilterRegion):
(WebCore::CSSFilter::outsets const):

  • rendering/CSSFilter.h:
  • rendering/RenderLayerFilters.cpp:

(WebCore::RenderLayerFilters::beginFilterEffect):

  • svg/graphics/filters/SVGFilter.cpp:

(WebCore::SVGFilter::create):
(WebCore::SVGFilter::outsets const):
(WebCore::SVGFilter::lastEffect const): Deleted.

  • svg/graphics/filters/SVGFilter.h:

LayoutTests:

  • css3/filters/reference-filter-outsets-expected.html: Added.
  • css3/filters/reference-filter-outsets.html: Added.
  • css3/filters/reference-filter-set-filter-regions-expected.html:
  • css3/filters/reference-filter-set-filter-regions.html:

The original expected page is wrong. To test the referenced SVG filter
correctly, the <div> element needs to move such that all its outsets are
not truncated.

  • platform/win/TestExpectations:
Location:
trunk
Files:
2 added
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r288182 r288183  
     12022-01-19  Said Abou-Hallawa  <said@apple.com>
     2
     3        filterRegion and outsets of referenced SVG filter are calculated incorrectly
     4        https://bugs.webkit.org/show_bug.cgi?id=235338
     5
     6        Reviewed by Darin Adler.
     7
     8        * css3/filters/reference-filter-outsets-expected.html: Added.
     9        * css3/filters/reference-filter-outsets.html: Added.
     10
     11        * css3/filters/reference-filter-set-filter-regions-expected.html:
     12        * css3/filters/reference-filter-set-filter-regions.html:
     13        The original expected page is wrong. To test the referenced SVG filter
     14        correctly, the <div> element needs to move such that all its outsets are
     15        not truncated.
     16
     17        * platform/win/TestExpectations:
     18
    1192022-01-18  Jon Lee  <jonlee554@gmail.com>
    220
  • trunk/LayoutTests/css3/filters/reference-filter-set-filter-regions-expected.html

    r235644 r288183  
    22    <style>
    33        .box {
    4           width: 200px;
    5           height: 200px;
     4          position: absolute;
     5          left: 20px;
     6          top: 20px;
     7          width: 240px;
     8          height: 240px;
    69          background-color: green;
    710        }
  • trunk/LayoutTests/css3/filters/reference-filter-set-filter-regions.html

    r287982 r288183  
    22    <style>
    33        .box {
     4          position: absolute;
     5          left: 40px;
     6          top: 40px;
    47          width: 200px;
    58          height: 200px;
  • trunk/LayoutTests/platform/win/TestExpectations

    r288070 r288183  
    128128webkit.org/b/74716 css3/masking/clip-path-filter.html [ Skip ]
    129129webkit.org/b/74716 css3/filters/backdrop [ Skip ]
     130webkit.org/b/74716 css3/filters/reference-filter-set-filter-regions.html [ Skip ]
    130131
    131132# platformLayerTreeAsText is only implemented for Cocoa ports.
  • trunk/Source/WebCore/ChangeLog

    r288181 r288183  
     12022-01-19  Said Abou-Hallawa  <said@apple.com>
     2
     3        filterRegion and outsets of referenced SVG filter are calculated incorrectly
     4        https://bugs.webkit.org/show_bug.cgi?id=235338
     5
     6        Reviewed by Darin Adler.
     7
     8        Calculate the filterRegion of the referenced SVGFilter by calling
     9        SVGLengthContext::resolveRectangle() given the targetBoundingBox of the
     10        CSSFilter.
     11
     12        There is no need to set the filterRegion of the referenced SVG filter
     13        from CSSFilter::setFilterRegion() since its filterRegion is the union
     14        of the filterRegions all its referenced SVGFilters.
     15
     16        Calculate the outsets of the SVGFilter by looping through its expression
     17        of FilterEffects.
     18
     19        Test: css3/filters/reference-filter-outsets.html
     20
     21        * platform/graphics/filters/FEDropShadow.cpp:
     22        (WebCore::FEDropShadow::outsets const):
     23        * platform/graphics/filters/FEDropShadow.h:
     24        * platform/graphics/filters/FEGaussianBlur.cpp:
     25        (WebCore::FEGaussianBlur::outsets const):
     26        * platform/graphics/filters/FEGaussianBlur.h:
     27        * platform/graphics/filters/FEOffset.cpp:
     28        (WebCore::FEOffset::outsets const):
     29        * platform/graphics/filters/FEOffset.h:
     30        * platform/graphics/filters/Filter.h:
     31        * platform/graphics/filters/FilterFunction.h:
     32        (WebCore::FilterFunction::outsets const):
     33        * rendering/CSSFilter.cpp:
     34        (WebCore::createSVGFilter):
     35        (WebCore::CSSFilter::setFilterRegion):
     36        (WebCore::CSSFilter::outsets const):
     37        * rendering/CSSFilter.h:
     38        * rendering/RenderLayerFilters.cpp:
     39        (WebCore::RenderLayerFilters::beginFilterEffect):
     40        * svg/graphics/filters/SVGFilter.cpp:
     41        (WebCore::SVGFilter::create):
     42        (WebCore::SVGFilter::outsets const):
     43        (WebCore::SVGFilter::lastEffect const): Deleted.
     44        * svg/graphics/filters/SVGFilter.h:
     45
    1462022-01-18  Sam Weinig  <weinig@apple.com>
    247
  • trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp

    r286589 r288183  
    6262}
    6363
    64 IntOutsets FEDropShadow::outsets() const
     64IntOutsets FEDropShadow::outsets(const Filter&) const
    6565{
    6666    IntSize outsetSize = FEGaussianBlur::calculateOutsetSize({ m_stdX, m_stdY });
  • trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.h

    r286589 r288183  
    5656    FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override;
    5757
    58     IntOutsets outsets() const override;
     58    IntOutsets outsets(const Filter&) const override;
    5959
    6060    std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const override;
  • trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp

    r286589 r288183  
    121121}
    122122
    123 IntOutsets FEGaussianBlur::outsets() const
     123IntOutsets FEGaussianBlur::outsets(const Filter& filter) const
    124124{
    125     IntSize outsetSize = calculateOutsetSize({ m_stdX, m_stdY });
     125    IntSize outsetSize = calculateOutsetSize(filter.resolvedSize({ m_stdX, m_stdY }));
    126126    return { outsetSize.height(), outsetSize.width(), outsetSize.height(), outsetSize.width() };
    127127}
  • trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h

    r286589 r288183  
    5353    FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override;
    5454
    55     IntOutsets outsets() const override;
     55    IntOutsets outsets(const Filter&) const override;
    5656
    5757    bool resultIsAlphaImage(const FilterImageVector& inputs) const override;
  • trunk/Source/WebCore/platform/graphics/filters/FEOffset.cpp

    r286589 r288183  
    6161}
    6262
     63IntOutsets FEOffset::outsets(const Filter& filter) const
     64{
     65    auto offset = expandedIntSize(filter.resolvedSize({ m_dx, m_dy }));
     66
     67    IntOutsets outsets;
     68    if (offset.height() < 0)
     69        outsets.setTop(-offset.height());
     70    else
     71        outsets.setBottom(offset.height());
     72    if (offset.width() < 0)
     73        outsets.setLeft(-offset.width());
     74    else
     75        outsets.setRight(offset.width());
     76
     77    return outsets;
     78}
     79
    6380bool FEOffset::resultIsAlphaImage(const FilterImageVector& inputs) const
    6481{
  • trunk/Source/WebCore/platform/graphics/filters/FEOffset.h

    r286589 r288183  
    4545    FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override;
    4646
     47    IntOutsets outsets(const Filter&) const override;
     48
    4749    bool resultIsAlphaImage(const FilterImageVector& inputs) const override;
    4850
  • trunk/Source/WebCore/platform/graphics/filters/Filter.h

    r287982 r288183  
    3737class Filter : public FilterFunction {
    3838    using FilterFunction::apply;
     39    using FilterFunction::outsets;
    3940
    4041public:
     
    6667    bool clampFilterRegionIfNeeded();
    6768
     69    virtual IntOutsets outsets() const = 0;
    6870    virtual RefPtr<FilterImage> apply(FilterImage* sourceImage, FilterResults&) = 0;
    6971    WEBCORE_EXPORT RefPtr<FilterImage> apply(ImageBuffer* sourceImage, const FloatRect& sourceImageRect, FilterResults&);
  • trunk/Source/WebCore/platform/graphics/filters/FilterFunction.h

    r287782 r288183  
    9999
    100100    virtual RefPtr<FilterImage> apply(const Filter&, FilterImage&, FilterResults&) { return nullptr; }
    101     virtual IntOutsets outsets() const { return { }; }
     101    virtual IntOutsets outsets(const Filter&) const { return { }; }
    102102
    103103    virtual WTF::TextStream& externalRepresentation(WTF::TextStream&, FilterRepresentation = FilterRepresentation::TestOutput) const = 0;
  • trunk/Source/WebCore/rendering/CSSFilter.cpp

    r287982 r288183  
    3333#include "FEGaussianBlur.h"
    3434#include "FilterOperations.h"
    35 #include "GraphicsContext.h"
    36 #include "LengthFunctions.h"
    3735#include "Logging.h"
    3836#include "ReferencedSVGResources.h"
     
    236234    }
    237235
     236    auto filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnits(), targetBoundingBox);
     237
    238238    SVGFilterBuilder builder;
    239     return SVGFilter::create(*filterElement, builder, filter.renderingMode(), filter.filterScale(), filter.clipOperation(), targetBoundingBox, targetBoundingBox);
     239    return SVGFilter::create(*filterElement, builder, filter.renderingMode(), filter.filterScale(), filter.clipOperation(), filterRegion, targetBoundingBox);
    240240}
    241241
     
    372372{
    373373    Filter::setFilterRegion(filterRegion);
    374 
    375     for (auto& function : m_functions) {
    376         if (function->isSVGFilter())
    377             downcast<SVGFilter>(function.ptr())->setFilterRegion(filterRegion);
    378     }
    379 
    380374    clampFilterRegionIfNeeded();
    381375}
     
    390384
    391385    for (auto& function : m_functions)
    392         m_outsets += function->outsets();
     386        m_outsets += function->outsets(*this);
    393387    return m_outsets;
    394388}
  • trunk/Source/WebCore/rendering/CSSFilter.h

    r287982 r288183  
    3131namespace WebCore {
    3232
    33 class FilterEffect;
    3433class FilterOperations;
    35 class GraphicsContext;
    36 class ReferenceFilterOperation;
    3734class RenderElement;
    3835class SourceGraphic;
  • trunk/Source/WebCore/rendering/RenderLayerFilters.cpp

    r287829 r288183  
    165165    // For CSSFilter, filterRegion = targetBoundingBox + filter->outsets()
    166166    auto filterRegion = targetBoundingBox;
    167     if (filter.hasFilterThatMovesPixels()) {
     167    if (filter.hasFilterThatMovesPixels())
    168168        filterRegion += filter.outsets();
    169         filterRegion.intersect(filterBoxRect);
    170     }
    171169
    172170    if (filterRegion.isEmpty())
  • trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp

    r287892 r288183  
    5353        filter->setRenderingMode(RenderingMode::Unaccelerated);
    5454#endif
    55 
    5655    return filter;
    5756}
     
    9796}
    9897#endif
    99 
    100 RefPtr<FilterEffect> SVGFilter::lastEffect() const
    101 {
    102     if (m_expression.isEmpty())
    103         return nullptr;
    104     return m_expression.last().effect.ptr();
    105 }
    10698
    10799FilterEffectVector SVGFilter::effectsOfType(FilterFunction::Type filterType) const
     
    162154IntOutsets SVGFilter::outsets() const
    163155{
    164     ASSERT(lastEffect());
    165     return lastEffect()->outsets();
     156    IntOutsets outsets;
     157    for (auto& term : m_expression)
     158        outsets += term.effect->outsets(*this);
     159    return outsets;
    166160}
    167161
  • trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h

    r287982 r288183  
    5757    void setExpression(SVGFilterExpression&& expression) { m_expression = WTFMove(expression); }
    5858
    59     RefPtr<FilterEffect> lastEffect() const;
    60 
    6159#if USE(CORE_IMAGE)
    6260    bool supportsCoreImageRendering() const final;
     
    6563
    6664    RefPtr<FilterImage> apply(const Filter&, FilterImage& sourceImage, FilterResults&) final;
     65
     66    IntOutsets outsets(const Filter&) const final { return outsets(); }
    6767    IntOutsets outsets() const final;
    6868
Note: See TracChangeset for help on using the changeset viewer.