SVGBBox nsSVGDisplayContainerFrame::GetBBoxContribution( const gfxMatrix &aToBBoxUserspace, uint32_t aFlags) { SVGBBox bboxUnion; nsIFrame* kid = mFrames.FirstChild(); while (kid) { nsISVGChildFrame* svgKid = do_QueryFrame(kid); if (svgKid) { gfxMatrix transform = aToBBoxUserspace; nsIContent *content = kid->GetContent(); if (content->IsSVG()) { transform = static_cast<nsSVGElement*>(content)-> PrependLocalTransformsTo(aToBBoxUserspace); } // We need to include zero width/height vertical/horizontal lines, so we have // to use UnionEdges. bboxUnion.UnionEdges(svgKid->GetBBoxContribution(transform, aFlags)); } kid = kid->GetNextSibling(); } return bboxUnion; }
SVGBBox nsSVGDisplayContainerFrame::GetBBoxContribution( const Matrix &aToBBoxUserspace, uint32_t aFlags) { SVGBBox bboxUnion; nsIFrame* kid = mFrames.FirstChild(); while (kid) { nsIContent *content = kid->GetContent(); nsISVGChildFrame* svgKid = do_QueryFrame(kid); // content could be a XUL element so check for an SVG element before casting if (svgKid && (!content->IsSVG() || static_cast<const nsSVGElement*>(content)->HasValidDimensions())) { gfxMatrix transform = gfx::ThebesMatrix(aToBBoxUserspace); if (content->IsSVG()) { transform = static_cast<nsSVGElement*>(content)-> PrependLocalTransformsTo(transform); } // We need to include zero width/height vertical/horizontal lines, so we have // to use UnionEdges. bboxUnion.UnionEdges(svgKid->GetBBoxContribution(gfx::ToMatrix(transform), aFlags)); } kid = kid->GetNextSibling(); } return bboxUnion; }
SVGBBox nsSVGMarkerFrame::GetMarkBBoxContribution(const gfxMatrix &aToBBoxUserspace, uint32_t aFlags, nsSVGPathGeometryFrame *aMarkedFrame, const nsSVGMark *aMark, float aStrokeWidth) { SVGBBox bbox; // If the flag is set when we get here, it means this marker frame // has already been used in calculating the current mark bbox, and // the document has a marker reference loop. if (mInUse) return bbox; AutoMarkerReferencer markerRef(this, aMarkedFrame); SVGMarkerElement *content = static_cast<SVGMarkerElement*>(mContent); const nsSVGViewBoxRect viewBox = content->GetViewBoxRect(); if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) { return bbox; } mStrokeWidth = aStrokeWidth; mX = aMark->x; mY = aMark->y; mAutoAngle = aMark->angle; mIsStart = aMark->type == nsSVGMark::eStart; gfxMatrix markerTM = content->GetMarkerTransform(mStrokeWidth, mX, mY, mAutoAngle, mIsStart); gfxMatrix viewBoxTM = content->GetViewBoxTransform(); gfxMatrix tm = viewBoxTM * markerTM * aToBBoxUserspace; for (nsIFrame* kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) { nsISVGChildFrame* child = do_QueryFrame(kid); if (child) { // When we're being called to obtain the invalidation area, we need to // pass down all the flags so that stroke is included. However, once DOM // getBBox() accepts flags, maybe we should strip some of those here? // We need to include zero width/height vertical/horizontal lines, so we have // to use UnionEdges. bbox.UnionEdges(child->GetBBoxContribution(tm, aFlags)); } } return bbox; }
SVGBBox nsSVGInnerSVGFrame::GetBBoxContribution(const Matrix &aToBBoxUserspace, uint32_t aFlags) { // XXXjwatt It seems like authors would want the result to be clipped by the // viewport we establish if IsScrollableOverflow() is true. We should // consider doing that. See bug 1350755. SVGBBox bbox; if (aFlags & nsSVGUtils::eForGetClientRects) { // XXXjwatt For consistency with the old code this code includes the // viewport we establish in the result, but only includes the bounds of our // descendants if they are not clipped to that viewport. However, this is // both inconsistent with Chrome and with the specs. See bug 1350755. // Ideally getClientRects/getBoundingClientRect should be consistent with // getBBox. float x, y, w, h; static_cast<SVGSVGElement*>(mContent)-> GetAnimatedLengthValues(&x, &y, &w, &h, nullptr); if (w < 0.0f) w = 0.0f; if (h < 0.0f) h = 0.0f; Rect viewport(x, y, w, h); bbox = aToBBoxUserspace.TransformBounds(viewport); if (StyleDisplay()->IsScrollableOverflow()) { return bbox; } // Else we're not clipping to our viewport so we fall through and include // the bounds of our children. } SVGBBox descendantsBbox = nsSVGDisplayContainerFrame::GetBBoxContribution(aToBBoxUserspace, aFlags); bbox.UnionEdges(descendantsBbox); return bbox; }