void nsSVGInnerSVGFrame::NotifySVGChanged(uint32_t aFlags) { NS_ABORT_IF_FALSE(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED), "Invalidation logic may need adjusting"); if (aFlags & COORD_CONTEXT_CHANGED) { SVGSVGElement *svg = static_cast<SVGSVGElement*>(mContent); bool xOrYIsPercentage = svg->mLengthAttributes[SVGSVGElement::ATTR_X].IsPercentage() || svg->mLengthAttributes[SVGSVGElement::ATTR_Y].IsPercentage(); bool widthOrHeightIsPercentage = svg->mLengthAttributes[SVGSVGElement::ATTR_WIDTH].IsPercentage() || svg->mLengthAttributes[SVGSVGElement::ATTR_HEIGHT].IsPercentage(); if (xOrYIsPercentage || widthOrHeightIsPercentage) { // Ancestor changes can't affect how we render from the perspective of // any rendering observers that we may have, so we don't need to // invalidate them. We also don't need to invalidate ourself, since our // changed ancestor will have invalidated its entire area, which includes // our area. // For perf reasons we call this before calling NotifySVGChanged() below. nsSVGUtils::ScheduleReflowSVG(this); } // Coordinate context changes affect mCanvasTM if we have a // percentage 'x' or 'y', or if we have a percentage 'width' or 'height' AND // a 'viewBox'. if (!(aFlags & TRANSFORM_CHANGED) && (xOrYIsPercentage || (widthOrHeightIsPercentage && svg->HasViewBox()))) { aFlags |= TRANSFORM_CHANGED; } if (svg->HasViewBox() || !widthOrHeightIsPercentage) { // Remove COORD_CONTEXT_CHANGED, since we establish the coordinate // context for our descendants and this notification won't change its // dimensions: aFlags &= ~COORD_CONTEXT_CHANGED; if (!aFlags) { return; // No notification flags left } } } if (aFlags & TRANSFORM_CHANGED) { // make sure our cached transform matrix gets (lazily) updated mCanvasTM = nullptr; } nsSVGInnerSVGFrameBase::NotifySVGChanged(aFlags); }