Remaining nsBlockFrame changes for split overflow areas. (Bug 542595, patch 14) r=roc a2.0=blocking2.0:beta8
authorL. David Baron <dbaron@dbaron.org>
Wed, 06 Oct 2010 21:25:45 -0700
changeset 55034 9292ed4f13c720ba7266a0e7d477906adf34e98f
parent 55033 0de9480228c0f90350d7009e494fbba088097d7f
child 55035 89551308e58554eff348cd6dd38acd0c47db4f4a
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs542595
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Remaining nsBlockFrame changes for split overflow areas. (Bug 542595, patch 14) r=roc a2.0=blocking2.0:beta8
layout/generic/nsBlockFrame.cpp
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -956,19 +956,20 @@ nsBlockFrame::Reflow(nsPresContext*     
   // XXXldb If we start storing the float manager in the frame rather
   // than keeping it around only during reflow then we should create it
   // only when there are actually floats to manage.  Otherwise things
   // like tables will gain significant bloat.
   PRBool needFloatManager = nsBlockFrame::BlockNeedsFloatManager(this);
   if (needFloatManager)
     autoFloatManager.CreateFloatManager(aPresContext);
 
-  // OK, some lines may be reflowed. Blow away any saved line cursor because
-  // we may invalidate the nondecreasing combinedArea.y/yMost invariant,
-  // and we may even delete the line with the line cursor.
+  // OK, some lines may be reflowed. Blow away any saved line cursor
+  // because we may invalidate the nondecreasing
+  // overflowArea.VisualOverflow().y/yMost invariant, and we may even
+  // delete the line with the line cursor.
   ClearLineCursor();
 
   if (IsFrameTreeTooDeep(aReflowState, aMetrics)) {
 #ifdef DEBUG_kipp
     {
       extern char* nsPresShell_ReflowStackPointerTop;
       char marker;
       char* newsp = (char*) &marker;
@@ -1188,22 +1189,27 @@ nsBlockFrame::Reflow(nsPresContext*     
 #ifdef DEBUG
   if (gNoisyReflow) {
     IndentBy(stdout, gNoiseIndent);
     ListTag(stdout);
     printf(": status=%x (%scomplete) metrics=%d,%d carriedMargin=%d",
            aStatus, NS_FRAME_IS_COMPLETE(aStatus) ? "" : "not ",
            aMetrics.width, aMetrics.height,
            aMetrics.mCarriedOutBottomMargin.get());
-    if (HasOverflowRect()) {
-      printf(" combinedArea={%d,%d,%d,%d}",
-             aMetrics.mOverflowArea.x,
-             aMetrics.mOverflowArea.y,
-             aMetrics.mOverflowArea.width,
-             aMetrics.mOverflowArea.height);
+    if (HasOverflowAreas()) {
+      printf(" overflow-vis={%d,%d,%d,%d}",
+             aMetrics.VisualOverflow().x,
+             aMetrics.VisualOverflow().y,
+             aMetrics.VisualOverflow().width,
+             aMetrics.VisualOverflow().height);
+      printf(" overflow-scr={%d,%d,%d,%d}",
+             aMetrics.ScrollableOverflow().x,
+             aMetrics.ScrollableOverflow().y,
+             aMetrics.ScrollableOverflow().width,
+             aMetrics.ScrollableOverflow().height);
     }
     printf("\n");
   }
 
   if (gLameReflowMetrics) {
     PRTime end = PR_Now();
 
     PRInt32 ectc = nsLineBox::GetCtorCount();
@@ -1654,18 +1660,21 @@ nsBlockFrame::PropagateFloatDamage(nsBlo
     return;
 
   // Check the damage region recorded in the float damage.
   if (floatManager->HasFloatDamage()) {
     // Need to check mBounds *and* mCombinedArea to find intersections 
     // with aLine's floats
     nscoord lineYA = aLine->mBounds.y + aDeltaY;
     nscoord lineYB = lineYA + aLine->mBounds.height;
-    nscoord lineYCombinedA = aLine->GetCombinedArea().y + aDeltaY;
-    nscoord lineYCombinedB = lineYCombinedA + aLine->GetCombinedArea().height;
+    // Scrollable overflow should be sufficient for things that affect
+    // layout.
+    nsRect overflow = aLine->GetOverflowArea(eScrollableOverflow);
+    nscoord lineYCombinedA = overflow.y + aDeltaY;
+    nscoord lineYCombinedB = lineYCombinedA + overflow.height;
     if (floatManager->IntersectsDamage(lineYA, lineYB) ||
         floatManager->IntersectsDamage(lineYCombinedA, lineYCombinedB)) {
       aLine->MarkDirty();
       return;
     }
   }
 
   // Check if the line is moving relative to the float manager
@@ -1727,24 +1736,26 @@ nsBlockFrame::ReparentFloats(nsIFrame* a
     mFloats.AppendFrames(nsnull, list);
   }
 }
 
 static void DumpLine(const nsBlockReflowState& aState, nsLineBox* aLine,
                      nscoord aDeltaY, PRInt32 aDeltaIndent) {
 #ifdef DEBUG
   if (nsBlockFrame::gNoisyReflow) {
-    nsRect lca(aLine->GetCombinedArea());
+    nsRect ovis(aLine->GetVisualOverflowArea());
+    nsRect oscr(aLine->GetScrollableOverflowArea());
     nsBlockFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent + aDeltaIndent);
-    printf("line=%p mY=%d dirty=%s oldBounds={%d,%d,%d,%d} oldCombinedArea={%d,%d,%d,%d} deltaY=%d mPrevBottomMargin=%d childCount=%d\n",
+    printf("line=%p mY=%d dirty=%s oldBounds={%d,%d,%d,%d} oldoverflow-vis={%d,%d,%d,%d} oldoverflow-scr={%d,%d,%d,%d} deltaY=%d mPrevBottomMargin=%d childCount=%d\n",
            static_cast<void*>(aLine), aState.mY,
            aLine->IsDirty() ? "yes" : "no",
            aLine->mBounds.x, aLine->mBounds.y,
            aLine->mBounds.width, aLine->mBounds.height,
-           lca.x, lca.y, lca.width, lca.height,
+           ovis.x, ovis.y, ovis.width, ovis.height,
+           oscr.x, oscr.y, oscr.width, oscr.height,
            aDeltaY, aState.mPrevBottomMargin.get(), aLine->GetChildCount());
   }
 #endif
 }
 
 /**
  * Reflow the dirty lines
  */
@@ -2443,48 +2454,48 @@ nsBlockFrame::ReflowLine(nsBlockReflowSt
   aState.mCurrentLine = aLine;
   aLine->ClearDirty();
   aLine->InvalidateCachedIsEmpty();
   aLine->ClearHadFloatPushed();
 
   // Now that we know what kind of line we have, reflow it
   if (aLine->IsBlock()) {
     nsRect oldBounds = aLine->mFirstChild->GetRect();
-    nsRect oldCombinedArea(aLine->GetCombinedArea());
+    nsRect oldVisOverflow(aLine->GetVisualOverflowArea());
     rv = ReflowBlockFrame(aState, aLine, aKeepReflowGoing);
     nsRect newBounds = aLine->mFirstChild->GetRect();
 
     // We expect blocks to damage any area inside their bounds that is
     // dirty; however, if the frame changes size or position then we
     // need to do some repainting.
     // XXX roc --- the above statement is ambiguous about whether 'bounds'
     // means the frame's bounds or overflowArea, and in fact this is a source
     // of much confusion and bugs. Thus the following hack considers *both*
     // overflowArea and bounds. This should be considered a temporary hack
     // until we decide how it's really supposed to work.
     // Note that we have a similar hack in nsTableFrame::InvalidateFrame.
-    nsRect lineCombinedArea(aLine->GetCombinedArea());
-    if (oldCombinedArea.TopLeft() != lineCombinedArea.TopLeft() ||
+    nsRect visOverflow(aLine->GetVisualOverflowArea());
+    if (oldVisOverflow.TopLeft() != visOverflow.TopLeft() ||
         oldBounds.TopLeft() != newBounds.TopLeft()) {
       // The block has moved, and so to be safe we need to repaint
       // XXX We need to improve on this...
       nsRect  dirtyRect;
-      dirtyRect.UnionRect(oldCombinedArea, lineCombinedArea);
+      dirtyRect.UnionRect(oldVisOverflow, visOverflow);
 #ifdef NOISY_BLOCK_INVALIDATE
       printf("%p invalidate 6 (%d, %d, %d, %d)\n",
              this, dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);
 #endif
       Invalidate(dirtyRect);
       FrameLayerBuilder::InvalidateThebesLayersInSubtree(aLine->mFirstChild);
     } else {
       nsRect combinedAreaHStrip, combinedAreaVStrip;
       nsRect boundsHStrip, boundsVStrip;
       nsLayoutUtils::GetRectDifferenceStrips(oldBounds, newBounds,
                                              &boundsHStrip, &boundsVStrip);
-      nsLayoutUtils::GetRectDifferenceStrips(oldCombinedArea, lineCombinedArea,
+      nsLayoutUtils::GetRectDifferenceStrips(oldVisOverflow, visOverflow,
                                              &combinedAreaHStrip,
                                              &combinedAreaVStrip);
 
 #ifdef NOISY_BLOCK_INVALIDATE
       printf("%p invalidate boundsVStrip (%d, %d, %d, %d)\n",
              this, boundsVStrip.x, boundsVStrip.y, boundsVStrip.width, boundsVStrip.height);
       printf("%p invalidate boundsHStrip (%d, %d, %d, %d)\n",
              this, boundsHStrip.x, boundsHStrip.y, boundsHStrip.width, boundsHStrip.height);
@@ -2497,25 +2508,25 @@ nsBlockFrame::ReflowLine(nsBlockReflowSt
       // don't bother doing that here.
       Invalidate(boundsVStrip);
       Invalidate(boundsHStrip);
       Invalidate(combinedAreaVStrip);
       Invalidate(combinedAreaHStrip);
     }
   }
   else {
-    nsRect oldCombinedArea(aLine->GetCombinedArea());
+    nsRect oldVisOverflow(aLine->GetVisualOverflowArea());
     aLine->SetLineWrapped(PR_FALSE);
 
     rv = ReflowInlineFrames(aState, aLine, aKeepReflowGoing);
 
     // We don't really know what changed in the line, so use the union
     // of the old and new combined areas
     nsRect dirtyRect;
-    dirtyRect.UnionRect(oldCombinedArea, aLine->GetCombinedArea());
+    dirtyRect.UnionRect(oldVisOverflow, aLine->GetVisualOverflowArea());
 #ifdef NOISY_BLOCK_INVALIDATE
     printf("%p invalidate (%d, %d, %d, %d)\n",
            this, dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);
     if (aLine->IsForceInvalidate())
       printf("  dirty line is %p\n", static_cast<void*>(aLine.get()));
 #endif
     Invalidate(dirtyRect);
     if (GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT) {
@@ -2635,17 +2646,17 @@ nsBlockFrame::PullFrameFrom(nsBlockReflo
     // the combined area always enclose the bounds?
     Invalidate(fromLine->mBounds);
     nsLineList* fromLineList = aFromOverflowLine
       ? aFromContainer->RemoveOverflowLines()
       : &aFromContainer->mLines;
     if (aFromLine.next() != fromLineList->end())
       aFromLine.next()->MarkPreviousMarginDirty();
 
-    Invalidate(fromLine->GetCombinedArea());
+    Invalidate(fromLine->GetVisualOverflowArea());
     fromLineList->erase(aFromLine);
     // aFromLine is now invalid
     aState.FreeLineBox(fromLine);
 
     // Put any remaining overflow lines back.
     if (aFromOverflowLine) {
       if (!fromLineList->empty()) {
         aFromContainer->SetOverflowLines(fromLineList);
@@ -2674,20 +2685,20 @@ PlaceFrameView(nsIFrame* aFrame)
 }
 
 void
 nsBlockFrame::SlideLine(nsBlockReflowState& aState,
                         nsLineBox* aLine, nscoord aDY)
 {
   NS_PRECONDITION(aDY != 0, "why slide a line nowhere?");
 
-  Invalidate(aLine->GetCombinedArea());
+  Invalidate(aLine->GetVisualOverflowArea());
   // Adjust line state
   aLine->SlideBy(aDY);
-  Invalidate(aLine->GetCombinedArea());
+  Invalidate(aLine->GetVisualOverflowArea());
 
   // Adjust the frames in the line
   nsIFrame* kid = aLine->mFirstChild;
   if (!kid) {
     return;
   }
 
   if (aLine->IsBlock()) {
@@ -5387,23 +5398,23 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aD
 #endif
       nsLineBox *cur = line;
       if (!searchingOverflowList) {
         line = mLines.erase(line);
         // Invalidate the space taken up by the line.
         // XXX We need to do this if we're removing a frame as a result of
         // a call to RemoveFrame(), but we may not need to do this in all
         // cases...
-        nsRect lineCombinedArea(cur->GetCombinedArea());
+        nsRect visOverflow(cur->GetVisualOverflowArea());
 #ifdef NOISY_BLOCK_INVALIDATE
         printf("%p invalidate 10 (%d, %d, %d, %d)\n",
-               this, lineCombinedArea.x, lineCombinedArea.y,
-               lineCombinedArea.width, lineCombinedArea.height);
+               this, visOverflow.x, visOverflow.y,
+               visOverflow.width, visOverflow.height);
 #endif
-        Invalidate(lineCombinedArea);
+        Invalidate(visOverflow);
       } else {
         nsLineList* lineList = RemoveOverflowLines();
         line = lineList->erase(line);
         if (!lineList->empty()) {
           SetOverflowLines(lineList);
         } else {
           delete lineList;
           // We just invalidated our iterators.  Since we were in
@@ -5766,17 +5777,17 @@ nsBlockFrame::ReflowFloat(nsBlockReflowS
   // XXXldb This seems like the wrong place to be doing this -- shouldn't
   // we be doing this in nsBlockReflowState::FlowAndPlaceFloat after
   // we've positioned the float, and shouldn't we be doing the equivalent
   // of |::PlaceFrameView| here?
   aFloat->SetSize(nsSize(metrics.width, metrics.height));
   if (aFloat->HasView()) {
     nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, aFloat,
                                                aFloat->GetView(),
-                                               &metrics.mOverflowArea,
+                                               metrics.VisualOverflow(),
                                                NS_FRAME_NO_MOVE_VIEW);
   }
   // Pass floatRS so the frame hierarchy can be used (redoFloatRS has the same hierarchy)  
   aFloat->DidReflow(aState.mPresContext, &floatRS,
                         NS_FRAME_REFLOW_FINISHED);
 
 #ifdef NOISY_FLOAT
   printf("end ReflowFloat %p, sized to %d,%d\n",
@@ -6030,17 +6041,17 @@ nsBlockFrame::AdjustForTextIndent(const 
     width -= indent;
   }
 }
 
 #ifdef DEBUG
 static void DebugOutputDrawLine(PRInt32 aDepth, nsLineBox* aLine, PRBool aDrawn) {
   if (nsBlockFrame::gNoisyDamageRepair) {
     nsFrame::IndentBy(stdout, aDepth+1);
-    nsRect lineArea = aLine->GetCombinedArea();
+    nsRect lineArea = aLine->GetVisualOverflowArea();
     printf("%s line=%p bounds=%d,%d,%d,%d ca=%d,%d,%d,%d\n",
            aDrawn ? "draw" : "skip",
            static_cast<void*>(aLine),
            aLine->mBounds.x, aLine->mBounds.y,
            aLine->mBounds.width, aLine->mBounds.height,
            lineArea.x, lineArea.y,
            lineArea.width, lineArea.height);
   }
@@ -6144,17 +6155,17 @@ nsBlockFrame::BuildDisplayList(nsDisplay
     ? nsnull : GetFirstLineContaining(aDirtyRect.y);
   line_iterator line_end = end_lines();
   nsresult rv = NS_OK;
   
   if (cursor) {
     for (line_iterator line = mLines.begin(cursor);
          line != line_end;
          ++line) {
-      nsRect lineArea = line->GetCombinedArea();
+      nsRect lineArea = line->GetVisualOverflowArea();
       if (!lineArea.IsEmpty()) {
         // Because we have a cursor, the combinedArea.ys are non-decreasing.
         // Once we've passed aDirtyRect.YMost(), we can never see it again.
         if (lineArea.y >= aDirtyRect.YMost()) {
           break;
         }
         rv = DisplayLine(aBuilder, lineArea, aDirtyRect, line, depth, drawnLines,
                          aLists, this);
@@ -6165,17 +6176,17 @@ nsBlockFrame::BuildDisplayList(nsDisplay
   } else {
     PRBool nonDecreasingYs = PR_TRUE;
     PRInt32 lineCount = 0;
     nscoord lastY = PR_INT32_MIN;
     nscoord lastYMost = PR_INT32_MIN;
     for (line_iterator line = begin_lines();
          line != line_end;
          ++line) {
-      nsRect lineArea = line->GetCombinedArea();
+      nsRect lineArea = line->GetVisualOverflowArea();
       rv = DisplayLine(aBuilder, lineArea, aDirtyRect, line, depth, drawnLines,
                        aLists, this);
       if (NS_FAILED(rv))
         break;
       if (!lineArea.IsEmpty()) {
         if (lineArea.y < lastY
             || lineArea.YMost() < lastYMost) {
           nonDecreasingYs = PR_FALSE;
@@ -6307,27 +6318,27 @@ nsLineBox* nsBlockFrame::GetFirstLineCon
     return nsnull;
   }
 
   FrameProperties props = Properties();
   
   nsLineBox* property = static_cast<nsLineBox*>
     (props.Get(LineCursorProperty()));
   line_iterator cursor = mLines.begin(property);
-  nsRect cursorArea = cursor->GetCombinedArea();
+  nsRect cursorArea = cursor->GetVisualOverflowArea();
 
   while ((cursorArea.IsEmpty() || cursorArea.YMost() > y)
          && cursor != mLines.front()) {
     cursor = cursor.prev();
-    cursorArea = cursor->GetCombinedArea();
+    cursorArea = cursor->GetVisualOverflowArea();
   }
   while ((cursorArea.IsEmpty() || cursorArea.YMost() <= y)
          && cursor != mLines.back()) {
     cursor = cursor.next();
-    cursorArea = cursor->GetCombinedArea();
+    cursorArea = cursor->GetVisualOverflowArea();
   }
 
   if (cursor.get() != property) {
     props.Set(LineCursorProperty(), cursor.get());
   }
 
   return cursor.get();
 }