Bug 1177606 - Correct the row positioning within rowGroups in vertical-rl tables when distributing extra width. r=dholbert
authorJonathan Kew <jkew@mozilla.com>
Fri, 26 Jun 2015 16:50:38 -0700
changeset 281222 645991c76862d7bf87ecf584737e20ba77f64eb1
parent 281221 e174d857a802d9a00583633ec3c95bdb083666c0
child 281223 4d8180c520d878fbba1dd9444862746bbc1352f8
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1177606
milestone41.0a1
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
Bug 1177606 - Correct the row positioning within rowGroups in vertical-rl tables when distributing extra width. r=dholbert
layout/tables/nsTableFrame.cpp
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -3382,38 +3382,45 @@ void ResizeCells(nsTableFrame& aTableFra
 
 void
 nsTableFrame::DistributeBSizeToRows(const nsHTMLReflowState& aReflowState,
                                     nscoord                  aAmount)
 {
   WritingMode wm = aReflowState.GetWritingMode();
   LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowState);
 
+  nscoord containerWidth = aReflowState.ComputedWidth();
+  if (containerWidth == NS_UNCONSTRAINEDSIZE) {
+    containerWidth = 0;
+  } else {
+    containerWidth += aReflowState.ComputedPhysicalBorderPadding().LeftRight();
+  }
+
   RowGroupArray rowGroups;
   OrderRowGroups(rowGroups);
 
   nscoord amountUsed = 0;
   // distribute space to each pct bsize row whose row group doesn't have a computed
   // bsize, and base the pct on the table bsize. If the row group had a computed
   // bsize, then this was already done in nsTableRowGroupFrame::CalculateRowBSizes
   nscoord pctBasis = aReflowState.ComputedBSize() - GetRowSpacing(-1, GetRowCount());
   nscoord bOriginRG = borderPadding.BStart(wm) + GetRowSpacing(0);
   nscoord bEndRG = bOriginRG;
   uint32_t rgX;
   for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
     nscoord amountUsedByRG = 0;
     nscoord bOriginRow = 0;
-    // We pass containerWidth of zero when constructing the LogicalRect here,
-    // and similarly below. This is OK because these rects will be used to make
-    // relative adjustments, not for actual conversion to physical coords.
-    LogicalRect rgNormalRect(wm, rgFrame->GetNormalRect(), 0);
+    LogicalRect rgNormalRect(wm, rgFrame->GetNormalRect(), containerWidth);
     if (!rgFrame->HasStyleBSize()) {
       nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
       while (rowFrame) {
+        // We don't know the final width of the rowGroupFrame yet, so use zero
+        // as a "fake" containerWidth here; we'll adjust the row positions at
+        // the end, after the rowGroup size is finalized.
         LogicalRect rowNormalRect(wm, rowFrame->GetNormalRect(), 0);
         nscoord cellSpacingB = GetRowSpacing(rowFrame->GetRowIndex());
         if ((amountUsed < aAmount) && rowFrame->HasPctBSize()) {
           nscoord pctBSize = rowFrame->GetInitialBSize(pctBasis);
           nscoord amountForRow = std::min(aAmount - amountUsed,
                                           pctBSize - rowNormalRect.BSize(wm));
           if (amountForRow > 0) {
             // XXXbz we don't need to move the row's b-position to bOriginRow?
@@ -3541,22 +3548,22 @@ nsTableFrame::DistributeBSizeToRows(cons
   // allocate the extra bsize to the unstyled row groups and rows
   nscoord bSizeToDistribute = aAmount - amountUsed;
   bOriginRG = borderPadding.BStart(wm) + GetRowSpacing(-1);
   bEndRG = bOriginRG;
   for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
     nscoord amountUsedByRG = 0;
     nscoord bOriginRow = 0;
-    LogicalRect rgNormalRect(wm, rgFrame->GetNormalRect(), 0);
+    LogicalRect rgNormalRect(wm, rgFrame->GetNormalRect(), containerWidth);
     nsRect rgVisualOverflow = rgFrame->GetVisualOverflowRect();
     // see if there is an eligible row group or we distribute to all rows
     if (!firstUnStyledRG || !rgFrame->HasStyleBSize() || !eligibleRows) {
-      nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
-      while (rowFrame) {
+      for (nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
+           rowFrame; rowFrame = rowFrame->GetNextRow()) {
         nscoord cellSpacingB = GetRowSpacing(rowFrame->GetRowIndex());
         LogicalRect rowNormalRect(wm, rowFrame->GetNormalRect(), 0);
         nsRect rowVisualOverflow = rowFrame->GetVisualOverflowRect();
         // see if there is an eligible row or we distribute to all rows
         if (!firstUnStyledRow || !rowFrame->HasStyleBSize() || !eligibleRows) {
           float ratio;
           if (eligibleRows) {
             if (!expandEmptyRows) {
@@ -3610,33 +3617,49 @@ nsTableFrame::DistributeBSizeToRows(cons
             rowFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRow -
                                                     rowNormalRect.BStart(wm)));
             nsTableFrame::RePositionViews(rowFrame);
             rowFrame->InvalidateFrameSubtree();
           }
           bOriginRow += rowNormalRect.BSize(wm) + cellSpacingB;
           bEndRG += rowNormalRect.BSize(wm) + cellSpacingB;
         }
-        rowFrame = rowFrame->GetNextRow();
       }
+
       if (amountUsed > 0) {
         if (rgNormalRect.BStart(wm) != bOriginRG) {
           rgFrame->InvalidateFrameSubtree();
         }
 
         nsRect origRgNormalRect = rgFrame->GetRect();
         rgFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRG -
                                                  rgNormalRect.BStart(wm)));
         rgFrame->SetSize(wm, LogicalSize(wm, rgNormalRect.ISize(wm),
                                 rgNormalRect.BSize(wm) + amountUsedByRG));
 
         nsTableFrame::InvalidateTableFrame(rgFrame, origRgNormalRect,
                                            rgVisualOverflow, false);
       }
-      // Make sure child views are properly positioned
+
+      // For vertical-rl mode, we needed to position the rows relative to the
+      // right-hand (block-start) side of the group; but we couldn't do that
+      // above, as we didn't know the rowGroupFrame's final block size yet.
+      // So we used a containerWidth of zero earlier, placing the rows to the
+      // left of the rowGroupFrame's (physical) origin. Now we move them all
+      // rightwards by its final width.
+      if (wm.IsVerticalRL()) {
+        nscoord rgWidth = rgFrame->GetRect().width;
+        for (nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
+             rowFrame; rowFrame = rowFrame->GetNextRow()) {
+          rowFrame->InvalidateFrameSubtree();
+          rowFrame->MovePositionBy(nsPoint(rgWidth, 0));
+          nsTableFrame::RePositionViews(rowFrame);
+          rowFrame->InvalidateFrameSubtree();
+        }
+      }
     }
     else if (amountUsed > 0 && bOriginRG != rgNormalRect.BStart(wm)) {
       rgFrame->InvalidateFrameSubtree();
       rgFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRG -
                                                rgNormalRect.BStart(wm)));
       // Make sure child views are properly positioned
       nsTableFrame::RePositionViews(rgFrame);
       rgFrame->InvalidateFrameSubtree();