nsRect nsSVGUtils::FindFilterInvalidation(nsIFrame *aFrame, const nsRect& aRect) { PRInt32 appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel(); nsIntRect rect = aRect.ToOutsidePixels(appUnitsPerDevPixel); while (aFrame) { if (aFrame->GetStateBits() & NS_STATE_IS_OUTER_SVG) break; nsSVGFilterFrame *filter = nsSVGEffects::GetFilterFrame(aFrame); if (filter) { // When we are under AttributeChanged, we can no longer get the old bbox // by calling GetBBox(), and we need that to set up the filter region // with the correct position. :-( //rect = filter->GetInvalidationBBox(aFrame, rect); // XXX [perf] As a horrible workaround, for now we just invalidate the // entire area of the nearest viewport establishing frame that doesnt // have overflow:visible. See bug 463939. nsSVGDisplayContainerFrame* viewportFrame = GetNearestSVGViewport(aFrame); while (viewportFrame && !viewportFrame->GetStyleDisplay()->IsScrollableOverflow()) { viewportFrame = GetNearestSVGViewport(viewportFrame); } if (!viewportFrame) { viewportFrame = GetOuterSVGFrame(aFrame); } if (viewportFrame->GetType() == nsGkAtoms::svgOuterSVGFrame) { nsRect r = viewportFrame->GetVisualOverflowRect(); // GetOverflowRect is relative to our border box, but we need it // relative to our content box. r.MoveBy(viewportFrame->GetPosition() - viewportFrame->GetContentRect().TopLeft()); return r; } NS_ASSERTION(viewportFrame->GetType() == nsGkAtoms::svgInnerSVGFrame, "Wrong frame type"); nsSVGInnerSVGFrame* innerSvg = do_QueryFrame(static_cast<nsIFrame*>(viewportFrame)); nsSVGDisplayContainerFrame* innerSvgParent = do_QueryFrame(viewportFrame->GetParent()); float x, y, width, height; static_cast<nsSVGSVGElement*>(innerSvg->GetContent())-> GetAnimatedLengthValues(&x, &y, &width, &height, nsnull); gfxRect bounds = nsSVGUtils::GetCanvasTM(innerSvgParent). TransformBounds(gfxRect(x, y, width, height)); bounds.RoundOut(); nsIntRect r; if (gfxUtils::GfxRectToIntRect(bounds, &r)) { rect = r; } else { NS_NOTREACHED("Not going to invalidate the correct area"); } aFrame = viewportFrame; } aFrame = aFrame->GetParent(); } nsRect r = rect.ToAppUnits(appUnitsPerDevPixel); if (aFrame) { NS_ASSERTION(aFrame->GetStateBits() & NS_STATE_IS_OUTER_SVG, "outer SVG frame expected"); r.MoveBy(aFrame->GetContentRect().TopLeft() - aFrame->GetPosition()); } return r; }