Commit 877dcbb8 authored by Chris Harrelson's avatar Chris Harrelson Committed by Commit Bot

Apply masks to <foreignObject>

An earlier CL stopped applying mask state, but this is incorrect,
as masks need to paint in the correct property tree state to apply.

The new CL applies the same logic as for the root <svg> element, which
paints in the same way as <foreignObject>

Bug: 998553

Change-Id: Ib8cea27e16063f459d9719336d4c0fac63589759
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1783144Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#693215}
parent b26b8d3b
...@@ -77,9 +77,12 @@ bool ScopedSVGPaintState::ApplyClipMaskAndFilterIfNecessary() { ...@@ -77,9 +77,12 @@ bool ScopedSVGPaintState::ApplyClipMaskAndFilterIfNecessary() {
return true; return true;
} }
bool is_svg_root = object_.IsSVGRoot(); // LayoutSVGRoot and LayoutSVGForeignObject always have a self-painting
if (is_svg_root) { // PaintLayer (hence comments below about PaintLayerPainter).
// Layer takes care of root opacity and blend mode. bool is_svg_root_or_foreign_object =
object_.IsSVGRoot() || object_.IsSVGForeignObject();
if (is_svg_root_or_foreign_object) {
// PaintLayerPainter takes care of opacity and blend mode.
DCHECK(object_.HasLayer() || !(object_.StyleRef().HasOpacity() || DCHECK(object_.HasLayer() || !(object_.StyleRef().HasOpacity() ||
object_.StyleRef().HasBlendMode() || object_.StyleRef().HasBlendMode() ||
object_.StyleRef().ClipPath())); object_.StyleRef().ClipPath()));
...@@ -93,8 +96,8 @@ bool ScopedSVGPaintState::ApplyClipMaskAndFilterIfNecessary() { ...@@ -93,8 +96,8 @@ bool ScopedSVGPaintState::ApplyClipMaskAndFilterIfNecessary() {
if (!ApplyMaskIfNecessary(resources)) if (!ApplyMaskIfNecessary(resources))
return false; return false;
if (is_svg_root) { if (is_svg_root_or_foreign_object) {
// Layer takes care of root filter. // PaintLayerPainter takes care of filter.
DCHECK(object_.HasLayer() || !object_.StyleRef().HasFilter()); DCHECK(object_.HasLayer() || !object_.StyleRef().HasFilter());
} else if (!ApplyFilterIfNecessary(resources)) { } else if (!ApplyFilterIfNecessary(resources)) {
return false; return false;
......
...@@ -55,6 +55,10 @@ void SVGForeignObjectPainter::Paint(const PaintInfo& paint_info) { ...@@ -55,6 +55,10 @@ void SVGForeignObjectPainter::Paint(const PaintInfo& paint_info) {
ScopedSVGPaintState paint_state(layout_svg_foreign_object_, ScopedSVGPaintState paint_state(layout_svg_foreign_object_,
paint_info_before_filtering); paint_info_before_filtering);
if (paint_state.GetPaintInfo().phase == PaintPhase::kForeground &&
!paint_state.ApplyClipMaskAndFilterIfNecessary())
return;
BlockPainter(layout_svg_foreign_object_).Paint(paint_info); BlockPainter(layout_svg_foreign_object_).Paint(paint_info);
} }
......
<!doctype HTML>
<div style="width: 32px; height: 32px; background: green; overflow: hidden; border-radius: 50%"></div>
<!doctype HTML>
<title>Tests that an SVG mask applies to a foreignObject element</title>
<link rel="match" href="masked-ref.html">
<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org">
<link rel="help" href="https://svgwg.org/svg2-draft/single-page.html#embedded-ForeignObjectElement"/>
<svg style="display: block">
<foreignObject x="0" y="0" width="32" height="32" mask="url(#circle)">
<div style="width: 32px; height: 32px; background: green"></div>
</foreignObject>
<mask id="circle" maskContentUnits="objectBoundingBox" viewBox="0 0 1 1">
<circle fill="white" cx="0.5" cy="0.5" r="0.5"></circle>
</mask>
</svg>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment