Bug 820131 - Compute a more accurate bounds for nsDisplayBoxShadowOuter. r=roc

This commit is contained in:
Matt Woodrow 2012-12-12 09:36:54 +13:00
parent 16aadb5e5c
commit d12fc1cdaf
5 changed files with 49 additions and 22 deletions

View File

@ -2384,7 +2384,13 @@ nsDisplayBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder,
nsRect
nsDisplayBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
return mBounds;
}
nsRect
nsDisplayBoxShadowOuter::GetBoundsInternal() {
return nsLayoutUtils::GetBoxShadowRectForFrame(mFrame, mFrame->GetSize()) +
ToReferenceFrame();
}
bool

View File

@ -1970,6 +1970,7 @@ public:
nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame) {
MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);
mBounds = GetBoundsInternal();
}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayBoxShadowOuter() {
@ -1999,8 +2000,11 @@ public:
}
}
nsRect GetBoundsInternal();
private:
nsRegion mVisibleRegion;
nsRect mBounds;
};
/**

View File

@ -5216,3 +5216,32 @@ nsLayoutUtils::FontSizeInflationEnabled(nsPresContext *aPresContext)
return true;
}
/* static */ nsRect
nsLayoutUtils::GetBoxShadowRectForFrame(nsIFrame* aFrame,
const nsSize& aFrameSize)
{
nsCSSShadowArray* boxShadows = aFrame->GetStyleBorder()->mBoxShadow;
if (!boxShadows) {
return nsRect();
}
nsRect shadows;
int32_t A2D = aFrame->PresContext()->AppUnitsPerDevPixel();
for (uint32_t i = 0; i < boxShadows->Length(); ++i) {
nsRect tmpRect(nsPoint(0, 0), aFrameSize);
nsCSSShadowItem* shadow = boxShadows->ShadowAt(i);
// inset shadows are never painted outside the frame
if (shadow->mInset)
continue;
tmpRect.MoveBy(nsPoint(shadow->mXOffset, shadow->mYOffset));
tmpRect.Inflate(shadow->mSpread);
tmpRect.Inflate(
nsContextBoxBlur::GetBlurRadiusMargin(shadow->mRadius, A2D));
shadows.UnionRect(shadows, tmpRect);
}
return shadows;
}

View File

@ -1766,6 +1766,14 @@ public:
static bool PointIsCloserToRect(PointType aPoint, const RectType& aRect,
CoordType& aClosestXDistance,
CoordType& aClosestYDistance);
/**
* Computes the box shadow rect for the frame, or returns an empty rect if
* there are no shadows.
*
* @param aFrame Frame to compute shadows for.
* @param aFrameSize Size of aFrame (in case it hasn't been set yet).
*/
static nsRect GetBoxShadowRectForFrame(nsIFrame* aFrame, const nsSize& aFrameSize);
#ifdef DEBUG
/**

View File

@ -5110,27 +5110,7 @@ ComputeOutlineAndEffectsRect(nsIFrame* aFrame,
}
// box-shadow
nsCSSShadowArray* boxShadows = aFrame->GetStyleBorder()->mBoxShadow;
if (boxShadows) {
nsRect shadows;
int32_t A2D = aFrame->PresContext()->AppUnitsPerDevPixel();
for (uint32_t i = 0; i < boxShadows->Length(); ++i) {
nsRect tmpRect(nsPoint(0, 0), aNewSize);
nsCSSShadowItem* shadow = boxShadows->ShadowAt(i);
// inset shadows are never painted outside the frame
if (shadow->mInset)
continue;
tmpRect.MoveBy(nsPoint(shadow->mXOffset, shadow->mYOffset));
tmpRect.Inflate(shadow->mSpread, shadow->mSpread);
tmpRect.Inflate(
nsContextBoxBlur::GetBlurRadiusMargin(shadow->mRadius, A2D));
shadows.UnionRect(shadows, tmpRect);
}
r.UnionRect(r, shadows);
}
r.UnionRect(r, nsLayoutUtils::GetBoxShadowRectForFrame(aFrame, aNewSize));
const nsStyleOutline* outline = aFrame->GetStyleOutline();
uint8_t outlineStyle = outline->GetOutlineStyle();