bool SVGLayoutSupport::mapToVisualRectInAncestorSpace( const LayoutObject& object, const LayoutBoxModelObject* ancestor, const FloatRect& localPaintInvalidationRect, LayoutRect& resultRect, VisualRectFlags visualRectFlags) { AffineTransform rootBorderBoxTransform; const LayoutSVGRoot& svgRoot = computeTransformToSVGRoot(object, rootBorderBoxTransform); resultRect = transformPaintInvalidationRect(object, rootBorderBoxTransform, localPaintInvalidationRect); // Apply initial viewport clip. if (svgRoot.shouldApplyViewportClip()) { LayoutRect clipRect(svgRoot.overflowClipRect(LayoutPoint())); if (visualRectFlags & EdgeInclusive) { if (!resultRect.inclusiveIntersect(clipRect)) return false; } else { resultRect.intersect(clipRect); } } return svgRoot.mapToVisualRectInAncestorSpace(ancestor, resultRect, visualRectFlags); }
void SVGLayoutSupport::mapAncestorToLocal(const LayoutObject& object, const LayoutBoxModelObject* ancestor, TransformState& transformState) { // |object| is either a LayoutSVGModelObject or a LayoutSVGBlock here. In // the former case, |object| can never be an ancestor while in the latter // the caller is responsible for doing the ancestor check. Because of this, // computing the transform to the SVG root is always what we want to do here. ASSERT(ancestor != &object); ASSERT(object.isSVGContainer() || object.isSVGShape() || object.isSVGImage() || object.isSVGText() || object.isSVGForeignObject()); AffineTransform localToSVGRoot; const LayoutSVGRoot& svgRoot = computeTransformToSVGRoot(object, localToSVGRoot); MapCoordinatesFlags mode = UseTransforms | ApplyContainerFlip; svgRoot.mapAncestorToLocal(ancestor, transformState, mode); transformState.applyTransform(localToSVGRoot); }