Skip to content

Commit

Permalink
REGRESSION(265135@main): CSS filter is not applied on SVG element
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=260152
rdar://114204485

Reviewed by Said Abou-Hallawa.

Before 265135@main, an SVG root with a filter specified as presentation attribute
(e.g: <svg filter="...">) was filtered twice instead of once: once by SVGRenderingContext,
and another by RenderLayer. 265135@main attempted to fix this by instructing RenderLayer
not to apply filters when rendering an SVG root. This caused a regression where an SVG root
with a filter specified using CSS filter property is not filtered, because SVGRenderingContext
is not responsible for apply CSS filters, and RenderLayer refuses to filter because it's an
SVG root. Fix the previous attempt by fixing SVGRenderingContext to not filter when rendering
an SVG root, so RenderLayer is now solely responsible for filtering SVG roots.

Test: LayoutTests/svg/filters/css-filter-specified-on-svg-root.html

* LayoutTests/svg/filters/css-filter-specified-on-svg-root-expected.html: Added.
* LayoutTests/svg/filters/css-filter-specified-on-svg-root.html: Added.
* Source/WebCore/rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintsWithFilters const):
(WebCore::RenderLayer::calculateClipRects const):
* Source/WebCore/rendering/svg/SVGRenderingContext.cpp:
(WebCore::SVGRenderingContext::prepareToRenderSVGContent):

Canonical link: https://commits.webkit.org/267236@main
  • Loading branch information
tuankiet65 committed Aug 24, 2023
1 parent 7e52ab8 commit d4e801e
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<style>
#rect {
width: 100px;
height: 100px;
background-color: red;
filter: drop-shadow(10px 10px 0px green);
}
</style>

<div id="rect"></div>
11 changes: 11 additions & 0 deletions LayoutTests/svg/filters/css-filter-specified-on-svg-root.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<style>
svg {
width: 100px;
height: 100px;
filter: drop-shadow(10px 10px 0px green);
}
</style>

<svg width="100" height="100">
<rect width="100" height="100" fill="red"/>
</svg>
10 changes: 3 additions & 7 deletions Source/WebCore/rendering/RenderLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -886,11 +886,6 @@ bool RenderLayer::paintsWithFilters() const
if (!hasFilter())
return false;

// The SVG rendering codepath should've already applied the filter to the SVG root,
// so do not apply the filter again.
if (renderer().isSVGRootOrLegacySVGRoot())
return false;

if (RenderLayerFilters::isIdentity(renderer()))
return false;

Expand Down Expand Up @@ -5584,8 +5579,9 @@ void RenderLayer::updateFiltersAfterStyleChange(StyleDifference diff, const Rend
return;
}

// Add the filter as a client to this renderer.
if (renderer().style().filter().hasReferenceFilter()) {
// Add the filter as a client to this renderer, unless we are a RenderLayer accommodating
// an SVG. In that case it takes care of its own resource management for filters.
if (renderer().style().filter().hasReferenceFilter() && !renderer().isSVGRootOrLegacySVGRoot()) {
ensureLayerFilters();
m_filters->updateReferenceFilterClients(renderer().style().filter());
} else if (m_filters)
Expand Down
4 changes: 3 additions & 1 deletion Source/WebCore/rendering/svg/SVGRenderingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderElement& renderer, Pai
return;
}

if (!isRenderingMask) {
// SVG roots with filters specified (using CSS or SVG presentation attributes) are applied
// as CSSFilter by RenderLayer, so don't reapply the filter here.
if (!isRenderingMask && !renderer.isSVGRootOrLegacySVGRoot()) {
m_filter = resources->filter();
if (m_filter && !m_filter->isIdentity()) {
m_savedContext = &m_paintInfo->context();
Expand Down

0 comments on commit d4e801e

Please sign in to comment.