diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 226660b8ec47..3d0cafe07bb2 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -659,6 +659,24 @@ nsDisplayBoxShadow::GetBounds(nsDisplayListBuilder* aBuilder) { return mFrame->GetOverflowRect() + aBuilder->ToReferenceFrame(mFrame); } +PRBool +nsDisplayBoxShadow::OptimizeVisibility(nsDisplayListBuilder* aBuilder, + nsRegion* aVisibleRegion) { + if (!nsDisplayItem::OptimizeVisibility(aBuilder, aVisibleRegion)) + return PR_FALSE; + + const nsStyleBorder* border = mFrame->GetStyleBorder(); + nsPoint origin = aBuilder->ToReferenceFrame(mFrame); + if (nsRect(origin, mFrame->GetSize()).Contains(aVisibleRegion->GetBounds()) && + !nsLayoutUtils::HasNonZeroCorner(border->mBorderRadius)) { + // the visible region is entirely inside the border-rect, and box shadows + // never render within the border-rect (unless there's a border radius). + return PR_FALSE; + } + + return PR_TRUE; +} + nsDisplayWrapList::nsDisplayWrapList(nsIFrame* aFrame, nsDisplayList* aList) : nsDisplayItem(aFrame) { mList.AppendToTop(aList); diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 0db24067be41..129dba7af7be 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -1053,6 +1053,7 @@ public: virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx, const nsRect& aDirtyRect); virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual PRBool OptimizeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion); NS_DISPLAY_DECL_NAME("BoxShadow") };