author | Markus Stange <mstange@themasta.com> |
Wed, 23 Apr 2014 11:47:42 +0200 | |
changeset 179748 | fcd9986a84c58232fdf6a2f8cb6ee994e5be3612 |
parent 179747 | 77a55da6682761f7d7284b671f56d9ce2ff7499a |
child 179749 | f5bd85e791c3f9d61e4da19de4a831f30cbe7c55 |
push id | 26639 |
push user | ryanvm@gmail.com |
push date | Wed, 23 Apr 2014 20:42:51 +0000 |
treeherder | mozilla-central@ed0236a51ed3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc |
bugs | 997735 |
milestone | 31.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
layout/svg/nsSVGUtils.cpp | file | annotate | diff | comparison | revisions | |
layout/svg/nsSVGUtils.h | file | annotate | diff | comparison | revisions |
--- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -884,26 +884,57 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, ui !static_cast<const nsSVGElement*>(content)->HasValidDimensions()) { return bbox; } gfxMatrix matrix; if (aFrame->GetType() == nsGkAtoms::svgForeignObjectFrame) { // The spec says getBBox "Returns the tight bounding box in *current user // space*". So we should really be doing this for all elements, but that // needs investigation to check that we won't break too much content. + // NOTE: When changing this to apply to other frame types, make sure to + // also update nsSVGUtils::FrameSpaceInCSSPxToUserSpaceOffset. NS_ABORT_IF_FALSE(content->IsSVG(), "bad cast"); nsSVGElement *element = static_cast<nsSVGElement*>(content); matrix = element->PrependLocalTransformsTo(matrix, nsSVGElement::eChildToUserSpace); } return svg->GetBBoxContribution(ToMatrix(matrix), aFlags).ToThebesRect(); } return nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(aFrame); } +gfxPoint +nsSVGUtils::FrameSpaceInCSSPxToUserSpaceOffset(nsIFrame *aFrame) +{ + if (!(aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) { + // The user space for non-SVG frames is defined as the bounding box of the + // frame's border-box rects over all continuations. + return gfxPoint(); + } + + // Leaf frames apply their own offset inside their user space. + if (aFrame->IsFrameOfType(nsIFrame::eSVGGeometry) || + aFrame->IsSVGText()) { + return nsLayoutUtils::RectToGfxRect(aFrame->GetRect(), + nsPresContext::AppUnitsPerCSSPixel()).TopLeft(); + } + + // For foreignObject frames, nsSVGUtils::GetBBox applies their local + // transform, so we need to do the same here. + if (aFrame->GetType() == nsGkAtoms::svgForeignObjectFrame) { + gfxMatrix transform = static_cast<nsSVGElement*>(aFrame->GetContent())-> + PrependLocalTransformsTo(gfxMatrix(), + nsSVGElement::eChildToUserSpace); + NS_ASSERTION(!transform.HasNonTranslation(), "we're relying on this being an offset-only transform"); + return transform.GetTranslation(); + } + + return gfxPoint(); +} + gfxRect nsSVGUtils::GetRelativeRect(uint16_t aUnits, const nsSVGLength2 *aXYWH, const gfxRect &aBBox, nsIFrame *aFrame) { float x, y, width, height; if (aUnits == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { x = aBBox.X() + ObjectSpace(aBBox, &aXYWH[0]); y = aBBox.Y() + ObjectSpace(aBBox, &aXYWH[1]);
--- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -400,16 +400,26 @@ public: }; /** * Get the SVG bbox (the SVG spec's simplified idea of bounds) of aFrame in * aFrame's userspace. */ static gfxRect GetBBox(nsIFrame *aFrame, uint32_t aFlags = eBBoxIncludeFillGeometry); + /* + * "User space" is the space that the frame's BBox (as calculated by + * nsSVGUtils::GetBBox) is in. "Frame space" is the space that has its origin + * at the top left of the union of the frame's border-box rects over all + * continuations. + * This function returns the offset one needs to add to something in frame + * space in order to get its coordinates in user space. + */ + static gfxPoint FrameSpaceInCSSPxToUserSpaceOffset(nsIFrame *aFrame); + /** * Convert a userSpaceOnUse/objectBoundingBoxUnits rectangle that's specified * using four nsSVGLength2 values into a user unit rectangle in user space. * * @param aXYWH pointer to 4 consecutive nsSVGLength2 objects containing * the x, y, width and height values in that order * @param aBBox the bounding box of the object the rect is relative to; * may be null if aUnits is not SVG_UNIT_TYPE_OBJECTBOUNDINGBOX