Invalidate things correctly when the caption or inner table is resized. Bug 424465, r=bernd, sr=roc
authorbzbarsky@mit.edu
Tue, 01 Apr 2008 14:53:19 -0700
changeset 13804 ccac2951875630258654d9b4b37274674752fe6e
parent 13803 e65c60c2bb13dee9e0994952870f882e1ea21f67
child 13805 2ae23c57b6c23214290566f4470942899fc51660
push idunknown
push userunknown
push dateunknown
reviewersbernd, roc
bugs424465
milestone1.9pre
Invalidate things correctly when the caption or inner table is resized. Bug 424465, r=bernd, sr=roc
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableOuterFrame.cpp
layout/tables/nsTableOuterFrame.h
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowGroupFrame.cpp
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -929,16 +929,22 @@ NS_METHOD nsTableCellFrame::Reflow(nsPre
       // the height that they could honor in the pass 2 reflow
       SetHasPctOverHeight(PR_TRUE);
     }
     if (NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) {
       aDesiredSize.height = mRect.height;
     }
   }
 
+  // If our parent is in initial reflow, it'll handle invalidating our
+  // entire overflow rect.
+  if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
+    CheckInvalidateSizeChange(aPresContext, aDesiredSize, aReflowState);
+  }
+
   // remember the desired size for this reflow
   SetDesiredSize(aDesiredSize);
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return NS_OK;
 }
 
 /* ----- global methods ----- */
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -526,105 +526,16 @@ GetContainingBlockSize(const nsHTMLReflo
     size.height = containRS->ComputedHeight();
     if (NS_UNCONSTRAINEDSIZE == size.height) {
       size.height = 0;
     }
   }
   return size;
 }
 
-void
-nsTableOuterFrame::InvalidateDamage(PRUint8         aCaptionSide,
-                                    const nsSize&   aOuterSize,
-                                    PRBool          aInnerChanged,
-                                    PRBool          aCaptionChanged,
-                                    nsRect*         aOldOverflowArea)
-{
-  if (!aInnerChanged && !aCaptionChanged) return;
-
-  nsRect damage;
-  if (aInnerChanged && aCaptionChanged) {
-    damage = nsRect(0, 0, aOuterSize.width, aOuterSize.height);
-    if (aOldOverflowArea) {
-      damage.UnionRect(damage, *aOldOverflowArea);
-    }
-    damage.UnionRect(damage, GetOverflowRect());
-  }
-  else {
-    nsRect captionRect(0,0,0,0);
-    nsRect innerRect = mInnerTableFrame->GetRect();
-    if (mCaptionFrame) {
-      captionRect = mCaptionFrame->GetRect();
-    }
-    
-    damage.x = 0;
-    damage.width  = aOuterSize.width;
-    switch(aCaptionSide) {
-    case NS_STYLE_CAPTION_SIDE_BOTTOM:
-    case NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE:
-      if (aCaptionChanged) {
-        damage.y = innerRect.y;
-        damage.height = aOuterSize.height - damage.y;
-      }
-      else { // aInnerChanged 
-        damage.y = 0;
-        damage.height = captionRect.y;
-      }
-      break;
-    case NS_STYLE_CAPTION_SIDE_LEFT:
-      if (aCaptionChanged) {
-        damage.width = innerRect.x;
-        damage.y = 0;
-        damage.height = captionRect.YMost();
-      }
-      else { // aInnerChanged
-        damage.x = captionRect.XMost();
-        damage.width = innerRect.XMost() - damage.x;
-        damage.y = 0;
-        damage.height = innerRect.YMost();
-      }
-      break;
-    case NS_STYLE_CAPTION_SIDE_RIGHT:
-     if (aCaptionChanged) {
-        damage.x = innerRect.XMost();
-        damage.width -= damage.x;
-        damage.y = 0;
-        damage.height = captionRect.YMost();
-      }
-     else { // aInnerChanged
-        damage.width -= captionRect.width;
-        damage.y = 0;
-        damage.height = innerRect.YMost();
-      }
-      break;
-    default:
-      NS_ASSERTION(aCaptionSide == NS_STYLE_CAPTION_SIDE_TOP ||
-                   aCaptionSide == NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE ||
-                   aCaptionSide == NO_SIDE,
-                   "unexpected caption side");
-      if (aCaptionChanged) {
-        damage.y = 0;
-        damage.height = innerRect.y;
-      }
-      else { // aInnerChanged
-        damage.y = captionRect.y;
-        damage.height = aOuterSize.height - damage.y;
-      }
-      break;
-    }
-     
-    nsIFrame* kidFrame = aCaptionChanged ? mCaptionFrame : mInnerTableFrame;
-    ConsiderChildOverflow(damage, kidFrame);
-    if (aOldOverflowArea) {
-      damage.UnionRect(damage, *aOldOverflowArea);
-    }
-  }
-  Invalidate(damage);
-}
-
 /* virtual */ nscoord
 nsTableOuterFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
 {
   nscoord width = nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
                     mInnerTableFrame, nsLayoutUtils::MIN_WIDTH);
   DISPLAY_MIN_WIDTH(this, width);
   if (mCaptionFrame) {
     nscoord capWidth =
@@ -1274,16 +1185,30 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPr
     ((sizeof(nsHTMLReflowState) + sizeof(long) - 1) / sizeof(long))
   long captionRSSpace[LONGS_IN_HTMLRS];
   nsHTMLReflowState *captionRS =
     static_cast<nsHTMLReflowState*>((void*)captionRSSpace);
   long innerRSSpace[LONGS_IN_HTMLRS];
   nsHTMLReflowState *innerRS =
     static_cast<nsHTMLReflowState*>((void*) innerRSSpace);
 
+  nsRect origInnerRect = mInnerTableFrame->GetRect();
+  nsRect origInnerOverflowRect = mInnerTableFrame->GetOverflowRect();
+  PRBool innerFirstReflow =
+    (mInnerTableFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
+  nsRect origCaptionRect;
+  nsRect origCaptionOverflowRect;
+  PRBool captionFirstReflow;
+  if (mCaptionFrame) {
+    origCaptionRect = mCaptionFrame->GetRect();
+    origCaptionOverflowRect = mCaptionFrame->GetOverflowRect();
+    captionFirstReflow =
+      (mCaptionFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
+  }
+  
   // ComputeAutoSize has to match this logic.
   if (captionSide == NO_SIDE) {
     // We don't have a caption.
     OuterBeginReflowChild(aPresContext, mInnerTableFrame, aOuterRS,
                           innerRSSpace, aOuterRS.ComputedWidth());
   } else if (captionSide == NS_STYLE_CAPTION_SIDE_LEFT ||
              captionSide == NS_STYLE_CAPTION_SIDE_RIGHT) {
     // nsTableCaptionFrame::ComputeAutoSize takes care of making side
@@ -1378,16 +1303,23 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPr
 
   nsPoint innerOrigin;
   GetInnerOrigin(captionSide, containSize, captionSize, 
                  captionMargin, innerSize, innerMargin, innerOrigin);
   FinishReflowChild(mInnerTableFrame, aPresContext, innerRS, innerMet,
                     innerOrigin.x, innerOrigin.y, 0);
   innerRS->~nsHTMLReflowState();
 
+  nsTableFrame::InvalidateFrame(mInnerTableFrame, origInnerRect,
+                                origInnerOverflowRect, innerFirstReflow);
+  if (mCaptionFrame) {
+    nsTableFrame::InvalidateFrame(mCaptionFrame, origCaptionRect,
+                                  origCaptionOverflowRect, captionFirstReflow);
+  }
+
   UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, captionMargin);
   
   // Return our desired rect
 
   NS_FRAME_SET_TRUNCATION(aStatus, aOuterRS, aDesiredSize);
   return rv;
 }
 
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -270,22 +270,16 @@ protected:
                               nsReflowStatus&          aStatus);
 
   // Set the reflow metrics
   void UpdateReflowMetrics(PRUint8              aCaptionSide,
                            nsHTMLReflowMetrics& aMet,
                            const nsMargin&      aInnerMargin,
                            const nsMargin&      aCaptionMargin);
 
-  void InvalidateDamage(PRUint8         aCaptionSide,
-                        const nsSize&   aOuterSize,
-                        PRBool          aInnerChanged,
-                        PRBool          aCaptionChanged,
-                        nsRect*         aOldOverflowArea);
-  
   // Get the margin.  aMarginNoAuto is aMargin, but with auto 
   // margins set to 0
   void GetMargin(nsPresContext*           aPresContext,
                  const nsHTMLReflowState& aOuterRS,
                  nsIFrame*                aChildFrame,
                  nscoord                  aAvailableWidth,
                  nsMargin&                aMargin);
 
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -1061,17 +1061,17 @@ nsTableRowFrame::Reflow(nsPresContext*  
   rv = ReflowChildren(aPresContext, aDesiredSize, aReflowState, *tableFrame,
                       aStatus);
 
   // just set our width to what was available. The table will calculate the width and not use our value.
   aDesiredSize.width = aReflowState.availableWidth;
 
   // If our parent is in initial reflow, it'll handle invalidating our
   // entire overflow rect.
-  if (!GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
+  if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     CheckInvalidateSizeChange(aPresContext, aDesiredSize, aReflowState);
   }
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return rv;
 }
 
 /**
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -1352,17 +1352,17 @@ nsTableRowGroupFrame::Reflow(nsPresConte
   // just set our width to what was available. The table will calculate the width and not use our value.
   aDesiredSize.width = aReflowState.availableWidth;
 
   aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, nsRect(0, 0, aDesiredSize.width,
 	                                                                      aDesiredSize.height));
 
   // If our parent is in initial reflow, it'll handle invalidating our
   // entire overflow rect.
-  if (!GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
+  if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     CheckInvalidateSizeChange(aPresContext, aDesiredSize, aReflowState);
   }
   
   FinishAndStoreOverflow(&aDesiredSize);
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return rv;
 }