Make box-shadow cause only the overflow it needs and not add on additional overflow. (Bug 514917) r=roc
authorL. David Baron <dbaron@dbaron.org>
Sun, 13 Dec 2009 19:40:55 -0800
changeset 35702 a26df386758fae109bd9244a687da86e31e417e1
parent 35701 808b422d1274118e540fe15616e23a202aa3bd6f
child 35703 038564bc6eb70b434e7cf5574615584b4e77cc47
push id10686
push userdbaron@mozilla.com
push dateMon, 14 Dec 2009 03:43:27 +0000
treeherdermozilla-central@4700e3c42868 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs514917
milestone1.9.3a1pre
Make box-shadow cause only the overflow it needs and not add on additional overflow. (Bug 514917) r=roc
layout/generic/nsFrame.cpp
layout/reftests/bugs/514917-1-ref.html
layout/reftests/bugs/514917-1.html
layout/reftests/bugs/reftest.list
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3809,26 +3809,27 @@ SetRectProperty(nsIFrame* aFrame, nsIAto
 /**
  * @param aAnyOutlineOrEffects set to true if this frame has any
  * outline, SVG effects or box shadows that mean we need to invalidate
  * the whole overflow area if the frame's size changes.
  */
 static nsRect
 ComputeOutlineAndEffectsRect(nsIFrame* aFrame, PRBool* aAnyOutlineOrEffects,
                              const nsRect& aOverflowRect,
+                             const nsSize& aNewSize,
                              PRBool aStoreRectProperties) {
   nsRect r = aOverflowRect;
   *aAnyOutlineOrEffects = PR_FALSE;
 
   // box-shadow
   nsCSSShadowArray* boxShadows = aFrame->GetEffectiveBoxShadows();
   if (boxShadows) {
     nsRect shadows;
     for (PRUint32 i = 0; i < boxShadows->Length(); ++i) {
-      nsRect tmpRect = r;
+      nsRect tmpRect(nsPoint(0, 0), aNewSize);
       nsCSSShadowItem* shadow = boxShadows->ShadowAt(i);
 
       // inset shadows are never painted outside the frame
       if (shadow->mInset)
         continue;
       nscoord outsetRadius = shadow->mRadius + shadow->mSpread;
 
       tmpRect.MoveBy(nsPoint(shadow->mXOffset, shadow->mYOffset));
@@ -3982,17 +3983,18 @@ nsIFrame::CheckInvalidateSizeChange(cons
   // though root-invalidation is technically only needed in the case where
   // layer.RenderingMightDependOnFrameSize().  This allows us to simplify the
   // code somewhat and return immediately after invalidation in the earlier
   // cases.
 
   // Invalidate the entire old frame+outline if the frame has an outline
   PRBool anyOutlineOrEffects;
   nsRect r = ComputeOutlineAndEffectsRect(this, &anyOutlineOrEffects,
-                                          aOldOverflowRect, PR_FALSE);
+                                          aOldOverflowRect, aNewDesiredSize,
+                                          PR_FALSE);
   if (anyOutlineOrEffects) {
     r.UnionRect(aOldOverflowRect, r);
     InvalidateRectForFrameSizeChange(this, r);
     return;
   }
 
   // Invalidate the old frame border box if the frame has borders. Those
   // borders may be moving.
@@ -5553,17 +5555,17 @@ IsInlineFrame(nsIFrame *aFrame)
 
 nsRect
 nsIFrame::GetAdditionalOverflow(const nsRect& aOverflowArea,
                                 const nsSize& aNewSize,
                                 PRBool* aHasOutlineOrEffects)
 {
   nsRect overflowRect =
     ComputeOutlineAndEffectsRect(this, aHasOutlineOrEffects,
-                                 aOverflowArea, PR_TRUE);
+                                 aOverflowArea, aNewSize, PR_TRUE);
 
   // Absolute position clipping
   PRBool hasAbsPosClip;
   nsRect absPosClipRect;
   hasAbsPosClip = GetAbsPosClipRect(GetStyleDisplay(), &absPosClipRect, aNewSize);
   if (hasAbsPosClip) {
     overflowRect.IntersectRect(overflowRect, absPosClipRect);
   }
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/514917-1-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<title>Testcase, bug 514917</title>
+<style type="text/css">
+
+body > div > div {
+  width: 100px;
+  height: 100px;
+  -moz-box-shadow: blue 50px 50px;
+}
+
+body > div > div > div {
+  width: 160px;
+  height: 160px;
+  border: medium solid;
+}
+
+</style>
+<body>
+<div><div><div></div></div></div>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/514917-1.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<title>Testcase, bug 514917</title>
+<style type="text/css">
+
+body > div {
+  overflow: auto; /* to detect too much overflow, which is the bug here */
+  width: 200px;
+  height: 200px;
+}
+
+body > div > div {
+  width: 100px;
+  height: 100px;
+  -moz-box-shadow: blue 50px 50px;
+}
+
+body > div > div > div {
+  width: 160px;
+  height: 160px;
+  border: medium solid;
+}
+
+</style>
+<body>
+<div><div><div></div></div></div>
+</body>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1324,16 +1324,17 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") ==
 == 512631-1.html 512631-1-ref.html
 == 513153-1a.html 513153-1-ref.html
 == 513153-1b.html 513153-1-ref.html
 == 513153-2a.html 513153-2-ref.html
 == 513153-2b.html 513153-2-ref.html
 == 513318-1.xul 513318-1-ref.xul
 != 513318-2.xul 513318-2-ref.xul
 != 513318-3.xul 513318-3-ref.xul
+== 514917-1.html 514917-1-ref.html
 == 520421-1.html 520421-1-ref.html
 == 520563-1.xhtml 520563-1-ref.xhtml
 == 521525-1.html 521525-1-ref.html
 == 521525-2.html 521525-2-ref.html
 == 521539-1.html 521539-1-ref.html
 == 521542-1.xhtml 521542-1-ref.xhtml
 == 521685-1.html 521685-1-ref.html
 == 523096-1.html 523096-1-ref.html