when splitting rowgroups the space that is left on the page is computed from relative to the bottom, bug 373400 r=sharparrow1 sr=dbaron a=blocking 1.9+
authorbmlk@gmx.de
Sun, 02 Dec 2007 11:19:00 -0800
changeset 8536 fcae522d50ee88cbc9d1bf4c2ebecb649df4d895
parent 8535 aa886c9aa7d466ffc33fee589ad4e7c0d274a1a5
child 8537 28a2141608309734375dec3482f3f3603e4c73d0
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssharparrow1, dbaron, blocking
bugs373400
milestone1.9b2pre
when splitting rowgroups the space that is left on the page is computed from relative to the bottom, bug 373400 r=sharparrow1 sr=dbaron a=blocking 1.9+
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowGroupFrame.cpp
layout/tables/nsTableRowGroupFrame.h
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -1075,19 +1075,20 @@ nsTableRowFrame::ReflowCellFrame(nsPresC
   InitChildReflowState(*aPresContext, availSize, borderCollapse, cellReflowState);
   cellReflowState.mFlags.mIsTopOfPage = aIsTopOfPage;
 
   nsHTMLReflowMetrics desiredSize;
 
   ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
               0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
   PRBool fullyComplete = NS_FRAME_IS_COMPLETE(aStatus) && !NS_FRAME_IS_TRUNCATED(aStatus);
-
-  aCellFrame->SetSize(
-    nsSize(cellSize.width, fullyComplete ? aAvailableHeight : desiredSize.height));
+  if (fullyComplete) {
+    desiredSize.height = aAvailableHeight;
+  }
+  aCellFrame->SetSize(nsSize(cellSize.width, desiredSize.height));
 
   // XXX What happens if this cell has 'vertical-align: baseline' ?
   // XXX Why is it assumed that the cell's ascent hasn't changed ?
   if (fullyComplete) {
     aCellFrame->VerticallyAlignChild(mMaxCellAscent);
   }
   aCellFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
 
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -917,21 +917,22 @@ nsTableRowGroupFrame::CreateContinuingRo
 // page that contains a cell which cannot split on this page 
 void
 nsTableRowGroupFrame::SplitSpanningCells(nsPresContext&          aPresContext,
                                          const nsHTMLReflowState& aReflowState,
                                          nsTableFrame&            aTable,
                                          nsTableRowFrame&         aFirstRow, 
                                          nsTableRowFrame&         aLastRow,  
                                          PRBool                   aFirstRowIsTopOfPage,
-                                         nscoord                  aAvailHeight,
+                                         nscoord                  aSpanningRowBottom,
                                          nsTableRowFrame*&        aContRow,
                                          nsTableRowFrame*&        aFirstTruncatedRow,
                                          nscoord&                 aDesiredHeight)
 {
+  NS_ASSERTION(aSpanningRowBottom >= 0, "Can't split negative heights");
   aFirstTruncatedRow = nsnull;
   aDesiredHeight     = 0;
 
   PRInt32 lastRowIndex = aLastRow.GetRowIndex();
   PRBool wasLast = PR_FALSE;
   // Iterate the rows between aFirstRow and aLastRow
   for (nsTableRowFrame* row = &aFirstRow; !wasLast; row = row->GetNextRow()) {
     wasLast = (row == &aLastRow);
@@ -941,17 +942,18 @@ nsTableRowGroupFrame::SplitSpanningCells
     for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) {
       PRInt32 rowSpan = aTable.GetEffectiveRowSpan(rowIndex, *cell);
       // Only reflow rowspan > 1 cells which span aLastRow. Those which don't span aLastRow
       // were reflowed correctly during the unconstrained height reflow. 
       if ((rowSpan > 1) && (rowIndex + rowSpan > lastRowIndex)) {
         nsReflowStatus status;
         // Ask the row to reflow the cell to the height of all the rows it spans up through aLastRow
         // aAvailHeight is the space between the row group start and the end of the page
-        nscoord cellAvailHeight = aAvailHeight - rowPos.y;
+        nscoord cellAvailHeight = aSpanningRowBottom - rowPos.y;
+        NS_ASSERTION(cellAvailHeight >= 0, "No space for cell?");
         PRBool isTopOfPage = (row == &aFirstRow) && aFirstRowIsTopOfPage;
         nscoord cellHeight = row->ReflowCellFrame(&aPresContext, aReflowState,
                                                   isTopOfPage, cell,
                                                   cellAvailHeight, status);
         aDesiredHeight = PR_MAX(aDesiredHeight, rowPos.y + cellHeight);
         if (NS_FRAME_IS_COMPLETE(status)) {
           if (cellHeight > cellAvailHeight) {
             aFirstTruncatedRow = row;
@@ -1103,64 +1105,65 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
           }
         } 
         else {
           // The row frame is complete because either (1) its minimum height is greater than the 
           // available height we gave it, or (2) it may have been given a larger height through 
           // style than its content, or (3) it contains a rowspan >1 cell which hasn't been
           // reflowed with a constrained height yet (we will find out when SplitSpanningCells is
           // called below)
-          if (rowMetrics.height >= availSize.height) {
+          if (rowMetrics.height > availSize.height) {
             // cases (1) and (2)
             if (isTopOfPage) { 
               // We're on top of the page, so keep the row on this page. There will be data loss.
               // Push the row frame that follows
               nsTableRowFrame* nextRowFrame = rowFrame->GetNextRow();
               if (nextRowFrame) {
                 aStatus = NS_FRAME_NOT_COMPLETE;
               }
               aDesiredSize.height += rowMetrics.height;
               if (prevRowFrame) 
                 aDesiredSize.height += cellSpacingY;
               NS_WARNING("data loss - complete row needed more height than available, on top of page");
             }
-            else {  
+            else {
               // We're not on top of the page, so put the row on the next page to give it more height 
               rowIsOnPage = PR_FALSE;
             }
           }
         }
       } //if (!prevRowFrame || (availHeight - aDesiredSize.height > pageHeight / 20))
       else { 
         // put the row on the next page to give it more height
         rowIsOnPage = PR_FALSE;
       }
 
       nsTableRowFrame* lastRowThisPage = rowFrame;
+      nscoord spanningRowBottom = availHeight;
       if (!rowIsOnPage) {
         NS_ASSERTION(!contRow, "We should not have created a continuation if none of this row fits");
         if (prevRowFrame) {
-          availHeight -= prevRowFrame->GetRect().YMost();
+          spanningRowBottom = prevRowFrame->GetRect().YMost();
           lastRowThisPage = prevRowFrame;
           isTopOfPage = (lastRowThisPage == firstRowThisPage) && aReflowState.mFlags.mIsTopOfPage;
           aStatus = NS_FRAME_NOT_COMPLETE;
         }
         else {
           // We can't push children, so let our parent reflow us again with more space
           aDesiredSize.height = rowRect.YMost();
           aStatus = NS_FRAME_COMPLETE;
           break;
         }
       }
       // reflow the cells with rowspan >1 that occur on the page
 
       nsTableRowFrame* firstTruncatedRow;
       nscoord yMost;
       SplitSpanningCells(*aPresContext, aReflowState, *aTableFrame, *firstRowThisPage,
-                         *lastRowThisPage, aReflowState.mFlags.mIsTopOfPage, availHeight, contRow, 
+                         *lastRowThisPage, aReflowState.mFlags.mIsTopOfPage, spanningRowBottom, contRow, 
                          firstTruncatedRow, yMost);
       if (firstTruncatedRow) {
         // A rowspan >1 cell did not fit (and could not split) in the space we gave it
         if (firstTruncatedRow == firstRowThisPage) {
           if (aReflowState.mFlags.mIsTopOfPage) {
             NS_WARNING("data loss in a row spanned cell");
           }
           else {
@@ -1169,36 +1172,38 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
             aStatus = NS_FRAME_COMPLETE;
             UndoContinuedRow(aPresContext, contRow);
             contRow = nsnull;
           }
         }
         else { // (firstTruncatedRow != firstRowThisPage)
           // Try to put firstTruncateRow on the next page 
           nsTableRowFrame* rowBefore = ::GetRowBefore(*firstRowThisPage, *firstTruncatedRow);
-          availHeight -= rowBefore->GetRect().YMost();
+          nscoord oldSpanningRowBottom = spanningRowBottom;
+          spanningRowBottom = rowBefore->GetRect().YMost();
 
           UndoContinuedRow(aPresContext, contRow);
           contRow = nsnull;
           nsTableRowFrame* oldLastRowThisPage = lastRowThisPage;
           lastRowThisPage = firstTruncatedRow;
           aStatus = NS_FRAME_NOT_COMPLETE;
 
           // Call SplitSpanningCells again with rowBefore as the last row on the page
           SplitSpanningCells(*aPresContext, aReflowState, *aTableFrame, 
                              *firstRowThisPage, *rowBefore, aReflowState.mFlags.mIsTopOfPage, 
-                             availHeight, contRow, firstTruncatedRow, aDesiredSize.height);
+                             spanningRowBottom, contRow, firstTruncatedRow, aDesiredSize.height);
           if (firstTruncatedRow) {
             if (aReflowState.mFlags.mIsTopOfPage) {
               // We were better off with the 1st call to SplitSpanningCells, do it again
               UndoContinuedRow(aPresContext, contRow);
               contRow = nsnull;
               lastRowThisPage = oldLastRowThisPage;
+              spanningRowBottom = oldSpanningRowBottom;
               SplitSpanningCells(*aPresContext, aReflowState, *aTableFrame, *firstRowThisPage,
-                                 *lastRowThisPage, aReflowState.mFlags.mIsTopOfPage, availHeight, contRow, 
+                                 *lastRowThisPage, aReflowState.mFlags.mIsTopOfPage, spanningRowBottom, contRow, 
                                  firstTruncatedRow, aDesiredSize.height);
               NS_WARNING("data loss in a row spanned cell");
             }
             else {
               // Let our parent reflow us again with more space
               aDesiredSize.height = rowRect.YMost();
               aStatus = NS_FRAME_COMPLETE;
               UndoContinuedRow(aPresContext, contRow);
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -345,17 +345,17 @@ protected:
                          nsReflowStatus&          aStatus);
 
   void SplitSpanningCells(nsPresContext&          aPresContext,
                           const nsHTMLReflowState& aReflowState,
                           nsTableFrame&            aTableFrame,
                           nsTableRowFrame&         aFirstRow, 
                           nsTableRowFrame&         aLastRow,  
                           PRBool                   aFirstRowIsTopOfPage,
-                          nscoord                  aAvailHeight,
+                          nscoord                  aSpanningRowBottom,
                           nsTableRowFrame*&        aContRowFrame,
                           nsTableRowFrame*&        aFirstTruncatedRow,
                           nscoord&                 aDesiredHeight);
 
   void CreateContinuingRowFrame(nsPresContext& aPresContext,
                                 nsIFrame&       aRowFrame,
                                 nsIFrame**      aContRowFrame);