diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 4e7ad2e5883..05603755a93 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1847,27 +1847,35 @@ nsLayoutUtils::GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback) } struct BoxToBorderRect : public nsLayoutUtils::BoxCallback { - nsIFrame* mRelativeTo; + nsIFrame* mRelativeTo; nsLayoutUtils::RectCallback* mCallback; + PRUint32 mFlags; - BoxToBorderRect(nsIFrame* aRelativeTo, nsLayoutUtils::RectCallback* aCallback) - : mRelativeTo(aRelativeTo), mCallback(aCallback) {} + BoxToBorderRect(nsIFrame* aRelativeTo, nsLayoutUtils::RectCallback* aCallback, + PRUint32 aFlags) + : mRelativeTo(aRelativeTo), mCallback(aCallback), mFlags(aFlags) {} virtual void AddBox(nsIFrame* aFrame) { nsRect r; nsIFrame* outer = nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(aFrame, &r); - if (outer) { - mCallback->AddRect(r + outer->GetOffsetTo(mRelativeTo)); - } else - mCallback->AddRect(nsRect(aFrame->GetOffsetTo(mRelativeTo), aFrame->GetSize())); + if (!outer) { + outer = aFrame; + r = nsRect(nsPoint(0, 0), aFrame->GetSize()); + } + if (mFlags & nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS) { + r = nsLayoutUtils::TransformFrameRectToAncestor(outer, r, mRelativeTo); + } else { + r += outer->GetOffsetTo(mRelativeTo); + } + mCallback->AddRect(r); } }; void nsLayoutUtils::GetAllInFlowRects(nsIFrame* aFrame, nsIFrame* aRelativeTo, - RectCallback* aCallback) + RectCallback* aCallback, PRUint32 aFlags) { - BoxToBorderRect converter(aRelativeTo, aCallback); + BoxToBorderRect converter(aRelativeTo, aCallback, aFlags); GetAllInFlowBoxes(aFrame, &converter); } @@ -1893,19 +1901,14 @@ void nsLayoutUtils::RectListBuilder::AddRect(const nsRect& aRect) { nsIFrame* nsLayoutUtils::GetContainingBlockForClientRect(nsIFrame* aFrame) { - // get the nearest enclosing SVG foreign object frame or the root frame - while (aFrame->GetParent() && - !aFrame->IsFrameOfType(nsIFrame::eSVGForeignObject)) { - aFrame = aFrame->GetParent(); - } - - return aFrame; + return aFrame->PresContext()->PresShell()->GetRootFrame(); } nsRect -nsLayoutUtils::GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo) { +nsLayoutUtils::GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo, + PRUint32 aFlags) { RectAccumulator accumulator; - GetAllInFlowRects(aFrame, aRelativeTo, &accumulator); + GetAllInFlowRects(aFrame, aRelativeTo, &accumulator, aFlags); return accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect : accumulator.mResultRect; } diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 1396a99f49c..3b355bf397d 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -704,8 +704,8 @@ public: }; struct RectAccumulator : public RectCallback { - nsRect mResultRect; - nsRect mFirstRect; + nsRect mResultRect; + nsRect mFirstRect; bool mSeenFirstRect; RectAccumulator(); @@ -723,6 +723,9 @@ public: static nsIFrame* GetContainingBlockForClientRect(nsIFrame* aFrame); + enum { + RECTS_ACCOUNT_FOR_TRANSFORMS = 0x01 + }; /** * Collect all CSS border-boxes associated with aFrame and its * continuations, "drilling down" through outer table frames and @@ -731,15 +734,22 @@ public: * into account) and passed to the callback in frame-tree order. * If aFrame is null, no boxes are returned. * For SVG frames, returns one rectangle, the bounding box. + * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting + * the boxes into aRelativeTo coordinates, transforms (including CSS + * and SVG transforms) are taken into account. */ static void GetAllInFlowRects(nsIFrame* aFrame, nsIFrame* aRelativeTo, - RectCallback* aCallback); + RectCallback* aCallback, PRUint32 aFlags = 0); /** * Computes the union of all rects returned by GetAllInFlowRects. If * the union is empty, returns the first rect. + * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting + * the boxes into aRelativeTo coordinates, transforms (including CSS + * and SVG transforms) are taken into account. */ - static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo); + static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo, + PRUint32 aFlags = 0); enum { EXCLUDE_BLUR_SHADOWS = 0x01