From 3db3aca9c1a404c2eee787d4d883fd11261cd935 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 23 Apr 2014 11:48:07 +0200 Subject: [PATCH] Bug 997735 - Invalidate when reflowing SVG containers. r=roc Without this patch, when changing the x/y attributes of svg:use, innerSVG and foreignObject, we were relying on the transform changes of the children to trigger the right invalidations. However, changes to those attributes can also change the filter region. And there's a difference between moving children in a fixed filter region and moving the filter region along with the children: In the first case, we wouldn't need to invalidate anything outside the old filter region, because those parts of the children would be clipped away anyway. But when the filter region changes, we need to invalidate both the old and the new filter region. Also, when the filter has primitives without inputs, e.g. flood or turbulence, the filtered frame needs to be invalidate even if it has no children. --- layout/svg/nsSVGForeignObjectFrame.cpp | 6 ++++++ layout/svg/nsSVGInnerSVGFrame.cpp | 7 +++++++ layout/svg/nsSVGUseFrame.cpp | 7 +++++++ 3 files changed, 20 insertions(+) diff --git a/layout/svg/nsSVGForeignObjectFrame.cpp b/layout/svg/nsSVGForeignObjectFrame.cpp index 44872728b990..c562b05204ed 100644 --- a/layout/svg/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/nsSVGForeignObjectFrame.cpp @@ -382,6 +382,12 @@ nsSVGForeignObjectFrame::ReflowSVG() nsSVGEffects::UpdateEffects(this); } + // If we have a filter, we need to invalidate ourselves because filter + // output can change even if none of our descendants need repainting. + if (StyleSVGReset()->HasFilters()) { + InvalidateFrame(); + } + // TODO: once we support |overflow:visible| on foreignObject, then we will // need to take account of our descendants here. nsRect overflow = nsRect(nsPoint(0,0), mRect.Size()); diff --git a/layout/svg/nsSVGInnerSVGFrame.cpp b/layout/svg/nsSVGInnerSVGFrame.cpp index c377679256a6..0ac21d3116f2 100644 --- a/layout/svg/nsSVGInnerSVGFrame.cpp +++ b/layout/svg/nsSVGInnerSVGFrame.cpp @@ -102,6 +102,13 @@ nsSVGInnerSVGFrame::ReflowSVG() mRect = nsLayoutUtils::RoundGfxRectToAppRect( gfxRect(x, y, width, height), PresContext()->AppUnitsPerCSSPixel()); + + // If we have a filter, we need to invalidate ourselves because filter + // output can change even if none of our descendants need repainting. + if (StyleSVGReset()->HasFilters()) { + InvalidateFrame(); + } + nsSVGInnerSVGFrameBase::ReflowSVG(); } diff --git a/layout/svg/nsSVGUseFrame.cpp b/layout/svg/nsSVGUseFrame.cpp index c9a22107c2b3..7c628513edaf 100644 --- a/layout/svg/nsSVGUseFrame.cpp +++ b/layout/svg/nsSVGUseFrame.cpp @@ -187,6 +187,13 @@ nsSVGUseFrame::ReflowSVG() mRect.MoveTo(nsLayoutUtils::RoundGfxRectToAppRect( gfxRect(x, y, 0.0, 0.0), PresContext()->AppUnitsPerCSSPixel()).TopLeft()); + + // If we have a filter, we need to invalidate ourselves because filter + // output can change even if none of our descendants need repainting. + if (StyleSVGReset()->HasFilters()) { + InvalidateFrame(); + } + nsSVGUseFrameBase::ReflowSVG(); }