From 1a9594b12bbfbdde4af72fc9d259c83117fb42ac Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Thu, 17 Aug 2017 09:52:17 +0800 Subject: [PATCH] Bug 1385745 Part 1 - Add BBoxFlags::eIncludeOnlyCurrentFrameForNonSVGElement to determine whether include all continuations while computing bbox of a html frame. r=cjku,heycam MozReview-Commit-ID: Fx11LjhBcrM --HG-- extra : rebase_source : 6a46553d77f940186d4e7ff2c744b1ccd19e3dad --- layout/svg/nsSVGClipPathFrame.cpp | 9 ++++++++- layout/svg/nsSVGIntegrationUtils.cpp | 18 ++++++++---------- layout/svg/nsSVGIntegrationUtils.h | 7 ++++--- layout/svg/nsSVGMaskFrame.cpp | 8 +++++++- layout/svg/nsSVGUtils.cpp | 10 +++++++--- layout/svg/nsSVGUtils.h | 13 ++++++++++--- 6 files changed, 44 insertions(+), 21 deletions(-) diff --git a/layout/svg/nsSVGClipPathFrame.cpp b/layout/svg/nsSVGClipPathFrame.cpp index d6cb30423e0a..8c1482425179 100644 --- a/layout/svg/nsSVGClipPathFrame.cpp +++ b/layout/svg/nsSVGClipPathFrame.cpp @@ -465,7 +465,14 @@ nsSVGClipPathFrame::GetClipPathTransform(nsIFrame* aClippedFrame) nsSVGEnum* clipPathUnits = &content->mEnumAttributes[SVGClipPathElement::CLIPPATHUNITS]; - return nsSVGUtils::AdjustMatrixForUnits(tm, clipPathUnits, aClippedFrame); + uint32_t flags = + nsSVGUtils::eBBoxIncludeFillGeometry | + (aClippedFrame->StyleBorder()->mBoxDecorationBreak == StyleBoxDecorationBreak::Clone + ? nsSVGUtils::eIncludeOnlyCurrentFrameForNonSVGElement + : 0); + + return nsSVGUtils::AdjustMatrixForUnits(tm, clipPathUnits, + aClippedFrame, flags); } SVGBBox diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index d6de1e03d1be..32a509b0ca78 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -217,7 +217,8 @@ nsSVGIntegrationUtils::GetSVGCoordContextForNonSVGFrame(nsIFrame* aNonSVGFrame) } gfxRect -nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame) +nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame, + bool aUnionContinuations) { // Except for nsSVGOuterSVGFrame, we shouldn't be getting here with SVG // frames at all. This function is for elements that are laid out using the @@ -230,15 +231,12 @@ nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame) nsIFrame* firstFrame = nsLayoutUtils::FirstContinuationOrIBSplitSibling(aNonSVGFrame); // 'r' is in "user space": - nsRect r; - if (aNonSVGFrame->StyleBorder()->mBoxDecorationBreak == StyleBoxDecorationBreak::Clone) { - r = GetPreEffectsVisualOverflow(firstFrame, aNonSVGFrame, - GetOffsetToBoundingBox(firstFrame)); - } else { - r = GetPreEffectsVisualOverflowUnion(firstFrame, nullptr, nsRect(), - GetOffsetToBoundingBox(firstFrame), - false); - } + nsRect r = (aUnionContinuations) + ? GetPreEffectsVisualOverflowUnion(firstFrame, nullptr, nsRect(), + GetOffsetToBoundingBox(firstFrame), + false) + : GetPreEffectsVisualOverflow(firstFrame, aNonSVGFrame, + GetOffsetToBoundingBox(firstFrame)); return nsLayoutUtils::RectToGfxRect(r, aNonSVGFrame->PresContext()->AppUnitsPerCSSPixel()); diff --git a/layout/svg/nsSVGIntegrationUtils.h b/layout/svg/nsSVGIntegrationUtils.h index 8f1345991533..4f840369b102 100644 --- a/layout/svg/nsSVGIntegrationUtils.h +++ b/layout/svg/nsSVGIntegrationUtils.h @@ -78,12 +78,13 @@ public: * "bbox" for the element they're being applied to in order to make decisions * about positioning, and to resolve various lengths against. This method * provides the "bbox" for non-SVG frames. The bbox returned is in CSS px - * units, and is the union of all aNonSVGFrame's continuations' overflow - * areas, relative to the top-left of the union of all aNonSVGFrame's + * units, and aUnionContinuations decide whether bbox contains the area of + * current frame only or the union of all aNonSVGFrame's continuations' + * overflow areas, relative to the top-left of the union of all aNonSVGFrame's * continuations' border box rects. */ static gfxRect - GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame); + GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame, bool aUnionContinuations); /** * Used to adjust a frame's pre-effects visual overflow rect to take account diff --git a/layout/svg/nsSVGMaskFrame.cpp b/layout/svg/nsSVGMaskFrame.cpp index 906620cb6da2..42b3171982a7 100644 --- a/layout/svg/nsSVGMaskFrame.cpp +++ b/layout/svg/nsSVGMaskFrame.cpp @@ -226,6 +226,12 @@ nsSVGMaskFrame::GetMaskTransform(nsIFrame* aMaskedFrame) nsSVGEnum* maskContentUnits = &content->mEnumAttributes[SVGMaskElement::MASKCONTENTUNITS]; + uint32_t flags = + nsSVGUtils::eBBoxIncludeFillGeometry | + (aMaskedFrame->StyleBorder()->mBoxDecorationBreak == StyleBoxDecorationBreak::Clone + ? nsSVGUtils::eIncludeOnlyCurrentFrameForNonSVGElement + : 0); + return nsSVGUtils::AdjustMatrixForUnits(gfxMatrix(), maskContentUnits, - aMaskedFrame); + aMaskedFrame, flags); } diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 0c1cb967d98f..d8c7b6f66fa0 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -1099,7 +1099,10 @@ nsSVGUtils::GetBBox(nsIFrame* aFrame, uint32_t aFlags, (isOuterSVG && (aFlags & eUseFrameBoundsForOuterSVG))) { // An HTML element or an SVG outer frame. MOZ_ASSERT(!hasSVGLayout); - return nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(aFrame); + bool onlyCurrentFrame = aFlags & eIncludeOnlyCurrentFrameForNonSVGElement; + return nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame( + aFrame, + /* aUnionContinuations = */ !onlyCurrentFrame); } MOZ_ASSERT(svg); @@ -1296,11 +1299,12 @@ nsSVGUtils::CanOptimizeOpacity(nsIFrame *aFrame) gfxMatrix nsSVGUtils::AdjustMatrixForUnits(const gfxMatrix &aMatrix, nsSVGEnum *aUnits, - nsIFrame *aFrame) + nsIFrame *aFrame, + uint32_t aFlags) { if (aFrame && aUnits->GetAnimValue() == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { - gfxRect bbox = GetBBox(aFrame); + gfxRect bbox = GetBBox(aFrame, aFlags); gfxMatrix tm = aMatrix; tm.PreTranslate(gfxPoint(bbox.X(), bbox.Y())); tm.PreScale(bbox.Width(), bbox.Height()); diff --git a/layout/svg/nsSVGUtils.h b/layout/svg/nsSVGUtils.h index cc09f5f7f48f..c92b9134be1b 100644 --- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -379,10 +379,13 @@ public: * bottom right of its bbox). * * If the bbox is empty, this will return a singular matrix. + * + * @param aFlags One or more of the BBoxFlags values defined below. */ static gfxMatrix AdjustMatrixForUnits(const gfxMatrix &aMatrix, nsSVGEnum *aUnits, - nsIFrame *aFrame); + nsIFrame *aFrame, + uint32_t aFlags); enum BBoxFlags { eBBoxIncludeFill = 1 << 0, @@ -392,11 +395,15 @@ public: eBBoxIncludeMarkers = 1 << 4, eBBoxIncludeClipped = 1 << 5, // Normally a getBBox call on outer- should only return the - // bounds of the elements children. This flag will cause the + // bounds of the elements children. This flag will cause the // element's bounds to be returned instead. eUseFrameBoundsForOuterSVG = 1 << 6, // https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect eForGetClientRects = 1 << 7, + // If the given frame is an HTML element, only include the region of the + // given frame, instead of all continuations of it, while computing bbox if + // this flag is set. + eIncludeOnlyCurrentFrameForNonSVGElement = 1 << 8, }; /** * This function in primarily for implementing the SVG DOM function getBBox() @@ -410,7 +417,7 @@ public: * obtained. * @param aFlags One or more of the BBoxFlags values defined above. * @param aToBoundsSpace If not specified the returned rect is in aFrame's - * element's "user space". A matrix can optionally be pass to specify a + * element's "user space". A matrix can optionally be pass to specify a * transform from aFrame's user space to the bounds space of interest * (typically this will be the ancestor nsSVGOuterSVGFrame, but it could be * to any other coordinate space).