Bug 1174700 - patch 1 - Convert nsTableRowFrame and nsTableRowGroupFrame to work with logical coordinates. r=dholbert
☠☠ backed out by b60de195ad59 ☠ ☠
authorJonathan Kew <jkew@mozilla.com>
Sat, 20 Jun 2015 21:00:26 +0100
changeset 280679 f18cb4c415785255eaee01d92a6c308ef9863250
parent 280678 f7fca0232ffc4ec5855557cfb7a6d039b28488e4
child 280680 ed293fc9596caa5d45186a712dd8b25daf433e68
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
bugs1174700
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 1174700 - patch 1 - Convert nsTableRowFrame and nsTableRowGroupFrame to work with logical coordinates. r=dholbert
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTablePainter.cpp
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowFrame.h
layout/tables/nsTableRowGroupFrame.cpp
layout/tables/nsTableRowGroupFrame.h
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -843,17 +843,17 @@ CalcUnpaginatedBSize(nsPresContext*     
                                                           rowIndex + rowSpan - 1);
   computedBSize -= aBlockDirBorderPadding;
   int32_t rowX;
   for (row = firstRGInFlow->GetFirstRow(), rowX = 0; row; row = row->GetNextRow(), rowX++) {
     if (rowX > rowIndex + rowSpan - 1) {
       break;
     }
     else if (rowX >= rowIndex) {
-      computedBSize += row->GetUnpaginatedHeight(aPresContext);
+      computedBSize += row->GetUnpaginatedBSize(aPresContext);
     }
   }
   return computedBSize;
 }
 
 void
 nsTableCellFrame::Reflow(nsPresContext*           aPresContext,
                          nsHTMLReflowMetrics&     aDesiredSize,
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -3321,23 +3321,23 @@ nsTableFrame::DistributeHeightToRows(con
   nscoord yOriginRG = borderPadding.BStart(wm) + GetRowSpacing(0);
   nscoord yEndRG = yOriginRG;
   uint32_t rgX;
   for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
     nscoord amountUsedByRG = 0;
     nscoord yOriginRow = 0;
     nsRect rgNormalRect = rgFrame->GetNormalRect();
-    if (!rgFrame->HasStyleHeight()) {
+    if (!rgFrame->HasStyleBSize()) {
       nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
       while (rowFrame) {
         nsRect rowNormalRect = rowFrame->GetNormalRect();
         nscoord cellSpacingY = GetRowSpacing(rowFrame->GetRowIndex());
-        if ((amountUsed < aAmount) && rowFrame->HasPctHeight()) {
-          nscoord pctHeight = rowFrame->GetHeight(pctBasis);
+        if ((amountUsed < aAmount) && rowFrame->HasPctBSize()) {
+          nscoord pctHeight = rowFrame->GetBSize(pctBasis);
           nscoord amountForRow = std::min(aAmount - amountUsed,
                                           pctHeight - rowNormalRect.height);
           if (amountForRow > 0) {
             // XXXbz we don't need to move the row's y position to yOriginRow?
             nsRect origRowRect = rowFrame->GetRect();
             nscoord newRowHeight = rowNormalRect.height + amountForRow;
             rowFrame->SetSize(nsSize(rowNormalRect.width, newRowHeight));
             yOriginRow += newRowHeight + cellSpacingY;
@@ -3396,20 +3396,20 @@ nsTableFrame::DistributeHeightToRows(con
   }
 
   // get the first row without a style height where its row group has an
   // unconstrained height
   nsTableRowGroupFrame* firstUnStyledRG  = nullptr;
   nsTableRowFrame*      firstUnStyledRow = nullptr;
   for (rgX = 0; rgX < rowGroups.Length() && !firstUnStyledRG; rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
-    if (!rgFrame->HasStyleHeight()) {
+    if (!rgFrame->HasStyleBSize()) {
       nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
       while (rowFrame) {
-        if (!rowFrame->HasStyleHeight()) {
+        if (!rowFrame->HasStyleBSize()) {
           firstUnStyledRG = rgFrame;
           firstUnStyledRow = rowFrame;
           break;
         }
         rowFrame = rowFrame->GetNextRow();
       }
     }
   }
@@ -3425,20 +3425,20 @@ nsTableFrame::DistributeHeightToRows(con
 
   if (!firstUnStyledRow) {
     // there is no unstyled row
     divisor = GetRowCount();
   }
   else {
     for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
       nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
-      if (!firstUnStyledRG || !rgFrame->HasStyleHeight()) {
+      if (!firstUnStyledRG || !rgFrame->HasStyleBSize()) {
         nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
         while (rowFrame) {
-          if (!firstUnStyledRG || !rowFrame->HasStyleHeight()) {
+          if (!firstUnStyledRG || !rowFrame->HasStyleBSize()) {
             NS_ASSERTION(rowFrame->GetSize().height >= 0,
                          "negative row frame height");
             divisor += rowFrame->GetSize().height;
             eligibleRows++;
             lastEligibleRow = rowFrame;
           }
           rowFrame = rowFrame->GetNextRow();
         }
@@ -3460,24 +3460,24 @@ nsTableFrame::DistributeHeightToRows(con
   yEndRG = yOriginRG;
   for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
     nscoord amountUsedByRG = 0;
     nscoord yOriginRow = 0;
     nsRect rgNormalRect = rgFrame->GetNormalRect();
     nsRect rgVisualOverflow = rgFrame->GetVisualOverflowRect();
     // see if there is an eligible row group or we distribute to all rows
-    if (!firstUnStyledRG || !rgFrame->HasStyleHeight() || !eligibleRows) {
+    if (!firstUnStyledRG || !rgFrame->HasStyleBSize() || !eligibleRows) {
       nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
       while (rowFrame) {
         nscoord cellSpacingY = GetRowSpacing(rowFrame->GetRowIndex());
         nsRect rowNormalRect = rowFrame->GetNormalRect();
         nsRect rowVisualOverflow = rowFrame->GetVisualOverflowRect();
         // see if there is an eligible row or we distribute to all rows
-        if (!firstUnStyledRow || !rowFrame->HasStyleHeight() || !eligibleRows) {
+        if (!firstUnStyledRow || !rowFrame->HasStyleBSize() || !eligibleRows) {
           float ratio;
           if (eligibleRows) {
             if (!expandEmptyRows) {
               // The amount of additional space each row gets is proportional to
               // its height
               ratio = float(rowNormalRect.height) / float(divisor);
             } else {
               // empty rows get all the same additional space
@@ -3908,72 +3908,35 @@ nsTableIterator::nsTableIterator(nsFrame
 }
 
 void
 nsTableIterator::Init(nsIFrame* aFirstChild)
 {
   mFirstListChild = aFirstChild;
   mFirstChild     = aFirstChild;
   mCurrentChild   = nullptr;
-  mLeftToRight    = true;
   mCount          = -1;
-
-  if (!mFirstChild) {
-    return;
-  }
-
-  nsTableFrame* table = nsTableFrame::GetTableFrame(mFirstChild);
-  mLeftToRight = (NS_STYLE_DIRECTION_LTR ==
-                  table->StyleVisibility()->mDirection);
-
-  if (!mLeftToRight) {
-    mCount = 0;
-    nsIFrame* nextChild = mFirstChild->GetNextSibling();
-    while (nullptr != nextChild) {
-      mCount++;
-      mFirstChild = nextChild;
-      nextChild = nextChild->GetNextSibling();
-    }
-  }
 }
 
 nsIFrame*
 nsTableIterator::First()
 {
   mCurrentChild = mFirstChild;
   return mCurrentChild;
 }
 
 nsIFrame*
 nsTableIterator::Next()
 {
   if (!mCurrentChild) {
     return nullptr;
   }
 
-  if (mLeftToRight) {
-    mCurrentChild = mCurrentChild->GetNextSibling();
-    return mCurrentChild;
-  }
-  else {
-    nsIFrame* targetChild = mCurrentChild;
-    mCurrentChild = nullptr;
-    nsIFrame* child = mFirstListChild;
-    while (child && (child != targetChild)) {
-      mCurrentChild = child;
-      child = child->GetNextSibling();
-    }
-    return mCurrentChild;
-  }
-}
-
-bool
-nsTableIterator::IsLeftToRight()
-{
-  return mLeftToRight;
+  mCurrentChild = mCurrentChild->GetNextSibling();
+  return mCurrentChild;
 }
 
 int32_t
 nsTableIterator::Count()
 {
   if (-1 == mCount) {
     mCount = 0;
     nsIFrame* child = mFirstListChild;
@@ -5405,17 +5368,17 @@ BCMapCellInfo::SetColGroupBEndContBCBord
 void
 BCMapCellInfo::SetRowGroupBEndContBCBorder()
 {
   BCCellBorder currentBorder;
   if (mRowGroup) {
     currentBorder = CompareBorders(mTableFrame, nullptr, nullptr, mRowGroup,
                                    mEndRow, nullptr, mTableWM,
                                    eLogicalSideBEnd, ADJACENT);
-    mRowGroup->SetContinuousBCBorderWidth(NS_SIDE_BOTTOM, currentBorder.width);
+    mRowGroup->SetContinuousBCBorderWidth(eLogicalSideBEnd, currentBorder.width);
   }
 }
 
 void
 BCMapCellInfo::SetInnerRowGroupBEndContBCBorder(const nsIFrame* aNextRowGroup,
                                                 nsTableRowFrame* aNextRow)
 {
   BCCellBorder currentBorder, adjacentBorder;
@@ -5429,17 +5392,17 @@ BCMapCellInfo::SetInnerRowGroupBEndContB
                                   !ADJACENT);
   currentBorder = CompareBorders(false, currentBorder, adjacentBorder,
                                  HORIZONTAL);
   if (aNextRow) {
     aNextRow->SetContinuousBCBorderWidth(eLogicalSideBStart,
                                          currentBorder.width);
   }
   if (mRgAtEnd && mRowGroup) {
-    mRowGroup->SetContinuousBCBorderWidth(NS_SIDE_BOTTOM, currentBorder.width);
+    mRowGroup->SetContinuousBCBorderWidth(eLogicalSideBEnd, currentBorder.width);
   }
 }
 
 void
 BCMapCellInfo::SetRowIStartContBCBorder()
 {
   //get row continuous borders
   if (mCurrentRowFrame) {
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -1004,22 +1004,20 @@ inline void nsTableFrame::SetContinuousL
 
 class nsTableIterator
 {
 public:
   explicit nsTableIterator(nsIFrame& aSource);
   explicit nsTableIterator(nsFrameList& aSource);
   nsIFrame* First();
   nsIFrame* Next();
-  bool      IsLeftToRight();
   int32_t   Count();
 
 protected:
   void Init(nsIFrame* aFirstChild);
-  bool      mLeftToRight;
   nsIFrame* mFirstListChild;
   nsIFrame* mFirstChild;
   nsIFrame* mCurrentChild;
   int32_t   mCount;
 };
 
 #define ABORT0() \
 {NS_ASSERTION(false, "CellIterator program error"); \
--- a/layout/tables/nsTablePainter.cpp
+++ b/layout/tables/nsTablePainter.cpp
@@ -203,34 +203,36 @@ TableBackgroundPainter::PaintTableFrame(
                                         nsTableRowGroupFrame* aFirstRowGroup,
                                         nsTableRowGroupFrame* aLastRowGroup,
                                         const nsMargin&       aDeflate)
 {
   MOZ_ASSERT(aTableFrame, "null frame");
   TableBackgroundData tableData(aTableFrame);
   tableData.mRect.MoveTo(0,0); //using table's coords
   tableData.mRect.Deflate(aDeflate);
+  WritingMode wm = aTableFrame->GetWritingMode();
   if (mIsBorderCollapse && tableData.ShouldSetBCBorder()) {
     if (aFirstRowGroup && aLastRowGroup && mNumCols > 0) {
       //only handle non-degenerate tables; we need a more robust BC model
       //to make degenerate tables' borders reasonable to deal with
       nsMargin border, tempBorder;
       nsTableColFrame* colFrame = aTableFrame->GetColFrame(mNumCols - 1);
       if (colFrame) {
         colFrame->GetContinuousBCBorderWidth(tempBorder);
       }
       border.right = tempBorder.right;
 
-      aLastRowGroup->GetContinuousBCBorderWidth(tempBorder);
-      border.bottom = tempBorder.bottom;
+      LogicalMargin logBorder(wm);
+      aLastRowGroup->GetContinuousBCBorderWidth(wm, logBorder);
+      border.bottom = logBorder.Bottom(wm);
 
       nsTableRowFrame* rowFrame = aFirstRowGroup->GetFirstRow();
       if (rowFrame) {
-        rowFrame->GetContinuousBCBorderWidth(tempBorder);
-        border.top = tempBorder.top;
+        rowFrame->GetContinuousBCBorderWidth(wm, logBorder);
+        border.top = logBorder.Top(wm);
       }
 
       border.left = aTableFrame->GetContinuousLeftBCBorderWidth();
 
       tableData.SetBCBorder(border);
     }
   }
 
@@ -382,31 +384,32 @@ TableBackgroundPainter::PaintRowGroup(ns
 DrawResult
 TableBackgroundPainter::PaintRowGroup(nsTableRowGroupFrame* aFrame,
                                       TableBackgroundData   aRowGroupBGData,
                                       bool                  aPassThrough)
 {
   MOZ_ASSERT(aFrame, "null frame");
 
   nsTableRowFrame* firstRow = aFrame->GetFirstRow();
+  WritingMode wm = aFrame->GetWritingMode();
 
   /* Load row group data */
   if (aPassThrough) {
     aRowGroupBGData.MakeInvisible();
   } else {
     if (mIsBorderCollapse && aRowGroupBGData.ShouldSetBCBorder()) {
-      nsMargin border;
+      LogicalMargin border(wm);
       if (firstRow) {
-        //pick up first row's top border (= rg top border)
-        firstRow->GetContinuousBCBorderWidth(border);
-        /* (row group doesn't store its top border) */
+        //pick up first row's bstart border (= rg bstart border)
+        firstRow->GetContinuousBCBorderWidth(wm, border);
+        /* (row group doesn't store its bstart border) */
       }
       //overwrite sides+bottom borders with rg's own
-      aFrame->GetContinuousBCBorderWidth(border);
-      aRowGroupBGData.SetBCBorder(border);
+      aFrame->GetContinuousBCBorderWidth(wm, border);
+      aRowGroupBGData.SetBCBorder(border.GetPhysicalMargin(wm));
     }
     aPassThrough = !aRowGroupBGData.IsVisible();
   }
 
   /* translate everything into row group coord system*/
   if (eOrigin_TableRowGroup != mOrigin) {
     TranslateContext(aRowGroupBGData.mRect.x, aRowGroupBGData.mRect.y);
   }
@@ -479,35 +482,34 @@ DrawResult
 TableBackgroundPainter::PaintRow(nsTableRowFrame* aFrame,
                                  const TableBackgroundData& aRowGroupBGData,
                                  TableBackgroundData aRowBGData,
                                  bool             aPassThrough)
 {
   MOZ_ASSERT(aFrame, "null frame");
 
   /* Load row data */
+  WritingMode wm = aFrame->GetWritingMode();
   if (aPassThrough) {
     aRowBGData.MakeInvisible();
   } else {
     if (mIsBorderCollapse && aRowBGData.ShouldSetBCBorder()) {
-      nsMargin border;
+      LogicalMargin border(wm);
       nsTableRowFrame* nextRow = aFrame->GetNextRow();
       if (nextRow) { //outer top below us is inner bottom for us
-        WritingMode wm = nextRow->GetWritingMode();
-        border.Side(wm.PhysicalSide(eLogicalSideBEnd)) =
-          nextRow->GetOuterBStartContBCBorderWidth();
+        border.BEnd(wm) = nextRow->GetOuterBStartContBCBorderWidth();
       }
       else { //acquire rg's bottom border
         nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame->GetParent());
-        rowGroup->GetContinuousBCBorderWidth(border);
+        rowGroup->GetContinuousBCBorderWidth(wm, border);
       }
       //get the rest of the borders; will overwrite all but bottom
-      aFrame->GetContinuousBCBorderWidth(border);
+      aFrame->GetContinuousBCBorderWidth(wm, border);
 
-      aRowBGData.SetBCBorder(border);
+      aRowBGData.SetBCBorder(border.GetPhysicalMargin(wm));
     }
     aPassThrough = !aRowBGData.IsVisible();
   }
 
   /* Translate */
   if (eOrigin_TableRow == mOrigin) {
     /* If we originate from the row, then make the row the origin. */
     aRowBGData.mRect.MoveTo(0, 0);
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -33,44 +33,44 @@ struct nsTableCellReflowState : public n
                          nsIFrame*                aFrame,
                          const LogicalSize&       aAvailableSpace,
                          uint32_t                 aFlags = 0)
     : nsHTMLReflowState(aPresContext, aParentReflowState, aFrame,
                         aAvailableSpace, nullptr, aFlags)
   {
   }
 
-  void FixUp(const nsSize& aAvailSpace);
+  void FixUp(const LogicalSize& aAvailSpace);
 };
 
-void nsTableCellReflowState::FixUp(const nsSize& aAvailSpace)
+void nsTableCellReflowState::FixUp(const LogicalSize& aAvailSpace)
 {
   // fix the mComputed values during a pass 2 reflow since the cell can be a percentage base
-  NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aAvailSpace.width,
-                   "have unconstrained width; this should only result from "
-                   "very large sizes, not attempts at intrinsic width "
+  NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aAvailSpace.ISize(mWritingMode),
+                   "have unconstrained inline-size; this should only result from "
+                   "very large sizes, not attempts at intrinsic inline size "
                    "calculation");
-  if (NS_UNCONSTRAINEDSIZE != ComputedWidth()) {
-    nscoord computedWidth =
-      aAvailSpace.width - mComputedBorderPadding.LeftRight();
-    computedWidth = std::max(0, computedWidth);
-    SetComputedWidth(computedWidth);
+  if (NS_UNCONSTRAINEDSIZE != ComputedISize()) {
+    nscoord computedISize = aAvailSpace.ISize(mWritingMode) -
+      ComputedLogicalBorderPadding().IStartEnd(mWritingMode);
+    computedISize = std::max(0, computedISize);
+    SetComputedISize(computedISize);
   }
-  if (NS_UNCONSTRAINEDSIZE != ComputedHeight() &&
-      NS_UNCONSTRAINEDSIZE != aAvailSpace.height) {
-    nscoord computedHeight =
-      aAvailSpace.height - mComputedBorderPadding.TopBottom();
-    computedHeight = std::max(0, computedHeight);
-    SetComputedHeight(computedHeight);
+  if (NS_UNCONSTRAINEDSIZE != ComputedBSize() &&
+      NS_UNCONSTRAINEDSIZE != aAvailSpace.BSize(mWritingMode)) {
+    nscoord computedBSize = aAvailSpace.BSize(mWritingMode) -
+      ComputedLogicalBorderPadding().BStartEnd(mWritingMode);
+    computedBSize = std::max(0, computedBSize);
+    SetComputedBSize(computedBSize);
   }
 }
 
 void
-nsTableRowFrame::InitChildReflowState(nsPresContext&         aPresContext,
-                                      const nsSize&           aAvailSize,
+nsTableRowFrame::InitChildReflowState(nsPresContext&          aPresContext,
+                                      const LogicalSize&      aAvailSize,
                                       bool                    aBorderCollapse,
                                       nsTableCellReflowState& aReflowState)
 {
   nsMargin collapseBorder;
   nsMargin* pCollapseBorder = nullptr;
   if (aBorderCollapse) {
     // we only reflow cells, so don't need to check frame type
     nsBCTableCellFrame* bcCellFrame = (nsBCTableCellFrame*)aReflowState.frame;
@@ -80,61 +80,61 @@ nsTableRowFrame::InitChildReflowState(ns
       pCollapseBorder = &collapseBorder;
     }
   }
   aReflowState.Init(&aPresContext, nullptr, pCollapseBorder);
   aReflowState.FixUp(aAvailSize);
 }
 
 void
-nsTableRowFrame::SetFixedHeight(nscoord aValue)
+nsTableRowFrame::SetFixedBSize(nscoord aValue)
 {
-  nscoord height = std::max(0, aValue);
-  if (HasFixedHeight()) {
-    if (height > mStyleFixedHeight) {
-      mStyleFixedHeight = height;
+  nscoord bsize = std::max(0, aValue);
+  if (HasFixedBSize()) {
+    if (bsize > mStyleFixedBSize) {
+      mStyleFixedBSize = bsize;
     }
   }
   else {
-    mStyleFixedHeight = height;
-    if (height > 0) {
-      SetHasFixedHeight(true);
+    mStyleFixedBSize = bsize;
+    if (bsize > 0) {
+      SetHasFixedBSize(true);
     }
   }
 }
 
 void
-nsTableRowFrame::SetPctHeight(float  aPctValue,
-                              bool aForce)
+nsTableRowFrame::SetPctBSize(float aPctValue,
+                             bool  aForce)
 {
-  nscoord height = std::max(0, NSToCoordRound(aPctValue * 100.0f));
-  if (HasPctHeight()) {
-    if ((height > mStylePctHeight) || aForce) {
-      mStylePctHeight = height;
+  nscoord bsize = std::max(0, NSToCoordRound(aPctValue * 100.0f));
+  if (HasPctBSize()) {
+    if ((bsize > mStylePctBSize) || aForce) {
+      mStylePctBSize = bsize;
     }
   }
   else {
-    mStylePctHeight = height;
-    if (height > 0) {
-      SetHasPctHeight(true);
+    mStylePctBSize = bsize;
+    if (bsize > 0) {
+      SetHasPctBSize(true);
     }
   }
 }
 
 /* ----------- nsTableRowFrame ---------- */
 
 NS_QUERYFRAME_HEAD(nsTableRowFrame)
   NS_QUERYFRAME_ENTRY(nsTableRowFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 nsTableRowFrame::nsTableRowFrame(nsStyleContext* aContext)
   : nsContainerFrame(aContext)
 {
   mBits.mRowIndex = mBits.mFirstInserted = 0;
-  ResetHeight(0);
+  ResetBSize(0);
 }
 
 nsTableRowFrame::~nsTableRowFrame()
 {
 }
 
 void
 nsTableRowFrame::Init(nsIContent*       aContent,
@@ -177,75 +177,77 @@ nsTableRowFrame::DidSetStyleContext(nsSt
   if (tableFrame->IsBorderCollapse() &&
       tableFrame->BCRecalcNeeded(aOldStyleContext, StyleContext())) {
     TableArea damageArea(0, GetRowIndex(), tableFrame->GetColCount(), 1);
     tableFrame->AddBCDamageArea(damageArea);
   }
 }
 
 void
-nsTableRowFrame::AppendFrames(ChildListID     aListID,
-                              nsFrameList&    aFrameList)
+nsTableRowFrame::AppendFrames(ChildListID  aListID,
+                              nsFrameList& aFrameList)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
   DrainSelfOverflowList(); // ensure the last frame is in mFrames
   const nsFrameList::Slice& newCells = mFrames.AppendFrames(nullptr, aFrameList);
 
   // Add the new cell frames to the table
   nsTableFrame* tableFrame = GetTableFrame();
   for (nsFrameList::Enumerator e(newCells) ; !e.AtEnd(); e.Next()) {
     nsIFrame *childFrame = e.get();
-    NS_ASSERTION(IS_TABLE_CELL(childFrame->GetType()),"Not a table cell frame/pseudo frame construction failure");
+    NS_ASSERTION(IS_TABLE_CELL(childFrame->GetType()),
+                 "Not a table cell frame/pseudo frame construction failure");
     tableFrame->AppendCell(static_cast<nsTableCellFrame&>(*childFrame), GetRowIndex());
   }
 
   PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                                                NS_FRAME_HAS_DIRTY_CHILDREN);
   tableFrame->SetGeometryDirty();
 }
 
 
 void
-nsTableRowFrame::InsertFrames(ChildListID     aListID,
-                              nsIFrame*       aPrevFrame,
-                              nsFrameList&    aFrameList)
+nsTableRowFrame::InsertFrames(ChildListID  aListID,
+                              nsIFrame*    aPrevFrame,
+                              nsFrameList& aFrameList)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
   NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
                "inserting after sibling frame with different parent");
   DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
   //Insert Frames in the frame list
   const nsFrameList::Slice& newCells = mFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);
 
   // Get the table frame
   nsTableFrame* tableFrame = GetTableFrame();
   nsIAtom* cellFrameType = tableFrame->IsBorderCollapse() ? nsGkAtoms::bcTableCellFrame : nsGkAtoms::tableCellFrame;
   nsTableCellFrame* prevCellFrame = (nsTableCellFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, cellFrameType);
   nsTArray<nsTableCellFrame*> cellChildren;
   for (nsFrameList::Enumerator e(newCells); !e.AtEnd(); e.Next()) {
     nsIFrame *childFrame = e.get();
-    NS_ASSERTION(IS_TABLE_CELL(childFrame->GetType()),"Not a table cell frame/pseudo frame construction failure");
+    NS_ASSERTION(IS_TABLE_CELL(childFrame->GetType()),
+                 "Not a table cell frame/pseudo frame construction failure");
     cellChildren.AppendElement(static_cast<nsTableCellFrame*>(childFrame));
   }
   // insert the cells into the cell map
   int32_t colIndex = -1;
   if (prevCellFrame) {
     prevCellFrame->GetColIndex(colIndex);
   }
   tableFrame->InsertCells(cellChildren, GetRowIndex(), colIndex);
 
   PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                                                NS_FRAME_HAS_DIRTY_CHILDREN);
   tableFrame->SetGeometryDirty();
 }
 
 void
-nsTableRowFrame::RemoveFrame(ChildListID     aListID,
-                             nsIFrame*       aOldFrame)
+nsTableRowFrame::RemoveFrame(ChildListID aListID,
+                             nsIFrame*   aOldFrame)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
   MOZ_ASSERT((nsTableCellFrame*)do_QueryFrame(aOldFrame));
   nsTableCellFrame* cellFrame = static_cast<nsTableCellFrame*>(aOldFrame);
   // remove the cell from the cell map
   nsTableFrame* tableFrame = GetTableFrame();
   tableFrame->RemoveCell(cellFrame, GetRowIndex());
@@ -274,32 +276,33 @@ nsTableRowFrame::GetUsedBorder() const
 
 /* virtual */ nsMargin
 nsTableRowFrame::GetUsedPadding() const
 {
   return nsMargin(0,0,0,0);
 }
 
 nscoord
-GetHeightOfRowsSpannedBelowFirst(nsTableCellFrame& aTableCellFrame,
-                                 nsTableFrame&     aTableFrame)
+GetBSizeOfRowsSpannedBelowFirst(nsTableCellFrame& aTableCellFrame,
+                                nsTableFrame&     aTableFrame,
+                                const WritingMode aWM)
 {
-  nscoord height = 0;
+  nscoord bsize = 0;
   int32_t rowSpan = aTableFrame.GetEffectiveRowSpan(aTableCellFrame);
-  // add in height of rows spanned beyond the 1st one
+  // add in bsize of rows spanned beyond the 1st one
   nsIFrame* nextRow = aTableCellFrame.GetParent()->GetNextSibling();
   for (int32_t rowX = 1; ((rowX < rowSpan) && nextRow);) {
     if (nsGkAtoms::tableRowFrame == nextRow->GetType()) {
-      height += nextRow->GetSize().height;
+      bsize += nextRow->BSize(aWM);
       rowX++;
     }
-    height += aTableFrame.GetRowSpacing(rowX);
+    bsize += aTableFrame.GetRowSpacing(rowX);
     nextRow = nextRow->GetNextSibling();
   }
-  return height;
+  return bsize;
 }
 
 nsTableCellFrame*
 nsTableRowFrame::GetFirstCell()
 {
   nsIFrame* childFrame = mFrames.FirstChild();
   while (childFrame) {
     nsTableCellFrame *cellFrame = do_QueryFrame(childFrame);
@@ -312,38 +315,40 @@ nsTableRowFrame::GetFirstCell()
 }
 
 /**
  * Post-reflow hook. This is where the table row does its post-processing
  */
 void
 nsTableRowFrame::DidResize()
 {
-  // Resize and re-align the cell frames based on our row height
+  // Resize and re-align the cell frames based on our row bsize
   nsTableFrame* tableFrame = GetTableFrame();
   nsTableIterator iter(*this);
   nsIFrame* childFrame = iter.First();
 
   WritingMode wm = GetWritingMode();
   nsHTMLReflowMetrics desiredSize(wm);
   desiredSize.SetSize(wm, GetLogicalSize(wm));
   desiredSize.SetOverflowAreasToDesiredBounds();
 
   while (childFrame) {
     nsTableCellFrame *cellFrame = do_QueryFrame(childFrame);
     if (cellFrame) {
-      nscoord cellHeight = mRect.height + GetHeightOfRowsSpannedBelowFirst(*cellFrame, *tableFrame);
+      nscoord cellBSize = BSize(wm) +
+        GetBSizeOfRowsSpannedBelowFirst(*cellFrame, *tableFrame, wm);
 
-      // resize the cell's height
-      nsRect cellRect = cellFrame->GetRect();
+      // resize the cell's bsize
+      LogicalSize cellSize = cellFrame->GetLogicalSize(wm);
       nsRect cellVisualOverflow = cellFrame->GetVisualOverflowRect();
-      if (cellRect.height != cellHeight)
-      {
-        cellFrame->SetSize(nsSize(cellRect.width, cellHeight));
-        nsTableFrame::InvalidateTableFrame(cellFrame, cellRect,
+      if (cellSize.BSize(wm) != cellBSize) {
+        cellSize.BSize(wm) = cellBSize;
+        nsRect cellOldRect = cellFrame->GetRect();
+        cellFrame->SetSize(wm, cellSize);
+        nsTableFrame::InvalidateTableFrame(cellFrame, cellOldRect,
                                            cellVisualOverflow,
                                            false);
       }
 
       // realign cell content based on the new bsize.  We might be able to
       // skip this if the bsize didn't change... maybe.  Hard to tell.
       cellFrame->BlockDirAlignChild(wm, mMaxCellAscent);
 
@@ -367,20 +372,21 @@ nsTableRowFrame::DidResize()
 
 // returns max-ascent amongst all cells that have 'vertical-align: baseline'
 // *including* cells with rowspans
 nscoord nsTableRowFrame::GetMaxCellAscent() const
 {
   return mMaxCellAscent;
 }
 
-nscoord nsTableRowFrame::GetRowBaseline(WritingMode aWritingMode)
+nscoord nsTableRowFrame::GetRowBaseline(WritingMode aWM)
 {
-  if(mMaxCellAscent)
+  if (mMaxCellAscent) {
     return mMaxCellAscent;
+  }
 
   // If we don't have a baseline on any of the cells we go for the lowest
   // content edge of the inner block frames.
   // Every table cell has a cell frame with its border and padding. Inside
   // the cell is a block frame. The cell is as high as the tallest cell in
   // the parent row. As a consequence the block frame might not touch both
   // the top and the bottom padding of it parent cell frame at the same time.
   //
@@ -394,164 +400,171 @@ nscoord nsTableRowFrame::GetRowBaseline(
   // bp              pb
   // bp              pb
   // bppppppppppppppppb
   // bbbbbbbbbbbbbbbbbb
 
   nsTableIterator iter(*this);
   nsIFrame* childFrame = iter.First();
   nscoord ascent = 0;
+  nscoord containerWidth = GetRect().width;
    while (childFrame) {
     if (IS_TABLE_CELL(childFrame->GetType())) {
       nsIFrame* firstKid = childFrame->GetFirstPrincipalChild();
-      ascent = std::max(ascent, firstKid->GetNormalRect().YMost());
+      ascent = std::max(ascent,
+                        LogicalRect(aWM, firstKid->GetNormalRect(),
+                                    containerWidth).BEnd(aWM));
     }
     // Get the next child
     childFrame = iter.Next();
   }
   return ascent;
 }
+
 nscoord
-nsTableRowFrame::GetHeight(nscoord aPctBasis) const
+nsTableRowFrame::GetBSize(nscoord aPctBasis) const
 {
-  nscoord height = 0;
-  if ((aPctBasis > 0) && HasPctHeight()) {
-    height = NSToCoordRound(GetPctHeight() * (float)aPctBasis);
+  nscoord bsize = 0;
+  if ((aPctBasis > 0) && HasPctBSize()) {
+    bsize = NSToCoordRound(GetPctBSize() * (float)aPctBasis);
   }
-  if (HasFixedHeight()) {
-    height = std::max(height, GetFixedHeight());
+  if (HasFixedBSize()) {
+    bsize = std::max(bsize, GetFixedBSize());
   }
-  return std::max(height, GetContentHeight());
+  return std::max(bsize, GetContentBSize());
 }
 
 void
-nsTableRowFrame::ResetHeight(nscoord aFixedHeight)
+nsTableRowFrame::ResetBSize(nscoord aFixedBSize)
 {
-  SetHasFixedHeight(false);
-  SetHasPctHeight(false);
-  SetFixedHeight(0);
-  SetPctHeight(0);
-  SetContentHeight(0);
+  SetHasFixedBSize(false);
+  SetHasPctBSize(false);
+  SetFixedBSize(0);
+  SetPctBSize(0);
+  SetContentBSize(0);
 
-  if (aFixedHeight > 0) {
-    SetFixedHeight(aFixedHeight);
+  if (aFixedBSize > 0) {
+    SetFixedBSize(aFixedBSize);
   }
 
   mMaxCellAscent = 0;
   mMaxCellDescent = 0;
 }
 
 void
-nsTableRowFrame::UpdateHeight(nscoord           aHeight,
-                              nscoord           aAscent,
-                              nscoord           aDescent,
-                              nsTableFrame*     aTableFrame,
-                              nsTableCellFrame* aCellFrame)
+nsTableRowFrame::UpdateBSize(nscoord           aBSize,
+                             nscoord           aAscent,
+                             nscoord           aDescent,
+                             nsTableFrame*     aTableFrame,
+                             nsTableCellFrame* aCellFrame)
 {
   if (!aTableFrame || !aCellFrame) {
     NS_ASSERTION(false , "invalid call");
     return;
   }
 
-  if (aHeight != NS_UNCONSTRAINEDSIZE) {
+  if (aBSize != NS_UNCONSTRAINEDSIZE) {
     if (!(aCellFrame->HasVerticalAlignBaseline())) { // only the cell's height matters
-      if (GetHeight() < aHeight) {
+      if (GetBSize() < aBSize) {
         int32_t rowSpan = aTableFrame->GetEffectiveRowSpan(*aCellFrame);
         if (rowSpan == 1) {
-          SetContentHeight(aHeight);
+          SetContentBSize(aBSize);
         }
       }
     }
-    else { // the alignment on the baseline can change the height
-      NS_ASSERTION((aAscent != NS_UNCONSTRAINEDSIZE) && (aDescent != NS_UNCONSTRAINEDSIZE), "invalid call");
+    else { // the alignment on the baseline can change the bsize
+      NS_ASSERTION((aAscent != NS_UNCONSTRAINEDSIZE) &&
+                   (aDescent != NS_UNCONSTRAINEDSIZE), "invalid call");
       // see if this is a long ascender
       if (mMaxCellAscent < aAscent) {
         mMaxCellAscent = aAscent;
       }
       // see if this is a long descender and without rowspan
       if (mMaxCellDescent < aDescent) {
         int32_t rowSpan = aTableFrame->GetEffectiveRowSpan(*aCellFrame);
         if (rowSpan == 1) {
           mMaxCellDescent = aDescent;
         }
       }
-      // keep the tallest height in sync
-      if (GetHeight() < mMaxCellAscent + mMaxCellDescent) {
-        SetContentHeight(mMaxCellAscent + mMaxCellDescent);
+      // keep the tallest bsize in sync
+      if (GetBSize() < mMaxCellAscent + mMaxCellDescent) {
+        SetContentBSize(mMaxCellAscent + mMaxCellDescent);
       }
     }
   }
 }
 
 nscoord
-nsTableRowFrame::CalcHeight(const nsHTMLReflowState& aReflowState)
+nsTableRowFrame::CalcBSize(const nsHTMLReflowState& aReflowState)
 {
   nsTableFrame* tableFrame = GetTableFrame();
-  nscoord computedHeight = (NS_UNCONSTRAINEDSIZE == aReflowState.ComputedHeight())
-                            ? 0 : aReflowState.ComputedHeight();
-  ResetHeight(computedHeight);
+  nscoord computedBSize = (NS_UNCONSTRAINEDSIZE == aReflowState.ComputedBSize())
+                            ? 0 : aReflowState.ComputedBSize();
+  ResetBSize(computedBSize);
 
+  WritingMode wm = aReflowState.GetWritingMode();
   const nsStylePosition* position = StylePosition();
-  if (position->mHeight.ConvertsToLength()) {
-    SetFixedHeight(nsRuleNode::ComputeCoordPercentCalc(position->mHeight, 0));
+  const nsStyleCoord& bsizeStyleCoord = position->BSize(wm);
+  if (bsizeStyleCoord.ConvertsToLength()) {
+    SetFixedBSize(nsRuleNode::ComputeCoordPercentCalc(bsizeStyleCoord, 0));
   }
-  else if (eStyleUnit_Percent == position->mHeight.GetUnit()) {
-    SetPctHeight(position->mHeight.GetPercentValue());
+  else if (eStyleUnit_Percent == bsizeStyleCoord.GetUnit()) {
+    SetPctBSize(bsizeStyleCoord.GetPercentValue());
   }
   // calc() with percentages is treated like 'auto' on table rows.
 
   for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame;
        kidFrame = kidFrame->GetNextSibling()) {
     nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
     if (cellFrame) {
-      WritingMode wm = cellFrame->GetWritingMode();
+      MOZ_ASSERT(cellFrame->GetWritingMode() == wm);
       LogicalSize desSize = cellFrame->GetDesiredSize();
-      if ((NS_UNCONSTRAINEDSIZE == aReflowState.AvailableHeight()) && !GetPrevInFlow()) {
-        CalculateCellActualHeight(cellFrame, desSize.BSize(wm));
+      if ((NS_UNCONSTRAINEDSIZE == aReflowState.AvailableBSize()) && !GetPrevInFlow()) {
+        CalculateCellActualBSize(cellFrame, desSize.BSize(wm), wm);
       }
-      // height may have changed, adjust descent to absorb any excess difference
+      // bsize may have changed, adjust descent to absorb any excess difference
       nscoord ascent;
        if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild())
          ascent = desSize.BSize(wm);
        else
          ascent = cellFrame->GetCellBaseline();
        nscoord descent = desSize.BSize(wm) - ascent;
-       UpdateHeight(desSize.BSize(wm), ascent, descent, tableFrame, cellFrame);
+       UpdateBSize(desSize.BSize(wm), ascent, descent, tableFrame, cellFrame);
     }
   }
-  return GetHeight();
+  return GetBSize();
 }
 
 /**
  * We need a custom display item for table row backgrounds. This is only used
  * when the table row is the root of a stacking context (e.g., has 'opacity').
  * Table row backgrounds can extend beyond the row frame bounds, when
  * the row contains row-spanning cells.
  */
 class nsDisplayTableRowBackground : public nsDisplayTableItem {
 public:
   nsDisplayTableRowBackground(nsDisplayListBuilder* aBuilder,
-                              nsTableRowFrame* aFrame) :
+                              nsTableRowFrame*      aFrame) :
     nsDisplayTableItem(aBuilder, aFrame) {
     MOZ_COUNT_CTOR(nsDisplayTableRowBackground);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayTableRowBackground() {
     MOZ_COUNT_DTOR(nsDisplayTableRowBackground);
   }
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx) override;
+                     nsRenderingContext*   aCtx) override;
   NS_DISPLAY_DECL_NAME("TableRowBackground", TYPE_TABLE_ROW_BACKGROUND)
 };
 
 void
 nsDisplayTableRowBackground::Paint(nsDisplayListBuilder* aBuilder,
-                                   nsRenderingContext* aCtx)
+                                   nsRenderingContext*   aCtx)
 {
   auto rowFrame = static_cast<nsTableRowFrame*>(mFrame);
   TableBackgroundPainter painter(rowFrame->GetTableFrame(),
                                  TableBackgroundPainter::eOrigin_TableRow,
                                  mFrame->PresContext(), *aCtx,
                                  mVisibleRect, ToReferenceFrame(),
                                  aBuilder->GetBackgroundPaintFlags());
 
@@ -594,81 +607,90 @@ nsTableRowFrame::GetLogicalSkipSides(con
     skip |= eLogicalSideBitsBStart;
   }
   if (nullptr != GetNextInFlow()) {
     skip |= eLogicalSideBitsBEnd;
   }
   return skip;
 }
 
-// Calculate the cell's actual height given its pass2  height.
-// Takes into account the specified height (in the style).
-// Modifies the desired height that is passed in.
+// Calculate the cell's actual bsize given its pass2 bsize.
+// Takes into account the specified bsize (in the style).
+// Modifies the desired bsize that is passed in.
 nsresult
-nsTableRowFrame::CalculateCellActualHeight(nsTableCellFrame* aCellFrame,
-                                           nscoord&          aDesiredHeight)
+nsTableRowFrame::CalculateCellActualBSize(nsTableCellFrame* aCellFrame,
+                                          nscoord&          aDesiredBSize,
+                                          WritingMode       aWM)
 {
-  nscoord specifiedHeight = 0;
+  nscoord specifiedBSize = 0;
 
-  // Get the height specified in the style information
+  // Get the bsize specified in the style information
   const nsStylePosition* position = aCellFrame->StylePosition();
 
   int32_t rowSpan = GetTableFrame()->GetEffectiveRowSpan(*aCellFrame);
 
-  switch (position->mHeight.GetUnit()) {
+  const nsStyleCoord& bsizeStyleCoord = position->BSize(aWM);
+  switch (bsizeStyleCoord.GetUnit()) {
     case eStyleUnit_Calc: {
-      if (position->mHeight.CalcHasPercent()) {
+      if (bsizeStyleCoord.CalcHasPercent()) {
         // Treat this like "auto"
         break;
       }
       // Fall through to the coord case
     }
     case eStyleUnit_Coord: {
       nscoord outsideBoxSizing = 0;
-      // In quirks mode, table cell width should be content-box, but height
+      // In quirks mode, table cell isize should be content-box, but bsize
       // should be border-box.
       // Because of this historic anomaly, we do not use quirk.css
-      // (since we can't specify one value of box-sizing for width and another
-      // for height)
+      // (since we can't specify one value of box-sizing for isize and another
+      // for bsize)
       if (PresContext()->CompatibilityMode() != eCompatibility_NavQuirks) {
         switch (position->mBoxSizing) {
           case NS_STYLE_BOX_SIZING_CONTENT:
-            outsideBoxSizing = aCellFrame->GetUsedBorderAndPadding().TopBottom();
+            outsideBoxSizing =
+              aCellFrame->GetLogicalUsedBorderAndPadding(aWM).BStartEnd(aWM);
             break;
           case NS_STYLE_BOX_SIZING_PADDING:
-            outsideBoxSizing = aCellFrame->GetUsedBorder().TopBottom();
+            outsideBoxSizing =
+              aCellFrame->GetLogicalUsedBorder(aWM).BStartEnd(aWM);
             break;
           default:
             // NS_STYLE_BOX_SIZING_BORDER
             break;
         }
       }
 
-      specifiedHeight =
-        nsRuleNode::ComputeCoordPercentCalc(position->mHeight, 0) +
-          outsideBoxSizing;
+      specifiedBSize =
+        nsRuleNode::ComputeCoordPercentCalc(bsizeStyleCoord, 0) +
+        outsideBoxSizing;
 
-      if (1 == rowSpan)
-        SetFixedHeight(specifiedHeight);
+      if (1 == rowSpan) {
+        SetFixedBSize(specifiedBSize);
+      }
       break;
     }
     case eStyleUnit_Percent: {
-      if (1 == rowSpan)
-        SetPctHeight(position->mHeight.GetPercentValue());
-      // pct heights are handled when all of the cells are finished, so don't set specifiedHeight
+      if (1 == rowSpan) {
+        SetPctBSize(bsizeStyleCoord.GetPercentValue());
+      }
+      // pct bsizes are handled when all of the cells are finished,
+      // so don't set specifiedBSize
       break;
     }
     case eStyleUnit_Auto:
     default:
       break;
   }
 
-  // If the specified height is greater than the desired height, then use the specified height
-  if (specifiedHeight > aDesiredHeight)
-    aDesiredHeight = specifiedHeight;
+  // If the specified bsize is greater than the desired bsize,
+  // then use the specified bsize
+  if (specifiedBSize > aDesiredBSize) {
+    aDesiredBSize = specifiedBSize;
+  }
 
   return NS_OK;
 }
 
 // Calculates the available isize for the table cell based on the known
 // column isizes taking into account column spans and column spacing
 static nscoord
 CalcAvailISize(nsTableFrame&     aTableFrame,
@@ -690,144 +712,126 @@ CalcAvailISize(nsTableFrame&     aTableF
   return cellAvailISize;
 }
 
 nscoord
 GetSpaceBetween(int32_t       aPrevColIndex,
                 int32_t       aColIndex,
                 int32_t       aColSpan,
                 nsTableFrame& aTableFrame,
-                bool          aIsLeftToRight,
                 bool          aCheckVisibility)
 {
   nscoord space = 0;
   int32_t colX;
-  if (aIsLeftToRight) {
-    for (colX = aPrevColIndex + 1; aColIndex > colX; colX++) {
-      bool isCollapsed = false;
-      if (!aCheckVisibility) {
-        space += aTableFrame.GetColumnISize(colX);
-      }
-      else {
-        nsTableColFrame* colFrame = aTableFrame.GetColFrame(colX);
-        const nsStyleVisibility* colVis = colFrame->StyleVisibility();
-        bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
-        nsIFrame* cgFrame = colFrame->GetParent();
-        const nsStyleVisibility* groupVis = cgFrame->StyleVisibility();
-        bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE ==
-                                groupVis->mVisible);
-        isCollapsed = collapseCol || collapseGroup;
-        if (!isCollapsed)
-          space += aTableFrame.GetColumnISize(colX);
-      }
-      if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) {
-        space += aTableFrame.GetColSpacing(colX - 1);
-      }
+  for (colX = aPrevColIndex + 1; aColIndex > colX; colX++) {
+    bool isCollapsed = false;
+    if (!aCheckVisibility) {
+      space += aTableFrame.GetColumnISize(colX);
     }
-  }
-  else {
-    int32_t lastCol = aColIndex + aColSpan - 1;
-    for (colX = aPrevColIndex - 1; colX > lastCol; colX--) {
-      bool isCollapsed = false;
-      if (!aCheckVisibility) {
+    else {
+      nsTableColFrame* colFrame = aTableFrame.GetColFrame(colX);
+      const nsStyleVisibility* colVis = colFrame->StyleVisibility();
+      bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
+      nsIFrame* cgFrame = colFrame->GetParent();
+      const nsStyleVisibility* groupVis = cgFrame->StyleVisibility();
+      bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE ==
+                              groupVis->mVisible);
+      isCollapsed = collapseCol || collapseGroup;
+      if (!isCollapsed)
         space += aTableFrame.GetColumnISize(colX);
-      }
-      else {
-        nsTableColFrame* colFrame = aTableFrame.GetColFrame(colX);
-        const nsStyleVisibility* colVis = colFrame->StyleVisibility();
-        bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
-        nsIFrame* cgFrame = colFrame->GetParent();
-        const nsStyleVisibility* groupVis = cgFrame->StyleVisibility();
-        bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE ==
-                                groupVis->mVisible);
-        isCollapsed = collapseCol || collapseGroup;
-        if (!isCollapsed)
-          space += aTableFrame.GetColumnISize(colX);
-      }
-      if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) {
-        space += aTableFrame.GetColSpacing(colX - 1);
-      }
+    }
+    if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) {
+      space += aTableFrame.GetColSpacing(colX - 1);
     }
   }
   return space;
 }
 
-// subtract the heights of aRow's prev in flows from the unpaginated height
+// subtract the bsizes of aRow's prev in flows from the unpaginated bsize
 static
-nscoord CalcHeightFromUnpaginatedHeight(nsPresContext*   aPresContext,
-                                        nsTableRowFrame& aRow)
+nscoord CalcBSizeFromUnpaginatedBSize(nsPresContext*   aPresContext,
+                                      nsTableRowFrame& aRow,
+                                      WritingMode      aWM)
 {
-  nscoord height = 0;
+  nscoord bsize = 0;
   nsTableRowFrame* firstInFlow =
     static_cast<nsTableRowFrame*>(aRow.FirstInFlow());
-  if (firstInFlow->HasUnpaginatedHeight()) {
-    height = firstInFlow->GetUnpaginatedHeight(aPresContext);
+  if (firstInFlow->HasUnpaginatedBSize()) {
+    bsize = firstInFlow->GetUnpaginatedBSize(aPresContext);
     for (nsIFrame* prevInFlow = aRow.GetPrevInFlow(); prevInFlow;
          prevInFlow = prevInFlow->GetPrevInFlow()) {
-      height -= prevInFlow->GetSize().height;
+      bsize -= prevInFlow->BSize(aWM);
     }
   }
-  return std::max(height, 0);
+  return std::max(bsize, 0);
 }
 
 void
-nsTableRowFrame::ReflowChildren(nsPresContext*          aPresContext,
+nsTableRowFrame::ReflowChildren(nsPresContext*           aPresContext,
                                 nsHTMLReflowMetrics&     aDesiredSize,
                                 const nsHTMLReflowState& aReflowState,
                                 nsTableFrame&            aTableFrame,
                                 nsReflowStatus&          aStatus)
 {
   aStatus = NS_FRAME_COMPLETE;
 
-  // XXXldb Should we be checking constrained height instead?
+  // XXXldb Should we be checking constrained bsize instead?
   const bool isPaginated = aPresContext->IsPaginated();
   const bool borderCollapse = aTableFrame.IsBorderCollapse();
 
   int32_t cellColSpan = 1;  // must be defined here so it's set properly for non-cell kids
 
   nsTableIterator iter(*this);
   // remember the col index of the previous cell to handle rowspans into this row
-  int32_t firstPrevColIndex = (iter.IsLeftToRight()) ? -1 : aTableFrame.GetColCount();
+  int32_t firstPrevColIndex = -1;
   int32_t prevColIndex  = firstPrevColIndex;
-  nscoord x = 0; // running total of children x offset
+  nscoord iCoord = 0; // running total of children inline-coord offset
 
-  // This computes the max of all cell heights
-  nscoord cellMaxHeight = 0;
+  // This computes the max of all cell bsizes
+  nscoord cellMaxBSize = 0;
 
   // Reflow each of our existing cell frames
+  WritingMode wm = aReflowState.GetWritingMode();
+  nscoord containerWidth = aReflowState.ComputedWidth();
+  if (containerWidth == NS_UNCONSTRAINEDSIZE) {
+    containerWidth = 0; // cell positions will not yet be correct
+  } else {
+    containerWidth += aReflowState.ComputedPhysicalBorderPadding().LeftRight();
+  }
+
   for (nsIFrame* kidFrame = iter.First(); kidFrame; kidFrame = iter.Next()) {
     nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
     if (!cellFrame) {
       // XXXldb nsCSSFrameConstructor needs to enforce this!
       NS_NOTREACHED("yikes, a non-row child");
 
       // it's an unknown frame type, give it a generic reflow and ignore the results
       nsTableCellReflowState
         kidReflowState(aPresContext, aReflowState, kidFrame,
                        LogicalSize(kidFrame->GetWritingMode(), 0, 0),
                        nsHTMLReflowState::CALLER_WILL_INIT);
-      InitChildReflowState(*aPresContext, nsSize(0,0), false, kidReflowState);
+      InitChildReflowState(*aPresContext, LogicalSize(wm), false, kidReflowState);
       nsHTMLReflowMetrics desiredSize(aReflowState);
       nsReflowStatus  status;
       ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, status);
       kidFrame->DidReflow(aPresContext, nullptr, nsDidReflowStatus::FINISHED);
 
       continue;
     }
 
     // See if we should only reflow the dirty child frames
     bool doReflowChild = true;
     if (!aReflowState.ShouldReflowAllKids() &&
         !aTableFrame.IsGeometryDirty() &&
         !NS_SUBTREE_DIRTY(kidFrame)) {
       if (!aReflowState.mFlags.mSpecialHeightReflow)
         doReflowChild = false;
     }
-    else if ((NS_UNCONSTRAINEDSIZE != aReflowState.AvailableHeight())) {
-      // We don't reflow a rowspan >1 cell here with a constrained height.
+    else if ((NS_UNCONSTRAINEDSIZE != aReflowState.AvailableBSize())) {
+      // We don't reflow a rowspan >1 cell here with a constrained bsize.
       // That happens in nsTableRowGroupFrame::SplitSpanningCells.
       if (aTableFrame.GetEffectiveRowSpan(*cellFrame) > 1) {
         doReflowChild = false;
       }
     }
     if (aReflowState.mFlags.mSpecialHeightReflow) {
       if (!isPaginated && !(cellFrame->GetStateBits() &
                             NS_FRAME_CONTAINS_RELATIVE_BSIZE)) {
@@ -835,39 +839,40 @@ nsTableRowFrame::ReflowChildren(nsPresCo
       }
     }
 
     int32_t cellColIndex;
     cellFrame->GetColIndex(cellColIndex);
     cellColSpan = aTableFrame.GetEffectiveColSpan(*cellFrame);
 
     // If the adjacent cell is in a prior row (because of a rowspan) add in the space
-    if ((iter.IsLeftToRight() && (prevColIndex != (cellColIndex - 1))) ||
-        (!iter.IsLeftToRight() && (prevColIndex != cellColIndex + cellColSpan))) {
-      x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan, aTableFrame,
-                           iter.IsLeftToRight(), false);
+    if (prevColIndex != (cellColIndex - 1)) {
+      iCoord += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan, aTableFrame,
+                                false);
     }
 
     // remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
-    prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
+    prevColIndex = cellColIndex + (cellColSpan - 1);
 
     // Reflow the child frame
     nsRect kidRect = kidFrame->GetRect();
-    nsPoint origKidNormalPosition = kidFrame->GetNormalPosition();
-    MOZ_ASSERT(origKidNormalPosition.y == 0);
+    LogicalPoint origKidNormalPosition =
+      kidFrame->GetLogicalNormalPosition(wm, containerWidth);
+    // All cells' no-relative-positioning position should be snapped to the
+    // row's bstart edge.
+    MOZ_ASSERT(origKidNormalPosition.B(wm) == 0);
     nsRect kidVisualOverflow = kidFrame->GetVisualOverflowRect();
-    nsPoint kidPosition(x, 0);
+    LogicalPoint kidPosition(wm, iCoord, 0);
     bool firstReflow =
       (kidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
 
     if (doReflowChild) {
       // Calculate the available isize for the table cell using the known
       // column isizes
-      nscoord availCellISize =
-        CalcAvailISize(aTableFrame, *cellFrame);
+      nscoord availCellISize = CalcAvailISize(aTableFrame, *cellFrame);
 
       Maybe<nsTableCellReflowState> kidReflowState;
       nsHTMLReflowMetrics desiredSize(aReflowState);
 
       // If the avail isize is not the same as last time we reflowed the cell or
       // the cell wants to be bigger than what was available last time or
       // it is a style change reflow or we are printing, then we must reflow the
       // cell. Otherwise we can skip the reflow.
@@ -878,198 +883,228 @@ nsTableRowFrame::ReflowChildren(nsPresCo
       LogicalSize cellDesiredSize = cellFrame->GetDesiredSize();
       if ((availCellISize != cellFrame->GetPriorAvailISize())       ||
           (cellDesiredSize.ISize(wm) > cellFrame->GetPriorAvailISize()) ||
           (GetStateBits() & NS_FRAME_IS_DIRTY)                      ||
           isPaginated                                               ||
           NS_SUBTREE_DIRTY(cellFrame)                               ||
           // See if it needs a special reflow, or if it had one that we need to undo.
           (cellFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE) ||
-          HasPctHeight()) {
+          HasPctBSize()) {
         // Reflow the cell to fit the available isize, bsize
         // XXX The old IR_ChildIsDirty code used availCellISize here.
         LogicalSize kidAvailSize(wm, availCellISize, aReflowState.AvailableBSize());
 
         // Reflow the child
         kidReflowState.emplace(aPresContext, aReflowState, kidFrame,
                                kidAvailSize,
                                // Cast needed for gcc 4.4.
                                uint32_t(nsHTMLReflowState::CALLER_WILL_INIT));
-        InitChildReflowState(*aPresContext, kidAvailSize.GetPhysicalSize(wm),
-                             borderCollapse, *kidReflowState);
+        InitChildReflowState(*aPresContext, kidAvailSize, borderCollapse,
+                             *kidReflowState);
 
         nsReflowStatus status;
         ReflowChild(kidFrame, aPresContext, desiredSize, *kidReflowState,
-                    x, 0, 0, status);
+                    wm, kidPosition, containerWidth, 0, status);
 
         // allow the table to determine if/how the table needs to be rebalanced
         // If any of the cells are not complete, then we're not complete
         if (NS_FRAME_IS_NOT_COMPLETE(status)) {
           aStatus = NS_FRAME_NOT_COMPLETE;
         }
-      }
-      else {
-        if (x != origKidNormalPosition.x) {
+      } else {
+        if (iCoord != origKidNormalPosition.I(wm)) {
           kidFrame->InvalidateFrameSubtree();
         }
 
         desiredSize.SetSize(wm, cellDesiredSize);
         desiredSize.mOverflowAreas = cellFrame->GetOverflowAreas();
 
         // if we are in a floated table, our position is not yet established, so we cannot reposition our views
         // the containing block will do this for us after positioning the table
         if (!aTableFrame.IsFloating()) {
           // Because we may have moved the frame we need to make sure any views are
           // positioned properly. We have to do this, because any one of our parent
           // frames could have moved and we have no way of knowing...
           nsTableFrame::RePositionViews(kidFrame);
         }
       }
 
-      if (NS_UNCONSTRAINEDSIZE == aReflowState.AvailableHeight()) {
+      if (NS_UNCONSTRAINEDSIZE == aReflowState.AvailableBSize()) {
         if (!GetPrevInFlow()) {
-          // Calculate the cell's actual height given its pass2 height. This
-          // function takes into account the specified height (in the style)
-          CalculateCellActualHeight(cellFrame, desiredSize.Height());
+          // Calculate the cell's actual bsize given its pass2 bsize. This
+          // function takes into account the specified bsize (in the style)
+          CalculateCellActualBSize(cellFrame, desiredSize.BSize(wm), wm);
         }
-        // height may have changed, adjust descent to absorb any excess difference
+        // bsize may have changed, adjust descent to absorb any excess difference
         nscoord ascent;
         if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild()) {
           ascent = desiredSize.BSize(wm);
         } else {
           ascent = ((nsTableCellFrame *)kidFrame)->GetCellBaseline();
         }
         nscoord descent = desiredSize.BSize(wm) - ascent;
-        UpdateHeight(desiredSize.BSize(wm), ascent, descent, &aTableFrame, cellFrame);
-      }
-      else {
-        cellMaxHeight = std::max(cellMaxHeight, desiredSize.Height());
+        UpdateBSize(desiredSize.BSize(wm), ascent, descent, &aTableFrame, cellFrame);
+      } else {
+        cellMaxBSize = std::max(cellMaxBSize, desiredSize.BSize(wm));
         int32_t rowSpan = aTableFrame.GetEffectiveRowSpan((nsTableCellFrame&)*kidFrame);
         if (1 == rowSpan) {
-          SetContentHeight(cellMaxHeight);
+          SetContentBSize(cellMaxBSize);
         }
       }
 
       // Place the child
       desiredSize.ISize(wm) = availCellISize;
 
       if (kidReflowState) {
         // We reflowed. Apply relative positioning in the normal way.
-        kidReflowState->ApplyRelativePositioning(&kidPosition);
+        kidReflowState->ApplyRelativePositioning(&kidPosition, containerWidth);
       } else if (kidFrame->IsRelativelyPositioned()) {
         // We didn't reflow.  Do the positioning part of what
         // MovePositionBy does internally.  (This codepath should really
         // be merged into the else below if we can.)
-        const nsMargin* computedOffsets = static_cast<nsMargin*>
-          (kidFrame->Properties().Get(nsIFrame::ComputedOffsetProperty()));
-        nsHTMLReflowState::ApplyRelativePositioning(kidFrame, *computedOffsets,
-                                                    &kidPosition);
+        LogicalMargin computedOffsets(wm, *static_cast<nsMargin*>
+          (kidFrame->Properties().Get(nsIFrame::ComputedOffsetProperty())));
+        nsHTMLReflowState::ApplyRelativePositioning(kidFrame, wm, computedOffsets,
+                                                    &kidPosition, containerWidth);
       }
+
+      // In vertical-rl writing mode, we are likely to have containerWidth 0
+      // because ComputedWidth() was NS_UNCONSTRAINEDSIZE. The true value
+      // we need is the row's bsize, but we don't know that yet. So we'll use
+      // the kid's (cell's) desiredSize.Width() value for now.
+      // For cases where that's wrong, we will fix up the position later.
       FinishReflowChild(kidFrame, aPresContext, desiredSize, nullptr,
-                        kidPosition.x, kidPosition.y, 0);
+                        wm, kidPosition,
+                        wm.IsVerticalRL() && containerWidth == 0
+                          ? desiredSize.Width()
+                          : containerWidth,
+                        0);
 
       nsTableFrame::InvalidateTableFrame(kidFrame, kidRect, kidVisualOverflow,
                                          firstReflow);
 
-      x += desiredSize.Width();
-    }
-    else {
-      if (x != origKidNormalPosition.x) {
+      iCoord += desiredSize.ISize(wm);
+    } else {
+      if (iCoord != origKidNormalPosition.I(wm)) {
         // Invalidate the old position
         kidFrame->InvalidateFrameSubtree();
         // Move to the new position. As above, we need to account for relative
         // positioning.
-        kidFrame->MovePositionBy(nsPoint(x - origKidNormalPosition.x, 0));
+        kidFrame->MovePositionBy(wm,
+          LogicalPoint(wm, iCoord - origKidNormalPosition.I(wm), 0));
         nsTableFrame::RePositionViews(kidFrame);
         // invalidate the new position
         kidFrame->InvalidateFrameSubtree();
       }
-      // we need to account for the cell's width even if it isn't reflowed
-      x += kidRect.width;
+      // we need to account for the cell's isize even if it isn't reflowed
+      iCoord += kidFrame->ISize(wm);
 
       if (kidFrame->GetNextInFlow()) {
         aStatus = NS_FRAME_NOT_COMPLETE;
       }
     }
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kidFrame);
-    x += aTableFrame.GetColSpacing(cellColIndex);
+    iCoord += aTableFrame.GetColSpacing(cellColIndex);
   }
 
-  // just set our width to what was available. The table will calculate the width and not use our value.
-  aDesiredSize.Width() = aReflowState.AvailableWidth();
+  // Just set our isize to what was available.
+  // The table will calculate the isize and not use our value.
+  aDesiredSize.ISize(wm) = aReflowState.AvailableISize();
 
   if (aReflowState.mFlags.mSpecialHeightReflow) {
-    aDesiredSize.Height() = mRect.height;
-  }
-  else if (NS_UNCONSTRAINEDSIZE == aReflowState.AvailableHeight()) {
-    aDesiredSize.Height() = CalcHeight(aReflowState);
+    aDesiredSize.BSize(wm) = BSize(wm);
+  } else if (NS_UNCONSTRAINEDSIZE == aReflowState.AvailableBSize()) {
+    aDesiredSize.BSize(wm) = CalcBSize(aReflowState);
     if (GetPrevInFlow()) {
-      nscoord height = CalcHeightFromUnpaginatedHeight(aPresContext, *this);
-      aDesiredSize.Height() = std::max(aDesiredSize.Height(), height);
+      nscoord bsize = CalcBSizeFromUnpaginatedBSize(aPresContext, *this, wm);
+      aDesiredSize.BSize(wm) = std::max(aDesiredSize.BSize(wm), bsize);
+    } else {
+      if (isPaginated && HasStyleBSize()) {
+        // set the unpaginated bsize so next in flows can try to honor it
+        SetHasUnpaginatedBSize(true);
+        SetUnpaginatedBSize(aPresContext, aDesiredSize.BSize(wm));
+      }
+      if (isPaginated && HasUnpaginatedBSize()) {
+        aDesiredSize.BSize(wm) = std::max(aDesiredSize.BSize(wm),
+                                          GetUnpaginatedBSize(aPresContext));
+      }
     }
-    else {
-      if (isPaginated && HasStyleHeight()) {
-        // set the unpaginated height so next in flows can try to honor it
-        SetHasUnpaginatedHeight(true);
-        SetUnpaginatedHeight(aPresContext, aDesiredSize.Height());
+  } else { // constrained bsize, paginated
+    // Compute the bsize we should have from style (subtracting the
+    // bsize from our prev-in-flows from the style bsize)
+    nscoord styleBSize = CalcBSizeFromUnpaginatedBSize(aPresContext, *this,
+                                                       wm);
+    if (styleBSize > aReflowState.AvailableBSize()) {
+      styleBSize = aReflowState.AvailableBSize();
+      NS_FRAME_SET_INCOMPLETE(aStatus);
+    }
+    aDesiredSize.BSize(wm) = std::max(cellMaxBSize, styleBSize);
+  }
+
+  if (wm.IsVerticalRL()) {
+    // Any children whose width was not the same as our final
+    // aDesiredSize.BSize will have been misplaced earlier at the
+    // FinishReflowChild stage. So fix them up now.
+    for (nsIFrame* kidFrame = iter.First(); kidFrame; kidFrame = iter.Next()) {
+      nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
+      if (!cellFrame) {
+        continue;
       }
-      if (isPaginated && HasUnpaginatedHeight()) {
-        aDesiredSize.Height() = std::max(aDesiredSize.Height(), GetUnpaginatedHeight(aPresContext));
+      if (kidFrame->BSize(wm) != aDesiredSize.BSize(wm)) {
+        kidFrame->MovePositionBy(wm,
+          LogicalPoint(wm, 0, kidFrame->BSize(wm) - aDesiredSize.BSize(wm)));
+        nsTableFrame::RePositionViews(kidFrame);
+        // Do we need to InvalidateFrameSubtree() here?
       }
     }
   }
-  else { // constrained height, paginated
-    // Compute the height we should have from style (subtracting the
-    // height from our prev-in-flows from the style height)
-    nscoord styleHeight = CalcHeightFromUnpaginatedHeight(aPresContext, *this);
-    if (styleHeight > aReflowState.AvailableHeight()) {
-      styleHeight = aReflowState.AvailableHeight();
-      NS_FRAME_SET_INCOMPLETE(aStatus);
-    }
-    aDesiredSize.Height() = std::max(cellMaxHeight, styleHeight);
-  }
+
   aDesiredSize.UnionOverflowAreasWithDesiredBounds();
   FinishAndStoreOverflow(&aDesiredSize);
 }
 
 /** Layout the entire row.
-  * This method stacks cells horizontally according to HTML 4.0 rules.
+  * This method stacks cells in the inline dir according to HTML 4.0 rules.
   */
 void
-nsTableRowFrame::Reflow(nsPresContext*          aPresContext,
+nsTableRowFrame::Reflow(nsPresContext*           aPresContext,
                         nsHTMLReflowMetrics&     aDesiredSize,
                         const nsHTMLReflowState& aReflowState,
                         nsReflowStatus&          aStatus)
 {
   MarkInReflow();
   DO_GLOBAL_REFLOW_COUNT("nsTableRowFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
 
+  WritingMode wm = aReflowState.GetWritingMode();
+
   nsTableFrame* tableFrame = GetTableFrame();
   const nsStyleVisibility* rowVis = StyleVisibility();
   bool collapseRow = (NS_STYLE_VISIBILITY_COLLAPSE == rowVis->mVisible);
   if (collapseRow) {
     tableFrame->SetNeedToCollapse(true);
   }
 
   // see if a special height reflow needs to occur due to having a pct height
   nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
 
-  // See if we have a cell with specified/pct height
-  InitHasCellWithStyleHeight(tableFrame);
+  // See if we have a cell with specified/pct bsize
+  InitHasCellWithStyleBSize(tableFrame);
 
   ReflowChildren(aPresContext, aDesiredSize, aReflowState, *tableFrame, aStatus);
 
   if (aPresContext->IsPaginated() && !NS_FRAME_IS_FULLY_COMPLETE(aStatus) &&
       ShouldAvoidBreakInside(aReflowState)) {
     aStatus = NS_INLINE_LINE_BREAK_BEFORE();
   }
 
-  // just set our width to what was available. The table will calculate the width and not use our value.
-  aDesiredSize.Width() = aReflowState.AvailableWidth();
+  // Just set our isize to what was available.
+  // The table will calculate the isize and not use our value.
+  aDesiredSize.ISize(wm) = aReflowState.AvailableISize();
 
   // If our parent is in initial reflow, it'll handle invalidating our
   // entire overflow rect.
   if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW) &&
       nsSize(aDesiredSize.Width(), aDesiredSize.Height()) != mRect.Size()) {
     InvalidateFrame();
   }
 
@@ -1082,236 +1117,243 @@ nsTableRowFrame::Reflow(nsPresContext*  
 }
 
 /**
  * This function is called by the row group frame's SplitRowGroup() code when
  * pushing a row frame that has cell frames that span into it. The cell frame
  * should be reflowed with the specified height
  */
 nscoord
-nsTableRowFrame::ReflowCellFrame(nsPresContext*          aPresContext,
+nsTableRowFrame::ReflowCellFrame(nsPresContext*           aPresContext,
                                  const nsHTMLReflowState& aReflowState,
                                  bool                     aIsTopOfPage,
                                  nsTableCellFrame*        aCellFrame,
-                                 nscoord                  aAvailableHeight,
+                                 nscoord                  aAvailableBSize,
                                  nsReflowStatus&          aStatus)
 {
   WritingMode wm = aReflowState.GetWritingMode();
 
   // Reflow the cell frame with the specified height. Use the existing width
-  nsRect cellRect = aCellFrame->GetRect();
+  nscoord containerWidth = aCellFrame->GetSize().width;
+  LogicalRect cellRect = aCellFrame->GetLogicalRect(wm, containerWidth);
   nsRect cellVisualOverflow = aCellFrame->GetVisualOverflowRect();
 
-  nsSize availSize(cellRect.width, aAvailableHeight);
+  LogicalSize cellSize = cellRect.Size(wm);
+  LogicalSize availSize(wm, cellRect.ISize(wm), aAvailableBSize);
   bool borderCollapse = GetTableFrame()->IsBorderCollapse();
   NS_ASSERTION(aCellFrame->GetWritingMode() == wm,
                "expected consistent writing-mode within table");
   nsTableCellReflowState
-    cellReflowState(aPresContext, aReflowState, aCellFrame,
-                    LogicalSize(wm, availSize),
+    cellReflowState(aPresContext, aReflowState, aCellFrame, availSize,
                     nsHTMLReflowState::CALLER_WILL_INIT);
   InitChildReflowState(*aPresContext, availSize, borderCollapse, cellReflowState);
   cellReflowState.mFlags.mIsTopOfPage = aIsTopOfPage;
 
   nsHTMLReflowMetrics desiredSize(aReflowState);
 
   ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
               0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
   bool fullyComplete = NS_FRAME_IS_COMPLETE(aStatus) && !NS_FRAME_IS_TRUNCATED(aStatus);
   if (fullyComplete) {
-    desiredSize.Height() = aAvailableHeight;
+    desiredSize.BSize(wm) = aAvailableBSize;
   }
-  aCellFrame->SetSize(nsSize(cellRect.width, desiredSize.Height()));
+  aCellFrame->SetSize(wm, LogicalSize(wm, cellSize.ISize(wm),
+                                      desiredSize.BSize(wm)));
 
   // Note: BlockDirAlignChild can affect the overflow rect.
   // 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->BlockDirAlignChild(wm, mMaxCellAscent);
   }
 
-  nsTableFrame::InvalidateTableFrame(aCellFrame, cellRect,
+  nsTableFrame::InvalidateTableFrame(aCellFrame,
+                                     cellRect.GetPhysicalRect(wm, containerWidth),
                                      cellVisualOverflow,
                                      (aCellFrame->GetStateBits() &
                                       NS_FRAME_FIRST_REFLOW) != 0);
 
   aCellFrame->DidReflow(aPresContext, nullptr, nsDidReflowStatus::FINISHED);
 
-  return desiredSize.Height();
+  return desiredSize.BSize(wm);
 }
 
 nscoord
 nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
-                                        nscoord aWidth,
+                                        nscoord aISize,
                                         bool    aCollapseGroup,
-                                        bool& aDidCollapse)
+                                        bool&   aDidCollapse)
 {
   const nsStyleVisibility* rowVis = StyleVisibility();
   bool collapseRow = (NS_STYLE_VISIBILITY_COLLAPSE == rowVis->mVisible);
   nsTableFrame* tableFrame =
     static_cast<nsTableFrame*>(GetTableFrame()->FirstInFlow());
   if (collapseRow) {
     tableFrame->SetNeedToCollapse(true);
   }
 
   if (aRowOffset != 0) {
     // We're moving, so invalidate our old position
     InvalidateFrameSubtree();
   }
 
-  nsRect rowRect = GetRect();
-  nsRect oldRect = rowRect;
+  WritingMode wm = GetWritingMode();
+
+  nscoord parentWidth = GetParent()->GetRect().width;
+  LogicalRect rowRect = GetLogicalRect(wm, parentWidth);
+  nsRect oldRect = mRect;
   nsRect oldVisualOverflow = GetVisualOverflowRect();
 
-  rowRect.y -= aRowOffset;
-  rowRect.width  = aWidth;
+  rowRect.BStart(wm) -= aRowOffset;
+  rowRect.ISize(wm)  = aISize;
   nsOverflowAreas overflow;
   nscoord shift = 0;
+  nscoord containerWidth = mRect.width;
 
   if (aCollapseGroup || collapseRow) {
     aDidCollapse = true;
-    shift = rowRect.height;
+    shift = rowRect.BSize(wm);
     nsTableCellFrame* cellFrame = GetFirstCell();
     if (cellFrame) {
       int32_t rowIndex;
       cellFrame->GetRowIndex(rowIndex);
       shift += tableFrame->GetRowSpacing(rowIndex);
       while (cellFrame) {
-        nsRect cRect = cellFrame->GetRect();
+        LogicalRect cRect = cellFrame->GetLogicalRect(wm, containerWidth);
         // If aRowOffset != 0, there's no point in invalidating the cells, since
         // we've already invalidated our overflow area.  Note that we _do_ still
         // need to invalidate if our row is not moving, because the cell might
         // span out of this row, so invalidating our row rect won't do enough.
         if (aRowOffset == 0) {
           InvalidateFrame();
         }
-        cRect.height = 0;
-        cellFrame->SetRect(cRect);
+        cRect.BSize(wm) = 0;
+        cellFrame->SetRect(wm, cRect, containerWidth);
         cellFrame = cellFrame->GetNextCell();
       }
     } else {
       shift += tableFrame->GetRowSpacing(GetRowIndex());
     }
-    rowRect.height = 0;
+    rowRect.BSize(wm) = 0;
   }
   else { // row is not collapsed
     nsTableIterator iter(*this);
     // remember the col index of the previous cell to handle rowspans into this
     // row
-    int32_t firstPrevColIndex = (iter.IsLeftToRight()) ? -1 :
-                                tableFrame->GetColCount();
+    int32_t firstPrevColIndex = -1;
     int32_t prevColIndex  = firstPrevColIndex;
-    nscoord x = 0; // running total of children x offset
+    nscoord iPos = 0; // running total of children inline-axis offset
 
-    int32_t colIncrement = iter.IsLeftToRight() ? 1 : -1;
+    int32_t colIncrement = 1;
 
     nsIFrame* kidFrame = iter.First();
     while (kidFrame) {
       nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
       if (cellFrame) {
         int32_t cellColIndex;
         cellFrame->GetColIndex(cellColIndex);
         int32_t cellColSpan = tableFrame->GetEffectiveColSpan(*cellFrame);
 
         // If the adjacent cell is in a prior row (because of a rowspan) add in
         // the space
-        if ((iter.IsLeftToRight() && (prevColIndex != (cellColIndex - 1))) ||
-            (!iter.IsLeftToRight() &&
-             (prevColIndex != cellColIndex + cellColSpan))) {
-          x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan,
-                               *tableFrame, iter.IsLeftToRight(),
-                               true);
+        if (prevColIndex != (cellColIndex - 1)) {
+          iPos += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan,
+                                  *tableFrame, true);
         }
-        nsRect cRect(x, 0, 0, rowRect.height);
+        LogicalRect cRect(wm, iPos, 0, 0, rowRect.BSize(wm));
 
-        // remember the rightmost (ltr) or leftmost (rtl) column this cell
-        // spans into
-        prevColIndex = (iter.IsLeftToRight()) ?
-                       cellColIndex + (cellColSpan - 1) : cellColIndex;
-        int32_t startIndex = (iter.IsLeftToRight()) ?
-                             cellColIndex : cellColIndex + (cellColSpan - 1);
+        // remember the last (iend-wards-most) column this cell spans into
+        prevColIndex = cellColIndex + cellColSpan - 1;
+        int32_t startIndex = cellColIndex;
         int32_t actualColSpan = cellColSpan;
         bool isVisible = false;
         for (int32_t colX = startIndex; actualColSpan > 0;
              colX += colIncrement, actualColSpan--) {
 
           nsTableColFrame* colFrame = tableFrame->GetColFrame(colX);
           const nsStyleVisibility* colVis = colFrame->StyleVisibility();
           bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE ==
                                 colVis->mVisible);
           nsIFrame* cgFrame = colFrame->GetParent();
           const nsStyleVisibility* groupVis = cgFrame->StyleVisibility();
           bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE ==
                                   groupVis->mVisible);
           bool isCollapsed = collapseCol || collapseGroup;
           if (!isCollapsed) {
-            cRect.width += tableFrame->GetColumnISize(colX);
+            cRect.ISize(wm) += tableFrame->GetColumnISize(colX);
             isVisible = true;
             if ((actualColSpan > 1)) {
               nsTableColFrame* nextColFrame =
                 tableFrame->GetColFrame(colX + colIncrement);
               const nsStyleVisibility* nextColVis =
               nextColFrame->StyleVisibility();
               if ( (NS_STYLE_VISIBILITY_COLLAPSE != nextColVis->mVisible) &&
                   tableFrame->ColumnHasCellSpacingBefore(colX + colIncrement)) {
-                cRect.width += tableFrame->GetColSpacing(cellColIndex);
+                cRect.ISize(wm) += tableFrame->GetColSpacing(cellColIndex);
               }
             }
           }
         }
-        x += cRect.width;
-        if (isVisible)
-          x += tableFrame->GetColSpacing(cellColIndex);
+        iPos += cRect.ISize(wm);
+        if (isVisible) {
+          iPos += tableFrame->GetColSpacing(cellColIndex);
+        }
         int32_t actualRowSpan = tableFrame->GetEffectiveRowSpan(*cellFrame);
         nsTableRowFrame* rowFrame = GetNextRow();
         for (actualRowSpan--; actualRowSpan > 0 && rowFrame; actualRowSpan--) {
           const nsStyleVisibility* nextRowVis = rowFrame->StyleVisibility();
           bool collapseNextRow = (NS_STYLE_VISIBILITY_COLLAPSE ==
                                     nextRowVis->mVisible);
           if (!collapseNextRow) {
-            nsRect nextRect = rowFrame->GetRect();
-            cRect.height += nextRect.height +
-                            tableFrame->GetRowSpacing(rowFrame->GetRowIndex());
+            LogicalRect nextRect = rowFrame->GetLogicalRect(wm,
+                                                            containerWidth);
+            cRect.BSize(wm) +=
+              nextRect.BSize(wm) +
+              tableFrame->GetRowSpacing(rowFrame->GetRowIndex());
           }
           rowFrame = rowFrame->GetNextRow();
         }
 
         nsRect oldCellRect = cellFrame->GetRect();
-        nsPoint oldCellNormalPos = cellFrame->GetNormalPosition();
+        LogicalPoint oldCellNormalPos =
+          cellFrame->GetLogicalNormalPosition(wm, containerWidth);
+
         nsRect oldCellVisualOverflow = cellFrame->GetVisualOverflowRect();
 
-        if (aRowOffset == 0 && cRect.TopLeft() != oldCellNormalPos) {
+        if (aRowOffset == 0 && cRect.Origin(wm) != oldCellNormalPos) {
           // We're moving the cell.  Invalidate the old overflow area
           cellFrame->InvalidateFrameSubtree();
         }
 
-        cellFrame->MovePositionBy(cRect.TopLeft() - oldCellNormalPos);
-        cellFrame->SetSize(cRect.Size());
+        cellFrame->MovePositionBy(wm, cRect.Origin(wm) - oldCellNormalPos);
+        cellFrame->SetSize(wm, cRect.Size(wm));
 
         // XXXbz This looks completely bogus in the cases when we didn't
         // collapse the cell!
-        nsRect cellBounds(0, 0, cRect.width, cRect.height);
-        nsOverflowAreas cellOverflow(cellBounds, cellBounds);
-        cellFrame->FinishAndStoreOverflow(cellOverflow, cRect.Size());
+        LogicalRect cellBounds(wm, 0, 0, cRect.ISize(wm), cRect.BSize(wm));
+        nsRect cellPhysicalBounds =
+          cellBounds.GetPhysicalRect(wm, containerWidth);
+        nsOverflowAreas cellOverflow(cellPhysicalBounds, cellPhysicalBounds);
+        cellFrame->FinishAndStoreOverflow(cellOverflow,
+                                          cRect.Size(wm).GetPhysicalSize(wm));
         nsTableFrame::RePositionViews(cellFrame);
         ConsiderChildOverflow(overflow, cellFrame);
 
         if (aRowOffset == 0) {
           nsTableFrame::InvalidateTableFrame(cellFrame, oldCellRect,
-                                             oldCellVisualOverflow,
-                                             false);
+                                             oldCellVisualOverflow, false);
         }
       }
       kidFrame = iter.Next(); // Get the next child
     }
   }
 
-  SetRect(rowRect);
-  overflow.UnionAllWith(nsRect(0, 0, rowRect.width, rowRect.height));
-  FinishAndStoreOverflow(overflow, rowRect.Size());
+  SetRect(wm, rowRect, containerWidth);
+  overflow.UnionAllWith(nsRect(0, 0, rowRect.Width(wm), rowRect.Height(wm)));
+  FinishAndStoreOverflow(overflow, rowRect.Size(wm).GetPhysicalSize(wm));
 
   nsTableFrame::RePositionViews(this);
   nsTableFrame::InvalidateTableFrame(this, oldRect, oldVisualOverflow, false);
   return shift;
 }
 
 /*
  * The following method is called by the row group frame's SplitRowGroup()
@@ -1358,27 +1400,27 @@ nsTableRowFrame::GetNextRow() const
     childFrame = childFrame->GetNextSibling();
   }
   return nullptr;
 }
 
 NS_DECLARE_FRAME_PROPERTY(RowUnpaginatedHeightProperty, nullptr)
 
 void
-nsTableRowFrame::SetUnpaginatedHeight(nsPresContext* aPresContext,
-                                      nscoord        aValue)
+nsTableRowFrame::SetUnpaginatedBSize(nsPresContext* aPresContext,
+                                     nscoord        aValue)
 {
   NS_ASSERTION(!GetPrevInFlow(), "program error");
   // Get the property
   aPresContext->PropertyTable()->
     Set(this, RowUnpaginatedHeightProperty(), NS_INT32_TO_PTR(aValue));
 }
 
 nscoord
-nsTableRowFrame::GetUnpaginatedHeight(nsPresContext* aPresContext)
+nsTableRowFrame::GetUnpaginatedBSize(nsPresContext* aPresContext)
 {
   FrameProperties props = FirstInFlow()->Properties();
   return NS_PTR_TO_INT32(props.Get(RowUnpaginatedHeightProperty()));
 }
 
 void nsTableRowFrame::SetContinuousBCBorderWidth(LogicalSide aForSide,
                                                  BCPixelSize aPixelValue)
 {
@@ -1403,32 +1445,33 @@ nsTableRowFrame::AccessibleType()
   return a11y::eHTMLTableRowType;
 }
 #endif
 /**
  * Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
  * this row has any cells that have non-auto-height.  (Row-spanning
  * cells are ignored.)
  */
-void nsTableRowFrame::InitHasCellWithStyleHeight(nsTableFrame* aTableFrame)
+void nsTableRowFrame::InitHasCellWithStyleBSize(nsTableFrame* aTableFrame)
 {
   nsTableIterator iter(*this);
+  WritingMode wm = GetWritingMode();
 
   for (nsIFrame* kidFrame = iter.First(); kidFrame; kidFrame = iter.Next()) {
     nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
     if (!cellFrame) {
       NS_NOTREACHED("Table row has a non-cell child.");
       continue;
     }
     // Ignore row-spanning cells
-    const nsStyleCoord &cellHeight = cellFrame->StylePosition()->mHeight;
+    const nsStyleCoord &cellBSize = cellFrame->StylePosition()->BSize(wm);
     if (aTableFrame->GetEffectiveRowSpan(*cellFrame) == 1 &&
-        cellHeight.GetUnit() != eStyleUnit_Auto &&
+        cellBSize.GetUnit() != eStyleUnit_Auto &&
          /* calc() with percentages treated like 'auto' */
-        (!cellHeight.IsCalcUnit() || !cellHeight.HasPercent())) {
+        (!cellBSize.IsCalcUnit() || !cellBSize.HasPercent())) {
       AddStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
       return;
     }
   }
   RemoveStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
 }
 
 void
--- a/layout/tables/nsTableRowFrame.h
+++ b/layout/tables/nsTableRowFrame.h
@@ -110,31 +110,31 @@ public:
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
   virtual mozilla::WritingMode GetWritingMode() const override
     { return GetTableFrame()->GetWritingMode(); }
  
-  void UpdateHeight(nscoord           aHeight,
-                    nscoord           aAscent,
-                    nscoord           aDescent,
-                    nsTableFrame*     aTableFrame = nullptr,
-                    nsTableCellFrame* aCellFrame  = nullptr);
+  void UpdateBSize(nscoord           aBSize,
+                   nscoord           aAscent,
+                   nscoord           aDescent,
+                   nsTableFrame*     aTableFrame = nullptr,
+                   nsTableCellFrame* aCellFrame  = nullptr);
 
-  void ResetHeight(nscoord aRowStyleHeight);
+  void ResetBSize(nscoord aRowStyleBSize);
 
-  // calculate the height, considering content height of the 
-  // cells and the style height of the row and cells, excluding pct heights
-  nscoord CalcHeight(const nsHTMLReflowState& aReflowState);
+  // calculate the bsize, considering content bsize of the 
+  // cells and the style bsize of the row and cells, excluding pct bsizes
+  nscoord CalcBSize(const nsHTMLReflowState& aReflowState);
 
   // Support for cells with 'vertical-align: baseline'.
 
-  /** 
+  /**
    * returns the max-ascent amongst all the cells that have 
    * 'vertical-align: baseline', *including* cells with rowspans.
    * returns 0 if we don't have any cell with 'vertical-align: baseline'
    */
   nscoord GetMaxCellAscent() const;
 
   /* return the row ascent
    */
@@ -142,93 +142,96 @@ public:
  
   /** returns the ordinal position of this row in its table */
   virtual int32_t GetRowIndex() const;
 
   /** set this row's starting row index */
   void SetRowIndex (int aRowIndex);
 
   /** used by row group frame code */
-  nscoord ReflowCellFrame(nsPresContext*          aPresContext,
+  nscoord ReflowCellFrame(nsPresContext*           aPresContext,
                           const nsHTMLReflowState& aReflowState,
                           bool                     aIsTopOfPage,
                           nsTableCellFrame*        aCellFrame,
-                          nscoord                  aAvailableHeight,
+                          nscoord                  aAvailableBSize,
                           nsReflowStatus&          aStatus);
   /**
     * Collapse the row if required, apply col and colgroup visibility: collapse
     * info to the cells in the row.
-    * @return he amount to shift up all following rows
-    * @param aRowOffset     - shift the row up by this amount
-    * @param aWidth         - new width of the row
+    * @return the amount to shift bstart-wards all following rows
+    * @param aRowOffset     - shift the row bstart-wards by this amount
+    * @param aISize         - new isize of the row
     * @param aCollapseGroup - parent rowgroup is collapsed so this row needs
     *                         to be collapsed
     * @param aDidCollapse   - the row has been collapsed
     */
   nscoord CollapseRowIfNecessary(nscoord aRowOffset,
-                                 nscoord aWidth,
+                                 nscoord aISize,
                                  bool    aCollapseGroup,
-                                 bool& aDidCollapse);
+                                 bool&   aDidCollapse);
 
   /**
    * Insert a cell frame after the last cell frame that has a col index
    * that is less than aColIndex.  If no such cell frame is found the
    * frame to insert is prepended to the child list.
    * @param aFrame the cell frame to insert
    * @param aColIndex the col index
    */
   void InsertCellFrame(nsTableCellFrame* aFrame,
                        int32_t           aColIndex);
 
-  nsresult CalculateCellActualHeight(nsTableCellFrame* aCellFrame,
-                                     nscoord&          aDesiredHeight);
+  nsresult CalculateCellActualBSize(nsTableCellFrame*    aCellFrame,
+                                    nscoord&             aDesiredBSize,
+                                    mozilla::WritingMode aWM);
 
   bool IsFirstInserted() const;
   void   SetFirstInserted(bool aValue);
 
-  nscoord GetContentHeight() const;
-  void    SetContentHeight(nscoord aTwipValue);
+  nscoord GetContentBSize() const;
+  void    SetContentBSize(nscoord aTwipValue);
 
-  bool HasStyleHeight() const;
+  bool HasStyleBSize() const;
 
-  bool HasFixedHeight() const;
-  void   SetHasFixedHeight(bool aValue);
+  bool HasFixedBSize() const;
+  void   SetHasFixedBSize(bool aValue);
 
-  bool HasPctHeight() const;
-  void   SetHasPctHeight(bool aValue);
+  bool HasPctBSize() const;
+  void   SetHasPctBSize(bool aValue);
 
-  nscoord GetFixedHeight() const;
-  void    SetFixedHeight(nscoord aValue);
+  nscoord GetFixedBSize() const;
+  void    SetFixedBSize(nscoord aValue);
 
-  float   GetPctHeight() const;
-  void    SetPctHeight(float  aPctValue,
+  float   GetPctBSize() const;
+  void    SetPctBSize(float  aPctValue,
                        bool aForce = false);
 
-  nscoord GetHeight(nscoord aBasis = 0) const;
+  nscoord GetBSize(nscoord aBasis = 0) const;
 
   nsTableRowFrame* GetNextRow() const;
 
-  bool    HasUnpaginatedHeight();
-  void    SetHasUnpaginatedHeight(bool aValue);
-  nscoord GetUnpaginatedHeight(nsPresContext* aPresContext);
-  void    SetUnpaginatedHeight(nsPresContext* aPresContext, nscoord aValue);
+  bool    HasUnpaginatedBSize();
+  void    SetHasUnpaginatedBSize(bool aValue);
+  nscoord GetUnpaginatedBSize(nsPresContext* aPresContext);
+  void    SetUnpaginatedBSize(nsPresContext* aPresContext, nscoord aValue);
 
   nscoord GetBStartBCBorderWidth() const { return mBStartBorderWidth; }
   nscoord GetBEndBCBorderWidth() const { return mBEndBorderWidth; }
   void SetBStartBCBorderWidth(BCPixelSize aWidth) { mBStartBorderWidth = aWidth; }
   void SetBEndBCBorderWidth(BCPixelSize aWidth) { mBEndBorderWidth = aWidth; }
   mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
                              
   /**
    * Gets inner border widths before collapsing with cell borders
    * Caller must get block-end border from next row or from table
    * GetContinuousBCBorderWidth will not overwrite that border
    * see nsTablePainter about continuous borders
    */
-  void GetContinuousBCBorderWidth(nsMargin& aBorder);
+  void GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
+                                  mozilla::LogicalMargin& aBorder);
+
   /**
    * @returns outer block-start bc border == prev row's block-end inner
    */
   nscoord GetOuterBStartContBCBorderWidth();
   /**
    * Sets full border widths before collapsing with cell borders
    * @param aForSide - side to set; only accepts iend, istart, and bstart
    */
@@ -250,20 +253,20 @@ public:
 
 protected:
 
   /** protected constructor.
     * @see NewFrame
     */
   explicit nsTableRowFrame(nsStyleContext *aContext);
 
-  void InitChildReflowState(nsPresContext&         aPresContext,
-                            const nsSize&           aAvailSize,
-                            bool                    aBorderCollapse,
-                            nsTableCellReflowState& aReflowState);
+  void InitChildReflowState(nsPresContext&              aPresContext,
+                            const mozilla::LogicalSize& aAvailSize,
+                            bool                        aBorderCollapse,
+                            nsTableCellReflowState&     aReflowState);
   
   virtual LogicalSides GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const override;
 
   // row-specific methods
 
   nscoord ComputeCellXOffset(const nsHTMLReflowState& aState,
                              nsIFrame*                aKidFrame,
                              const nsMargin&          aKidMargin) const;
@@ -275,29 +278,29 @@ protected:
                       nsHTMLReflowMetrics&     aDesiredSize,
                       const nsHTMLReflowState& aReflowState,
                       nsTableFrame&            aTableFrame,
                       nsReflowStatus&          aStatus);
 
 private:
   struct RowBits {
     unsigned mRowIndex:29;
-    unsigned mHasFixedHeight:1; // set if the dominating style height on the row or any cell is pixel based
-    unsigned mHasPctHeight:1;   // set if the dominating style height on the row or any cell is pct based
-    unsigned mFirstInserted:1;  // if true, then it was the top most newly inserted row 
+    unsigned mHasFixedBSize:1; // set if the dominating style bsize on the row or any cell is pixel based
+    unsigned mHasPctBSize:1;   // set if the dominating style bsize on the row or any cell is pct based
+    unsigned mFirstInserted:1; // if true, then it was the bstart-most newly inserted row 
   } mBits;
 
-  // the desired height based on the content of the tallest cell in the row
-  nscoord mContentHeight;
-  // the height based on a style percentage height on either the row or any cell
-  // if mHasPctHeight is set
-  nscoord mStylePctHeight;
-  // the height based on a style pixel height on the row or any
-  // cell if mHasFixedHeight is set
-  nscoord mStyleFixedHeight;
+  // the desired bsize based on the content of the tallest cell in the row
+  nscoord mContentBSize;
+  // the bsize based on a style percentage bsize on either the row or any cell
+  // if mHasPctBSize is set
+  nscoord mStylePctBSize;
+  // the bsize based on a style pixel bsize on the row or any
+  // cell if mHasFixedBSize is set
+  nscoord mStyleFixedBSize;
 
   // max-ascent and max-descent amongst all cells that have 'vertical-align: baseline'
   nscoord mMaxCellAscent;  // does include cells with rowspan > 1
   nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1
 
   // border widths in pixels in the collapsing border model of the *inner*
   // half of the border only
   BCPixelSize mBStartBorderWidth;
@@ -306,17 +309,17 @@ private:
   BCPixelSize mBStartContBorderWidth;
   BCPixelSize mIStartContBorderWidth;
 
   /**
    * Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
    * this row has any cells that have non-auto-height.  (Row-spanning
    * cells are ignored.)
    */
-  void InitHasCellWithStyleHeight(nsTableFrame* aTableFrame);
+  void InitHasCellWithStyleBSize(nsTableFrame* aTableFrame);
 
 };
 
 inline int32_t nsTableRowFrame::GetRowIndex() const
 {
   return int32_t(mBits.mRowIndex);
 }
 
@@ -330,74 +333,74 @@ inline bool nsTableRowFrame::IsFirstInse
   return bool(mBits.mFirstInserted);
 }
 
 inline void nsTableRowFrame::SetFirstInserted(bool aValue)
 {
   mBits.mFirstInserted = aValue;
 }
 
-inline bool nsTableRowFrame::HasStyleHeight() const
+inline bool nsTableRowFrame::HasStyleBSize() const
 {
-  return (bool)mBits.mHasFixedHeight || (bool)mBits.mHasPctHeight;
+  return (bool)mBits.mHasFixedBSize || (bool)mBits.mHasPctBSize;
 }
 
-inline bool nsTableRowFrame::HasFixedHeight() const
+inline bool nsTableRowFrame::HasFixedBSize() const
 {
-  return (bool)mBits.mHasFixedHeight;
+  return (bool)mBits.mHasFixedBSize;
 }
 
-inline void nsTableRowFrame::SetHasFixedHeight(bool aValue)
+inline void nsTableRowFrame::SetHasFixedBSize(bool aValue)
 {
-  mBits.mHasFixedHeight = aValue;
+  mBits.mHasFixedBSize = aValue;
 }
 
-inline bool nsTableRowFrame::HasPctHeight() const
+inline bool nsTableRowFrame::HasPctBSize() const
 {
-  return (bool)mBits.mHasPctHeight;
+  return (bool)mBits.mHasPctBSize;
 }
 
-inline void nsTableRowFrame::SetHasPctHeight(bool aValue)
+inline void nsTableRowFrame::SetHasPctBSize(bool aValue)
 {
-  mBits.mHasPctHeight = aValue;
+  mBits.mHasPctBSize = aValue;
 }
 
-inline nscoord nsTableRowFrame::GetContentHeight() const
+inline nscoord nsTableRowFrame::GetContentBSize() const
 {
-  return mContentHeight;
+  return mContentBSize;
 }
 
-inline void nsTableRowFrame::SetContentHeight(nscoord aValue)
+inline void nsTableRowFrame::SetContentBSize(nscoord aValue)
 {
-  mContentHeight = aValue;
+  mContentBSize = aValue;
 }
 
-inline nscoord nsTableRowFrame::GetFixedHeight() const
+inline nscoord nsTableRowFrame::GetFixedBSize() const
 {
-  if (mBits.mHasFixedHeight)
-    return mStyleFixedHeight;
-  else
-    return 0;
+  if (mBits.mHasFixedBSize) {
+    return mStyleFixedBSize;
+  }
+  return 0;
 }
 
-inline float nsTableRowFrame::GetPctHeight() const
+inline float nsTableRowFrame::GetPctBSize() const
 {
-  if (mBits.mHasPctHeight) 
-    return (float)mStylePctHeight / 100.0f;
-  else
-    return 0.0f;
+  if (mBits.mHasPctBSize) {
+    return (float)mStylePctBSize / 100.0f;
+  }
+  return 0.0f;
 }
 
-inline bool nsTableRowFrame::HasUnpaginatedHeight()
+inline bool nsTableRowFrame::HasUnpaginatedBSize()
 {
   return (mState & NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT) ==
          NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT;
 }
 
-inline void nsTableRowFrame::SetHasUnpaginatedHeight(bool aValue)
+inline void nsTableRowFrame::SetHasUnpaginatedBSize(bool aValue)
 {
   if (aValue) {
     mState |= NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT;
   } else {
     mState &= ~NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT;
   }
 }
 
@@ -405,28 +408,26 @@ inline mozilla::LogicalMargin
 nsTableRowFrame::GetBCBorderWidth(mozilla::WritingMode aWM)
 {
   return mozilla::LogicalMargin(
     aWM, nsPresContext::CSSPixelsToAppUnits(mBStartBorderWidth), 0,
     nsPresContext::CSSPixelsToAppUnits(mBEndBorderWidth), 0);
 }
 
 inline void
-nsTableRowFrame::GetContinuousBCBorderWidth(nsMargin& aBorder)
+nsTableRowFrame::GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
+                                            mozilla::LogicalMargin& aBorder)
 {
   int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
-  mozilla::WritingMode wm = GetWritingMode();
-  mozilla::LogicalMargin border(wm, aBorder);
-  border.IEnd(wm) = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
-                                               mIStartContBorderWidth);
-  border.BStart(wm) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
-                                               mBStartContBorderWidth);
-  border.IStart(wm) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
-                                               mIEndContBorderWidth);
-  aBorder = border.GetPhysicalMargin(wm);
+  aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
+                                                 mIStartContBorderWidth);
+  aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
+                                                 mBStartContBorderWidth);
+  aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
+                                                 mIEndContBorderWidth);
 }
 
 inline nscoord nsTableRowFrame::GetOuterBStartContBCBorderWidth()
 {
   int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
   return BC_BORDER_START_HALF_COORD(aPixelsToTwips, mBStartContBorderWidth);
 }
 
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -250,43 +250,44 @@ nsTableRowGroupFrame::GetLogicalSkipSide
     skip |= eLogicalSideBitsBStart;
   }
   if (nullptr != GetNextInFlow()) {
     skip |= eLogicalSideBitsBEnd;
   }
   return skip;
 }
 
-// Position and size aKidFrame and update our reflow state. The origin of
-// aKidRect is relative to the upper-left origin of our frame
+// Position and size aKidFrame and update our reflow state.
 void
 nsTableRowGroupFrame::PlaceChild(nsPresContext*         aPresContext,
                                  nsRowGroupReflowState& aReflowState,
                                  nsIFrame*              aKidFrame,
-                                 nsPoint                aKidPosition,
+                                 WritingMode            aWM,
+                                 const LogicalPoint&    aKidPosition,
+                                 nscoord                aContainerWidth,
                                  nsHTMLReflowMetrics&   aDesiredSize,
                                  const nsRect&          aOriginalKidRect,
                                  const nsRect&          aOriginalKidVisualOverflow)
 {
   bool isFirstReflow =
     (aKidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
 
   // Place and size the child
   FinishReflowChild(aKidFrame, aPresContext, aDesiredSize, nullptr,
-                    aKidPosition.x, aKidPosition.y, 0);
+                    aWM, aKidPosition, aContainerWidth, 0);
 
   nsTableFrame::InvalidateTableFrame(aKidFrame, aOriginalKidRect,
                                      aOriginalKidVisualOverflow, isFirstReflow);
 
-  // Adjust the running y-offset
-  aReflowState.y += aDesiredSize.Height();
+  // Adjust the running block-offset
+  aReflowState.bCoord += aDesiredSize.BSize(aWM);
 
-  // If our height is constrained then update the available height
-  if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height) {
-    aReflowState.availSize.height -= aDesiredSize.Height();
+  // If our block-size is constrained then update the available bsize
+  if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.BSize(aWM)) {
+    aReflowState.availSize.BSize(aWM) -= aDesiredSize.BSize(aWM);
   }
 }
 
 void
 nsTableRowGroupFrame::InitChildReflowState(nsPresContext&     aPresContext,
                                            bool               aBorderCollapse,
                                            nsHTMLReflowState& aReflowState)
 {
@@ -301,168 +302,183 @@ nsTableRowGroupFrame::InitChildReflowSta
       collapseBorder = border.GetPhysicalMargin(wm);
       pCollapseBorder = &collapseBorder;
     }
   }
   aReflowState.Init(&aPresContext, nullptr, pCollapseBorder, &padding);
 }
 
 static void
-CacheRowHeightsForPrinting(nsPresContext*   aPresContext,
-                           nsTableRowFrame* aFirstRow)
+CacheRowBSizesForPrinting(nsPresContext*   aPresContext,
+                          nsTableRowFrame* aFirstRow,
+                          WritingMode      aWM)
 {
   for (nsTableRowFrame* row = aFirstRow; row; row = row->GetNextRow()) {
     if (!row->GetPrevInFlow()) {
-      row->SetHasUnpaginatedHeight(true);
-      row->SetUnpaginatedHeight(aPresContext, row->GetSize().height);
+      row->SetHasUnpaginatedBSize(true);
+      row->SetUnpaginatedBSize(aPresContext, row->BSize(aWM));
     }
   }
 }
 
 void
 nsTableRowGroupFrame::ReflowChildren(nsPresContext*         aPresContext,
                                      nsHTMLReflowMetrics&   aDesiredSize,
                                      nsRowGroupReflowState& aReflowState,
                                      nsReflowStatus&        aStatus,
                                      bool*                aPageBreakBeforeEnd)
 {
-  if (aPageBreakBeforeEnd)
+  if (aPageBreakBeforeEnd) {
     *aPageBreakBeforeEnd = false;
+  }
 
+  WritingMode wm = aReflowState.reflowState.GetWritingMode();
   nsTableFrame* tableFrame = GetTableFrame();
   const bool borderCollapse = tableFrame->IsBorderCollapse();
 
-  // XXXldb Should we really be checking this rather than available height?
+  // XXXldb Should we really be checking IsPaginated(),
+  // or should we *only* check available block-size?
   // (Think about multi-column layout!)
   bool isPaginated = aPresContext->IsPaginated() &&
-                       NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height;
+                     NS_UNCONSTRAINEDSIZE != aReflowState.availSize.BSize(wm);
 
   bool haveRow = false;
   bool reflowAllKids = aReflowState.reflowState.ShouldReflowAllKids() ||
                          tableFrame->IsGeometryDirty();
-  bool needToCalcRowHeights = reflowAllKids;
+  bool needToCalcRowBSizes = reflowAllKids;
+
+  nscoord containerWidth = aReflowState.reflowState.ComputedWidth();
+  if (containerWidth == NS_UNCONSTRAINEDSIZE) {
+    containerWidth = 0; // we can't position frames correctly in RTL yet,
+                        // so they will need to be adjusted later
+  } else {
+    containerWidth +=
+      aReflowState.reflowState.ComputedPhysicalBorderPadding().LeftRight();
+  }
 
   nsIFrame *prevKidFrame = nullptr;
   for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame;
        prevKidFrame = kidFrame, kidFrame = kidFrame->GetNextSibling()) {
     nsTableRowFrame *rowFrame = do_QueryFrame(kidFrame);
     if (!rowFrame) {
       // XXXldb nsCSSFrameConstructor needs to enforce this!
       NS_NOTREACHED("yikes, a non-row child");
       continue;
     }
-    nscoord cellSpacingY = tableFrame->GetRowSpacing(rowFrame->GetRowIndex());
+    nscoord cellSpacingB = tableFrame->GetRowSpacing(rowFrame->GetRowIndex());
     haveRow = true;
 
     // Reflow the row frame
     if (reflowAllKids ||
         NS_SUBTREE_DIRTY(kidFrame) ||
         (aReflowState.reflowState.mFlags.mSpecialHeightReflow &&
          (isPaginated || (kidFrame->GetStateBits() &
                           NS_FRAME_CONTAINS_RELATIVE_BSIZE)))) {
-      nsRect oldKidRect = kidFrame->GetRect();
+      LogicalRect oldKidRect = kidFrame->GetLogicalRect(wm, containerWidth);
       nsRect oldKidVisualOverflow = kidFrame->GetVisualOverflowRect();
 
       // XXXldb We used to only pass aDesiredSize.mFlags through for the
       // incremental reflow codepath.
       nsHTMLReflowMetrics desiredSize(aReflowState.reflowState,
                                       aDesiredSize.mFlags);
       desiredSize.ClearSize();
 
-      // Reflow the child into the available space, giving it as much height as
+      // Reflow the child into the available space, giving it as much bsize as
       // it wants. We'll deal with splitting later after we've computed the row
-      // heights, taking into account cells with row spans...
-      WritingMode wm = kidFrame->GetWritingMode();
-      LogicalSize kidAvailSize(wm, aReflowState.availSize);
+      // bsizes, taking into account cells with row spans...
+      LogicalSize kidAvailSize = aReflowState.availSize;
       kidAvailSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
       nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
                                        kidFrame, kidAvailSize,
                                        nullptr,
                                        nsHTMLReflowState::CALLER_WILL_INIT);
       InitChildReflowState(*aPresContext, borderCollapse, kidReflowState);
 
       // This can indicate that columns were resized.
-      if (aReflowState.reflowState.IsHResize()) {
-        kidReflowState.SetHResize(true);
+      if (aReflowState.reflowState.IsIResize()) {
+        kidReflowState.SetIResize(true);
       }
 
       NS_ASSERTION(kidFrame == mFrames.FirstChild() || prevKidFrame,
                    "If we're not on the first frame, we should have a "
                    "previous sibling...");
       // If prev row has nonzero YMost, then we can't be at the top of the page
       if (prevKidFrame && prevKidFrame->GetNormalRect().YMost() > 0) {
         kidReflowState.mFlags.mIsTopOfPage = false;
       }
 
+      LogicalPoint kidPosition(wm, 0, aReflowState.bCoord);
       ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
-                  0, aReflowState.y, 0, aStatus);
-      nsPoint kidPosition(0, aReflowState.y);
-      kidReflowState.ApplyRelativePositioning(&kidPosition);
+                  wm, kidPosition, containerWidth, 0, aStatus);
+      kidReflowState.ApplyRelativePositioning(&kidPosition, containerWidth);
 
       // Place the child
-      PlaceChild(aPresContext, aReflowState, kidFrame, kidPosition,
-                 desiredSize, oldKidRect, oldKidVisualOverflow);
-      aReflowState.y += cellSpacingY;
+      PlaceChild(aPresContext, aReflowState, kidFrame,
+                 wm, kidPosition, containerWidth,
+                 desiredSize, oldKidRect.GetPhysicalRect(wm, containerWidth),
+                 oldKidVisualOverflow);
+      aReflowState.bCoord += cellSpacingB;
 
       if (!reflowAllKids) {
         if (IsSimpleRowFrame(aReflowState.tableFrame, kidFrame)) {
-          // Inform the row of its new height.
+          // Inform the row of its new bsize.
           rowFrame->DidResize();
           // the overflow area may have changed inflate the overflow area
           const nsStylePosition *stylePos = StylePosition();
-          nsStyleUnit unit = stylePos->mHeight.GetUnit();
+          nsStyleUnit unit = stylePos->BSize(wm).GetUnit();
           if (aReflowState.tableFrame->IsAutoHeight() &&
               unit != eStyleUnit_Coord) {
             // Because other cells in the row may need to be aligned
             // differently, repaint the entire row
             InvalidateFrame();
+          } else if (oldKidRect.BSize(wm) != desiredSize.BSize(wm)) {
+            needToCalcRowBSizes = true;
           }
-          else if (oldKidRect.height != desiredSize.Height())
-            needToCalcRowHeights = true;
         } else {
-          needToCalcRowHeights = true;
+          needToCalcRowBSizes = true;
         }
       }
 
       if (isPaginated && aPageBreakBeforeEnd && !*aPageBreakBeforeEnd) {
         nsTableRowFrame* nextRow = rowFrame->GetNextRow();
         if (nextRow) {
           *aPageBreakBeforeEnd = nsTableFrame::PageBreakAfter(kidFrame, nextRow);
         }
       }
     } else {
       SlideChild(aReflowState, kidFrame);
 
-      // Adjust the running y-offset so we know where the next row should be placed
-      nscoord height = kidFrame->GetSize().height + cellSpacingY;
-      aReflowState.y += height;
+      // Adjust the running b-offset so we know where the next row should be placed
+      nscoord bSize = kidFrame->BSize(wm) + cellSpacingB;
+      aReflowState.bCoord += bSize;
 
-      if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height) {
-        aReflowState.availSize.height -= height;
+      if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.BSize(wm)) {
+        aReflowState.availSize.BSize(wm) -= bSize;
       }
     }
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kidFrame);
   }
 
-  if (haveRow)
-    aReflowState.y -= tableFrame->GetRowSpacing(GetStartRowIndex() +
-                                                GetRowCount());
+  if (haveRow) {
+    aReflowState.bCoord -= tableFrame->GetRowSpacing(GetStartRowIndex() +
+                                                     GetRowCount());
+  }
 
   // Return our desired rect
-  aDesiredSize.Width() = aReflowState.reflowState.AvailableWidth();
-  aDesiredSize.Height() = aReflowState.y;
+  aDesiredSize.ISize(wm) = aReflowState.reflowState.AvailableISize();
+  aDesiredSize.BSize(wm) = aReflowState.bCoord;
 
   if (aReflowState.reflowState.mFlags.mSpecialHeightReflow) {
     DidResizeRows(aDesiredSize);
     if (isPaginated) {
-      CacheRowHeightsForPrinting(aPresContext, GetFirstRow());
+      CacheRowBSizesForPrinting(aPresContext, GetFirstRow(), wm);
     }
   }
-  else if (needToCalcRowHeights) {
-    CalculateRowHeights(aPresContext, aDesiredSize, aReflowState.reflowState);
+  else if (needToCalcRowBSizes) {
+    CalculateRowBSizes(aPresContext, aDesiredSize, aReflowState.reflowState);
     if (!reflowAllKids) {
       InvalidateFrame();
     }
   }
 }
 
 nsTableRowFrame*
 nsTableRowGroupFrame::GetFirstRow()
@@ -474,111 +490,119 @@ nsTableRowGroupFrame::GetFirstRow()
       return rowFrame;
     }
   }
   return nullptr;
 }
 
 
 struct RowInfo {
-  RowInfo() { height = pctHeight = hasStyleHeight = hasPctHeight = isSpecial = 0; }
-  unsigned height;       // content height or fixed height, excluding pct height
-  unsigned pctHeight:29; // pct height
-  unsigned hasStyleHeight:1;
-  unsigned hasPctHeight:1;
+  RowInfo() { bSize = pctBSize = hasStyleBSize = hasPctBSize = isSpecial = 0; }
+  unsigned bSize;       // content bsize or fixed bsize, excluding pct bsize
+  unsigned pctBSize:29; // pct bsize
+  unsigned hasStyleBSize:1;
+  unsigned hasPctBSize:1;
   unsigned isSpecial:1; // there is no cell originating in the row with rowspan=1 and there are at
-                        // least 2 cells spanning the row and there is no style height on the row
+                        // least 2 cells spanning the row and there is no style bsize on the row
 };
 
 static void
-UpdateHeights(RowInfo& aRowInfo,
-              nscoord  aAdditionalHeight,
-              nscoord& aTotal,
-              nscoord& aUnconstrainedTotal)
+UpdateBSizes(RowInfo& aRowInfo,
+             nscoord  aAdditionalBSize,
+             nscoord& aTotal,
+             nscoord& aUnconstrainedTotal)
 {
-  aRowInfo.height += aAdditionalHeight;
-  aTotal          += aAdditionalHeight;
-  if (!aRowInfo.hasStyleHeight) {
-    aUnconstrainedTotal += aAdditionalHeight;
+  aRowInfo.bSize += aAdditionalBSize;
+  aTotal         += aAdditionalBSize;
+  if (!aRowInfo.hasStyleBSize) {
+    aUnconstrainedTotal += aAdditionalBSize;
   }
 }
 
 void
 nsTableRowGroupFrame::DidResizeRows(nsHTMLReflowMetrics& aDesiredSize)
 {
-  // update the cells spanning rows with their new heights
-  // this is the place where all of the cells in the row get set to the height of the row
-  // Reset the overflow area
+  // Update the cells spanning rows with their new bsizes.
+  // This is the place where all of the cells in the row get set to the bsize
+  // of the row.
+  // Reset the overflow area.
   aDesiredSize.mOverflowAreas.Clear();
   for (nsTableRowFrame* rowFrame = GetFirstRow();
        rowFrame; rowFrame = rowFrame->GetNextRow()) {
     rowFrame->DidResize();
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, rowFrame);
   }
 }
 
-// This calculates the height of all the rows and takes into account
-// style height on the row group, style heights on rows and cells, style heights on rowspans.
-// Actual row heights will be adjusted later if the table has a style height.
-// Even if rows don't change height, this method must be called to set the heights of each
-// cell in the row to the height of its row.
+// This calculates the bsize of all the rows and takes into account
+// style bsize on the row group, style bsizes on rows and cells, style bsizes on rowspans.
+// Actual row bsizes will be adjusted later if the table has a style bsize.
+// Even if rows don't change bsize, this method must be called to set the bsizes of each
+// cell in the row to the bsize of its row.
 void
-nsTableRowGroupFrame::CalculateRowHeights(nsPresContext*           aPresContext,
+nsTableRowGroupFrame::CalculateRowBSizes(nsPresContext*           aPresContext,
                                           nsHTMLReflowMetrics&     aDesiredSize,
                                           const nsHTMLReflowState& aReflowState)
 {
   nsTableFrame* tableFrame = GetTableFrame();
   const bool isPaginated = aPresContext->IsPaginated();
 
   int32_t numEffCols = tableFrame->GetEffectiveColCount();
 
   int32_t startRowIndex = GetStartRowIndex();
   // find the row corresponding to the row index we just found
   nsTableRowFrame* startRowFrame = GetFirstRow();
 
-  if (!startRowFrame) return;
+  if (!startRowFrame) {
+    return;
+  }
 
-  // the current row group height is the y origin of the 1st row we are about to calculated a height for
-  nscoord startRowGroupHeight = startRowFrame->GetNormalPosition().y;
+  // The current row group block-size is the block-origin of the 1st row
+  // we are about to calculate a block-size for.
+  WritingMode wm = aReflowState.GetWritingMode();
+  nscoord containerWidth = 0; // actual value is unimportant as we're initially
+                              // computing sizes, not physical positions
+  nscoord startRowGroupBSize =
+    startRowFrame->GetLogicalNormalPosition(wm, containerWidth).B(wm);
 
   int32_t numRows = GetRowCount() - (startRowFrame->GetRowIndex() - GetStartRowIndex());
-  // collect the current height of each row.  nscoord* rowHeights = nullptr;
+  // Collect the current bsize of each row.
   if (numRows <= 0)
     return;
 
   nsTArray<RowInfo> rowInfo;
   if (!rowInfo.AppendElements(numRows)) {
     return;
   }
 
   bool    hasRowSpanningCell = false;
-  nscoord heightOfRows = 0;
-  nscoord heightOfUnStyledRows = 0;
-  // Get the height of each row without considering rowspans. This will be the max of
-  // the largest desired height of each cell, the largest style height of each cell,
-  // the style height of the row.
-  nscoord pctHeightBasis = GetHeightBasis(aReflowState);
+  nscoord bSizeOfRows = 0;
+  nscoord bSizeOfUnStyledRows = 0;
+  // Get the bsize of each row without considering rowspans. This will be the max of
+  // the largest desired bsize of each cell, the largest style bsize of each cell,
+  // the style bsize of the row.
+  nscoord pctBSizeBasis = GetBSizeBasis(aReflowState);
   int32_t rowIndex; // the index in rowInfo, not among the rows in the row group
   nsTableRowFrame* rowFrame;
   for (rowFrame = startRowFrame, rowIndex = 0; rowFrame; rowFrame = rowFrame->GetNextRow(), rowIndex++) {
-    nscoord nonPctHeight = rowFrame->GetContentHeight();
+    nscoord nonPctBSize = rowFrame->GetContentBSize();
     if (isPaginated) {
-      nonPctHeight = std::max(nonPctHeight, rowFrame->GetSize().height);
+      nonPctBSize = std::max(nonPctBSize, rowFrame->BSize(wm));
     }
     if (!rowFrame->GetPrevInFlow()) {
-      if (rowFrame->HasPctHeight()) {
-        rowInfo[rowIndex].hasPctHeight = true;
-        rowInfo[rowIndex].pctHeight = rowFrame->GetHeight(pctHeightBasis);
+      if (rowFrame->HasPctBSize()) {
+        rowInfo[rowIndex].hasPctBSize = true;
+        rowInfo[rowIndex].pctBSize = rowFrame->GetBSize(pctBSizeBasis);
       }
-      rowInfo[rowIndex].hasStyleHeight = rowFrame->HasStyleHeight();
-      nonPctHeight = std::max(nonPctHeight, rowFrame->GetFixedHeight());
+      rowInfo[rowIndex].hasStyleBSize = rowFrame->HasStyleBSize();
+      nonPctBSize = std::max(nonPctBSize, rowFrame->GetFixedBSize());
     }
-    UpdateHeights(rowInfo[rowIndex], nonPctHeight, heightOfRows, heightOfUnStyledRows);
+    UpdateBSizes(rowInfo[rowIndex], nonPctBSize, bSizeOfRows, bSizeOfUnStyledRows);
 
-    if (!rowInfo[rowIndex].hasStyleHeight) {
+    if (!rowInfo[rowIndex].hasStyleBSize) {
       if (isPaginated || tableFrame->HasMoreThanOneCell(rowIndex + startRowIndex)) {
         rowInfo[rowIndex].isSpecial = true;
         // iteratate the row's cell frames to see if any do not have rowspan > 1
         nsTableCellFrame* cellFrame = rowFrame->GetFirstCell();
         while (cellFrame) {
           int32_t rowSpan = tableFrame->GetEffectiveRowSpan(rowIndex + startRowIndex, *cellFrame);
           if (1 == rowSpan) {
             rowInfo[rowIndex].isSpecial = false;
@@ -592,284 +616,299 @@ nsTableRowGroupFrame::CalculateRowHeight
     if (!hasRowSpanningCell) {
       if (tableFrame->RowIsSpannedInto(rowIndex + startRowIndex, numEffCols)) {
         hasRowSpanningCell = true;
       }
     }
   }
 
   if (hasRowSpanningCell) {
-    // Get the height of cells with rowspans and allocate any extra space to the rows they span
+    // Get the bsize of cells with rowspans and allocate any extra space to the rows they span
     // iteratate the child frames and process the row frames among them
     for (rowFrame = startRowFrame, rowIndex = 0; rowFrame; rowFrame = rowFrame->GetNextRow(), rowIndex++) {
       // See if the row has an originating cell with rowspan > 1. We cannot determine this for a row in a
       // continued row group by calling RowHasSpanningCells, because the row's fif may not have any originating
       // cells yet the row may have a continued cell which originates in it.
       if (GetPrevInFlow() || tableFrame->RowHasSpanningCells(startRowIndex + rowIndex, numEffCols)) {
         nsTableCellFrame* cellFrame = rowFrame->GetFirstCell();
         // iteratate the row's cell frames
         while (cellFrame) {
-          nscoord cellSpacingY = tableFrame->GetRowSpacing(startRowIndex + rowIndex);
+          nscoord cellSpacingB = tableFrame->GetRowSpacing(startRowIndex + rowIndex);
           int32_t rowSpan = tableFrame->GetEffectiveRowSpan(rowIndex + startRowIndex, *cellFrame);
           if ((rowIndex + rowSpan) > numRows) {
             // there might be rows pushed already to the nextInFlow
             rowSpan = numRows - rowIndex;
           }
-          if (rowSpan > 1) { // a cell with rowspan > 1, determine the height of the rows it spans
-            nscoord heightOfRowsSpanned = 0;
-            nscoord heightOfUnStyledRowsSpanned = 0;
+          if (rowSpan > 1) { // a cell with rowspan > 1, determine the bsize of the rows it spans
+            nscoord bsizeOfRowsSpanned = 0;
+            nscoord bsizeOfUnStyledRowsSpanned = 0;
             nscoord numSpecialRowsSpanned = 0;
             nscoord cellSpacingTotal = 0;
             int32_t spanX;
             for (spanX = 0; spanX < rowSpan; spanX++) {
-              heightOfRowsSpanned += rowInfo[rowIndex + spanX].height;
-              if (!rowInfo[rowIndex + spanX].hasStyleHeight) {
-                heightOfUnStyledRowsSpanned += rowInfo[rowIndex + spanX].height;
+              bsizeOfRowsSpanned += rowInfo[rowIndex + spanX].bSize;
+              if (!rowInfo[rowIndex + spanX].hasStyleBSize) {
+                bsizeOfUnStyledRowsSpanned += rowInfo[rowIndex + spanX].bSize;
               }
               if (0 != spanX) {
-                cellSpacingTotal += cellSpacingY;
+                cellSpacingTotal += cellSpacingB;
               }
               if (rowInfo[rowIndex + spanX].isSpecial) {
                 numSpecialRowsSpanned++;
               }
             }
-            nscoord heightOfAreaSpanned = heightOfRowsSpanned + cellSpacingTotal;
-            // get the height of the cell
-            nsSize cellFrameSize = cellFrame->GetSize();
-            nsSize cellDesSize =
-              cellFrame->GetDesiredSize().GetPhysicalSize(cellFrame->GetWritingMode());
-            rowFrame->CalculateCellActualHeight(cellFrame, cellDesSize.height);
-            cellFrameSize.height = cellDesSize.height;
+            nscoord bsizeOfAreaSpanned = bsizeOfRowsSpanned + cellSpacingTotal;
+            // get the bsize of the cell
+            LogicalSize cellFrameSize = cellFrame->GetLogicalSize(wm);
+            LogicalSize cellDesSize = cellFrame->GetDesiredSize();
+            rowFrame->CalculateCellActualBSize(cellFrame, cellDesSize.BSize(wm), wm);
+            cellFrameSize.BSize(wm) = cellDesSize.BSize(wm);
             if (cellFrame->HasVerticalAlignBaseline()) {
               // to ensure that a spanning cell with a long descender doesn't
               // collide with the next row, we need to take into account the shift
               // that will be done to align the cell on the baseline of the row.
-              cellFrameSize.height += rowFrame->GetMaxCellAscent() -
-                                      cellFrame->GetCellBaseline();
+              cellFrameSize.BSize(wm) += rowFrame->GetMaxCellAscent() -
+                                         cellFrame->GetCellBaseline();
             }
 
-            if (heightOfAreaSpanned < cellFrameSize.height) {
-              // the cell's height is larger than the available space of the rows it
-              // spans so distribute the excess height to the rows affected
-              nscoord extra     = cellFrameSize.height - heightOfAreaSpanned;
+            if (bsizeOfAreaSpanned < cellFrameSize.BSize(wm)) {
+              // the cell's bsize is larger than the available space of the rows it
+              // spans so distribute the excess bsize to the rows affected
+              nscoord extra     = cellFrameSize.BSize(wm) - bsizeOfAreaSpanned;
               nscoord extraUsed = 0;
               if (0 == numSpecialRowsSpanned) {
-                //NS_ASSERTION(heightOfRowsSpanned > 0, "invalid row span situation");
-                bool haveUnStyledRowsSpanned = (heightOfUnStyledRowsSpanned > 0);
+                //NS_ASSERTION(bsizeOfRowsSpanned > 0, "invalid row span situation");
+                bool haveUnStyledRowsSpanned = (bsizeOfUnStyledRowsSpanned > 0);
                 nscoord divisor = (haveUnStyledRowsSpanned)
-                                  ? heightOfUnStyledRowsSpanned : heightOfRowsSpanned;
+                                  ? bsizeOfUnStyledRowsSpanned : bsizeOfRowsSpanned;
                 if (divisor > 0) {
                   for (spanX = rowSpan - 1; spanX >= 0; spanX--) {
-                    if (!haveUnStyledRowsSpanned || !rowInfo[rowIndex + spanX].hasStyleHeight) {
-                      // The amount of additional space each row gets is proportional to its height
-                      float percent = ((float)rowInfo[rowIndex + spanX].height) / ((float)divisor);
+                    if (!haveUnStyledRowsSpanned || !rowInfo[rowIndex + spanX].hasStyleBSize) {
+                      // The amount of additional space each row gets is proportional to its bsize
+                      float percent = ((float)rowInfo[rowIndex + spanX].bSize) / ((float)divisor);
 
                       // give rows their percentage, except for the first row which gets the remainder
                       nscoord extraForRow = (0 == spanX) ? extra - extraUsed
                                                          : NSToCoordRound(((float)(extra)) * percent);
                       extraForRow = std::min(extraForRow, extra - extraUsed);
-                      // update the row height
-                      UpdateHeights(rowInfo[rowIndex + spanX], extraForRow, heightOfRows, heightOfUnStyledRows);
+                      // update the row bsize
+                      UpdateBSizes(rowInfo[rowIndex + spanX], extraForRow, bSizeOfRows, bSizeOfUnStyledRows);
                       extraUsed += extraForRow;
                       if (extraUsed >= extra) {
-                        NS_ASSERTION((extraUsed == extra), "invalid row height calculation");
+                        NS_ASSERTION((extraUsed == extra), "invalid row bsize calculation");
                         break;
                       }
                     }
                   }
                 }
                 else {
                   // put everything in the last row
-                  UpdateHeights(rowInfo[rowIndex + rowSpan - 1], extra, heightOfRows, heightOfUnStyledRows);
+                  UpdateBSizes(rowInfo[rowIndex + rowSpan - 1], extra, bSizeOfRows, bSizeOfUnStyledRows);
                 }
               }
               else {
                 // give the extra to the special rows
                 nscoord numSpecialRowsAllocated = 0;
                 for (spanX = rowSpan - 1; spanX >= 0; spanX--) {
                   if (rowInfo[rowIndex + spanX].isSpecial) {
                     // The amount of additional space each degenerate row gets is proportional to the number of them
                     float percent = 1.0f / ((float)numSpecialRowsSpanned);
 
                     // give rows their percentage, except for the first row which gets the remainder
                     nscoord extraForRow = (numSpecialRowsSpanned - 1 == numSpecialRowsAllocated)
                                           ? extra - extraUsed
                                           : NSToCoordRound(((float)(extra)) * percent);
                     extraForRow = std::min(extraForRow, extra - extraUsed);
-                    // update the row height
-                    UpdateHeights(rowInfo[rowIndex + spanX], extraForRow, heightOfRows, heightOfUnStyledRows);
+                    // update the row bsize
+                    UpdateBSizes(rowInfo[rowIndex + spanX], extraForRow, bSizeOfRows, bSizeOfUnStyledRows);
                     extraUsed += extraForRow;
                     if (extraUsed >= extra) {
-                      NS_ASSERTION((extraUsed == extra), "invalid row height calculation");
+                      NS_ASSERTION((extraUsed == extra), "invalid row bsize calculation");
                       break;
                     }
                   }
                 }
               }
             }
           } // if (rowSpan > 1)
           cellFrame = cellFrame->GetNextCell();
         } // while (cellFrame)
       } // if (tableFrame->RowHasSpanningCells(startRowIndex + rowIndex) {
     } // while (rowFrame)
   }
 
-  // pct height rows have already got their content heights. Give them their pct heights up to pctHeightBasis
-  nscoord extra = pctHeightBasis - heightOfRows;
-  for (rowFrame = startRowFrame, rowIndex = 0; rowFrame && (extra > 0); rowFrame = rowFrame->GetNextRow(), rowIndex++) {
+  // pct bsize rows have already got their content bsizes.
+  // Give them their pct bsizes up to pctBSizeBasis
+  nscoord extra = pctBSizeBasis - bSizeOfRows;
+  for (rowFrame = startRowFrame, rowIndex = 0; rowFrame && (extra > 0);
+       rowFrame = rowFrame->GetNextRow(), rowIndex++) {
     RowInfo& rInfo = rowInfo[rowIndex];
-    if (rInfo.hasPctHeight) {
-      nscoord rowExtra = (rInfo.pctHeight > rInfo.height)
-                         ? rInfo.pctHeight - rInfo.height: 0;
+    if (rInfo.hasPctBSize) {
+      nscoord rowExtra = (rInfo.pctBSize > rInfo.bSize)
+                         ? rInfo.pctBSize - rInfo.bSize: 0;
       rowExtra = std::min(rowExtra, extra);
-      UpdateHeights(rInfo, rowExtra, heightOfRows, heightOfUnStyledRows);
+      UpdateBSizes(rInfo, rowExtra, bSizeOfRows, bSizeOfUnStyledRows);
       extra -= rowExtra;
     }
   }
 
-  bool styleHeightAllocation = false;
-  nscoord rowGroupHeight = startRowGroupHeight + heightOfRows +
+  bool styleBSizeAllocation = false;
+  nscoord rowGroupBSize = startRowGroupBSize + bSizeOfRows +
                            tableFrame->GetRowSpacing(0, numRows-1);
-  // if we have a style height, allocate the extra height to unconstrained rows
-  if ((aReflowState.ComputedHeight() > rowGroupHeight) &&
-      (NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight())) {
-    nscoord extraComputedHeight = aReflowState.ComputedHeight() - rowGroupHeight;
+  // if we have a style bsize, allocate the extra bsize to unconstrained rows
+  if ((aReflowState.ComputedBSize() > rowGroupBSize) &&
+      (NS_UNCONSTRAINEDSIZE != aReflowState.ComputedBSize())) {
+    nscoord extraComputedBSize = aReflowState.ComputedBSize() - rowGroupBSize;
     nscoord extraUsed = 0;
-    bool haveUnStyledRows = (heightOfUnStyledRows > 0);
+    bool haveUnStyledRows = (bSizeOfUnStyledRows > 0);
     nscoord divisor = (haveUnStyledRows)
-                      ? heightOfUnStyledRows : heightOfRows;
+                      ? bSizeOfUnStyledRows : bSizeOfRows;
     if (divisor > 0) {
-      styleHeightAllocation = true;
+      styleBSizeAllocation = true;
       for (rowIndex = 0; rowIndex < numRows; rowIndex++) {
-        if (!haveUnStyledRows || !rowInfo[rowIndex].hasStyleHeight) {
+        if (!haveUnStyledRows || !rowInfo[rowIndex].hasStyleBSize) {
           // The amount of additional space each row gets is based on the
           // percentage of space it occupies
-          float percent = ((float)rowInfo[rowIndex].height) / ((float)divisor);
+          float percent = ((float)rowInfo[rowIndex].bSize) / ((float)divisor);
           // give rows their percentage, except for the last row which gets the remainder
           nscoord extraForRow = (numRows - 1 == rowIndex)
-                                ? extraComputedHeight - extraUsed
-                                : NSToCoordRound(((float)extraComputedHeight) * percent);
-          extraForRow = std::min(extraForRow, extraComputedHeight - extraUsed);
-          // update the row height
-          UpdateHeights(rowInfo[rowIndex], extraForRow, heightOfRows, heightOfUnStyledRows);
+                                ? extraComputedBSize - extraUsed
+                                : NSToCoordRound(((float)extraComputedBSize) * percent);
+          extraForRow = std::min(extraForRow, extraComputedBSize - extraUsed);
+          // update the row bsize
+          UpdateBSizes(rowInfo[rowIndex], extraForRow, bSizeOfRows, bSizeOfUnStyledRows);
           extraUsed += extraForRow;
-          if (extraUsed >= extraComputedHeight) {
-            NS_ASSERTION((extraUsed == extraComputedHeight), "invalid row height calculation");
+          if (extraUsed >= extraComputedBSize) {
+            NS_ASSERTION((extraUsed == extraComputedBSize), "invalid row bsize calculation");
             break;
           }
         }
       }
     }
-    rowGroupHeight = aReflowState.ComputedHeight();
+    rowGroupBSize = aReflowState.ComputedBSize();
+  }
+
+  if (wm.IsVertical()) {
+    // we need the correct containerWidth below for block positioning in
+    // vertical-rl writing mode
+    containerWidth = rowGroupBSize;
   }
 
-  nscoord yOrigin = startRowGroupHeight;
-  // update the rows with their (potentially) new heights
-  for (rowFrame = startRowFrame, rowIndex = 0; rowFrame; rowFrame = rowFrame->GetNextRow(), rowIndex++) {
+  nscoord bOrigin = startRowGroupBSize;
+  // update the rows with their (potentially) new bsizes
+  for (rowFrame = startRowFrame, rowIndex = 0; rowFrame;
+       rowFrame = rowFrame->GetNextRow(), rowIndex++) {
     nsRect rowBounds = rowFrame->GetRect();
+    LogicalSize rowBoundsSize(wm, rowBounds.Size());
     nsRect rowVisualOverflow = rowFrame->GetVisualOverflowRect();
-    nscoord deltaY = yOrigin - rowFrame->GetNormalPosition().y;
-
-    nscoord rowHeight = (rowInfo[rowIndex].height > 0) ? rowInfo[rowIndex].height : 0;
+    nscoord deltaB =
+      bOrigin - rowFrame->GetLogicalNormalPosition(wm, containerWidth).B(wm);
 
-    if (deltaY != 0 || (rowHeight != rowBounds.height)) {
+    nscoord rowBSize = (rowInfo[rowIndex].bSize > 0) ? rowInfo[rowIndex].bSize : 0;
+
+    if (deltaB != 0 || (rowBSize != rowBoundsSize.BSize(wm))) {
       // Resize/move the row to its final size and position
-      if (deltaY != 0) {
+      if (deltaB != 0) {
         rowFrame->InvalidateFrameSubtree();
       }
 
-      rowFrame->MovePositionBy(nsPoint(0, deltaY));
-      rowFrame->SetSize(nsSize(rowBounds.width, rowHeight));
+      rowFrame->MovePositionBy(wm, LogicalPoint(wm, 0, deltaB));
+      rowFrame->SetSize(LogicalSize(wm, rowBoundsSize.ISize(wm), rowBSize));
 
       nsTableFrame::InvalidateTableFrame(rowFrame, rowBounds, rowVisualOverflow,
                                          false);
 
-      if (deltaY != 0) {
+      if (deltaB != 0) {
         nsTableFrame::RePositionViews(rowFrame);
         // XXXbz we don't need to update our overflow area?
       }
     }
-    yOrigin += rowHeight + tableFrame->GetRowSpacing(startRowIndex + rowIndex);
+    bOrigin += rowBSize + tableFrame->GetRowSpacing(startRowIndex + rowIndex);
   }
 
-  if (isPaginated && styleHeightAllocation) {
-    // since the row group has a style height, cache the row heights, so next in flows can honor them
-    CacheRowHeightsForPrinting(aPresContext, GetFirstRow());
+  if (isPaginated && styleBSizeAllocation) {
+    // since the row group has a style bsize, cache the row bsizes,
+    // so next in flows can honor them
+    CacheRowBSizesForPrinting(aPresContext, GetFirstRow(), wm);
   }
 
   DidResizeRows(aDesiredSize);
 
-  aDesiredSize.Height() = rowGroupHeight; // Adjust our desired size
+  aDesiredSize.BSize(wm) = rowGroupBSize; // Adjust our desired size
 }
 
 nscoord
-nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aYTotalOffset,
-                                                  nscoord aWidth)
+nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aBTotalOffset,
+                                                  nscoord aISize)
 {
+  WritingMode wm = GetWritingMode(); // XXX pass from caller
   nsTableFrame* tableFrame = GetTableFrame();
+  nscoord containerWidth = tableFrame->GetRect().width;
   const nsStyleVisibility* groupVis = StyleVisibility();
   bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
   if (collapseGroup) {
     tableFrame->SetNeedToCollapse(true);
   }
 
   nsOverflowAreas overflow;
 
-  nsTableRowFrame* rowFrame= GetFirstRow();
+  nsTableRowFrame* rowFrame = GetFirstRow();
   bool didCollapse = false;
-  nscoord yGroupOffset = 0;
+  nscoord bGroupOffset = 0;
   while (rowFrame) {
-    yGroupOffset += rowFrame->CollapseRowIfNecessary(yGroupOffset,
-                                                     aWidth, collapseGroup,
+    bGroupOffset += rowFrame->CollapseRowIfNecessary(bGroupOffset,
+                                                     aISize, collapseGroup,
                                                      didCollapse);
     ConsiderChildOverflow(overflow, rowFrame);
     rowFrame = rowFrame->GetNextRow();
   }
 
-  nsRect groupRect = GetRect();
-  nsRect oldGroupRect = groupRect;
+  LogicalRect groupRect = GetLogicalRect(wm, containerWidth);
+  nsRect oldGroupRect = GetRect();
   nsRect oldGroupVisualOverflow = GetVisualOverflowRect();
 
-  groupRect.height -= yGroupOffset;
+  groupRect.BSize(wm) -= bGroupOffset;
   if (didCollapse) {
     // add back the cellspacing between rowgroups
-    groupRect.height += tableFrame->GetRowSpacing(GetStartRowIndex() +
-                                                  GetRowCount());
+    groupRect.BSize(wm) += tableFrame->GetRowSpacing(GetStartRowIndex() +
+                                                     GetRowCount());
   }
 
-  groupRect.y -= aYTotalOffset;
-  groupRect.width = aWidth;
+  groupRect.BStart(wm) -= aBTotalOffset;
+  groupRect.ISize(wm) = aISize;
 
-  if (aYTotalOffset != 0) {
+  if (aBTotalOffset != 0) {
     InvalidateFrameSubtree();
   }
 
-  SetRect(groupRect);
-  overflow.UnionAllWith(nsRect(0, 0, groupRect.width, groupRect.height));
-  FinishAndStoreOverflow(overflow, groupRect.Size());
+  SetRect(wm, groupRect, containerWidth);
+  overflow.UnionAllWith(nsRect(0, 0, groupRect.Width(wm),
+                               groupRect.Height(wm)));
+  FinishAndStoreOverflow(overflow, groupRect.Size(wm).GetPhysicalSize(wm));
   nsTableFrame::RePositionViews(this);
   nsTableFrame::InvalidateTableFrame(this, oldGroupRect, oldGroupVisualOverflow,
                                      false);
 
-  return yGroupOffset;
+  return bGroupOffset;
 }
 
 // Move a child that was skipped during a reflow.
 void
 nsTableRowGroupFrame::SlideChild(nsRowGroupReflowState& aReflowState,
                                  nsIFrame*              aKidFrame)
 {
   // Move the frame if we need to
-  nsPoint oldPosition = aKidFrame->GetNormalPosition();
-  nsPoint newPosition = oldPosition;
-  newPosition.y = aReflowState.y;
-  if (oldPosition.y != newPosition.y) {
+  WritingMode wm = aReflowState.reflowState.GetWritingMode();
+  LogicalPoint oldPosition = aKidFrame->GetLogicalNormalPosition(wm, 0);
+  LogicalPoint newPosition = oldPosition;
+  newPosition.B(wm) = aReflowState.bCoord;
+  if (oldPosition.B(wm) != newPosition.B(wm)) {
     aKidFrame->InvalidateFrameSubtree();
-    aReflowState.reflowState.ApplyRelativePositioning(&newPosition);
-    aKidFrame->SetPosition(newPosition);
+    aReflowState.reflowState.ApplyRelativePositioning(&newPosition, 0);
+    aKidFrame->SetPosition(wm, newPosition, 0);
     nsTableFrame::RePositionViews(aKidFrame);
     aKidFrame->InvalidateFrameSubtree();
   }
 }
 
 // Create a continuing frame, add it to the child list, and then push it
 // and the frames that follow
 void
@@ -895,69 +934,69 @@ 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,
                                          bool                     aFirstRowIsTopOfPage,
-                                         nscoord                  aSpanningRowBottom,
+                                         nscoord                  aSpanningRowBEnd,
                                          nsTableRowFrame*&        aContRow,
                                          nsTableRowFrame*&        aFirstTruncatedRow,
-                                         nscoord&                 aDesiredHeight)
+                                         nscoord&                 aDesiredBSize)
 {
-  NS_ASSERTION(aSpanningRowBottom >= 0, "Can't split negative heights");
+  NS_ASSERTION(aSpanningRowBEnd >= 0, "Can't split negative bsizes");
   aFirstTruncatedRow = nullptr;
-  aDesiredHeight     = 0;
+  aDesiredBSize     = 0;
 
   const bool borderCollapse = aTable.IsBorderCollapse();
   int32_t lastRowIndex = aLastRow.GetRowIndex();
   bool wasLast = false;
   bool haveRowSpan = false;
   // Iterate the rows between aFirstRow and aLastRow
   for (nsTableRowFrame* row = &aFirstRow; !wasLast; row = row->GetNextRow()) {
     wasLast = (row == &aLastRow);
     int32_t rowIndex = row->GetRowIndex();
     nsPoint rowPos = row->GetNormalPosition();
     // Iterate the cells looking for those that have rowspan > 1
     for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) {
       int32_t 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.
+      // were reflowed correctly during the unconstrained bsize reflow.
       if ((rowSpan > 1) && (rowIndex + rowSpan > lastRowIndex)) {
         haveRowSpan = true;
         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 = aSpanningRowBottom - rowPos.y;
-        NS_ASSERTION(cellAvailHeight >= 0, "No space for cell?");
+        // Ask the row to reflow the cell to the bsize of all the rows it spans up through aLastRow
+        // cellAvailBSize is the space between the row group start and the end of the page
+        nscoord cellAvailBSize = aSpanningRowBEnd - rowPos.y;
+        NS_ASSERTION(cellAvailBSize >= 0, "No space for cell?");
         bool isTopOfPage = (row == &aFirstRow) && aFirstRowIsTopOfPage;
 
         nsRect rowRect = row->GetNormalRect();
         nsSize rowAvailSize(aReflowState.AvailableWidth(),
                             std::max(aReflowState.AvailableHeight() - rowRect.y,
                                    0));
         // don't let the available height exceed what
-        // CalculateRowHeights set for it
+        // CalculateRowBSizes set for it
         rowAvailSize.height = std::min(rowAvailSize.height, rowRect.height);
         nsHTMLReflowState rowReflowState(&aPresContext, aReflowState, row,
                                          LogicalSize(row->GetWritingMode(),
                                                      rowAvailSize),
                                          nullptr,
                                          nsHTMLReflowState::CALLER_WILL_INIT);
         InitChildReflowState(aPresContext, borderCollapse, rowReflowState);
         rowReflowState.mFlags.mIsTopOfPage = isTopOfPage; // set top of page
 
-        nscoord cellHeight = row->ReflowCellFrame(&aPresContext, rowReflowState,
+        nscoord cellBSize = row->ReflowCellFrame(&aPresContext, rowReflowState,
                                                   isTopOfPage, cell,
-                                                  cellAvailHeight, status);
-        aDesiredHeight = std::max(aDesiredHeight, rowPos.y + cellHeight);
+                                                  cellAvailBSize, status);
+        aDesiredBSize = std::max(aDesiredBSize, rowPos.y + cellBSize);
         if (NS_FRAME_IS_COMPLETE(status)) {
-          if (cellHeight > cellAvailHeight) {
+          if (cellBSize > cellAvailBSize) {
             aFirstTruncatedRow = row;
             if ((row != &aFirstRow) || !aFirstRowIsTopOfPage) {
               // return now, since we will be getting another reflow after either (1) row is
               // moved to the next page or (2) the row group is moved to the next page
               return;
             }
           }
         }
@@ -977,17 +1016,17 @@ nsTableRowGroupFrame::SplitSpanningCells
               aContRow->InsertCellFrame(contCell, colIndex);
             }
           }
         }
       }
     }
   }
   if (!haveRowSpan) {
-    aDesiredHeight = aLastRow.GetNormalRect().YMost();
+    aDesiredBSize = aLastRow.GetNormalRect().YMost();
   }
 }
 
 // Remove the next-in-flow of the row, its cells and their cell blocks. This
 // is necessary in case the row doesn't need a continuation later on or needs
 // a continuation which doesn't have the same number of cells that now exist.
 void
 nsTableRowGroupFrame::UndoContinuedRow(nsPresContext*   aPresContext,
@@ -1057,17 +1096,17 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
   // Need to dirty the table's geometry, or else the row might skip
   // reflowing its cell as an optimization.
   aTableFrame->SetGeometryDirty();
 
   // Walk each of the row frames looking for the first row frame that doesn't fit
   // in the available space
   for (nsTableRowFrame* rowFrame = firstRowThisPage; rowFrame; rowFrame = rowFrame->GetNextRow()) {
     bool rowIsOnPage = true;
-    nscoord cellSpacingY = aTableFrame->GetRowSpacing(rowFrame->GetRowIndex());
+    nscoord cellSpacingB = aTableFrame->GetRowSpacing(rowFrame->GetRowIndex());
     nsRect rowRect = rowFrame->GetNormalRect();
     // See if the row fits on this page
     if (rowRect.YMost() > availHeight) {
       nsTableRowFrame* contRow = nullptr;
       // Reflow the row in the availabe space and have it split if it is the 1st
       // row (on the page) or there is at least 5% of the current page available
       // XXX this 5% should be made a preference
       if (!prevRowFrame || (availHeight - aDesiredSize.Height() > pageHeight / 20)) {
@@ -1113,17 +1152,17 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
             // The row stays on this page because either it split ok or we're on the top of page.
             // If top of page and the height exceeded the avail height, then there will be data loss
             NS_ASSERTION(rowMetrics.Height() <= rowReflowState.AvailableHeight(),
                          "data loss - incomplete row needed more height than available, on top of page");
             CreateContinuingRowFrame(*aPresContext, *rowFrame, (nsIFrame**)&contRow);
             if (contRow) {
               aDesiredSize.Height() += rowMetrics.Height();
               if (prevRowFrame)
-                aDesiredSize.Height() += cellSpacingY;
+                aDesiredSize.Height() += cellSpacingB;
             }
             else return NS_ERROR_NULL_POINTER;
           }
           else {
             // Put the row on the next page to give it more height
             rowIsOnPage = false;
           }
         }
@@ -1140,17 +1179,17 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
               // 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;
+                aDesiredSize.Height() += cellSpacingB;
               NS_WARNING("data loss - complete row needed more height than available, on top of page");
             }
             else {
               // We're not on top of the page, so put the row on the next page to give it more height
               rowIsOnPage = false;
             }
           }
         }
@@ -1179,20 +1218,20 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
           aDesiredSize.Height() = rowRect.YMost();
           aStatus = NS_FRAME_COMPLETE;
           break;
         }
       }
       // reflow the cells with rowspan >1 that occur on the page
 
       nsTableRowFrame* firstTruncatedRow;
-      nscoord yMost;
+      nscoord bMost;
       SplitSpanningCells(*aPresContext, aReflowState, *aTableFrame, *firstRowThisPage,
                          *lastRowThisPage, aReflowState.mFlags.mIsTopOfPage, spanningRowBottom, contRow,
-                         firstTruncatedRow, yMost);
+                         firstTruncatedRow, bMost);
       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 {
             // We can't push children, so let our parent reflow us again with more space
@@ -1236,17 +1275,17 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
               aStatus = NS_FRAME_COMPLETE;
               UndoContinuedRow(aPresContext, contRow);
               contRow = nullptr;
             }
           }
         } // if (firstTruncatedRow == firstRowThisPage)
       } // if (firstTruncatedRow)
       else {
-        aDesiredSize.Height() = std::max(aDesiredSize.Height(), yMost);
+        aDesiredSize.Height() = std::max(aDesiredSize.Height(), bMost);
         if (contRow) {
           aStatus = NS_FRAME_NOT_COMPLETE;
         }
       }
       if (NS_FRAME_IS_NOT_COMPLETE(aStatus) && !contRow) {
         nsTableRowFrame* nextRow = lastRowThisPage->GetNextRow();
         if (nextRow) {
           PushChildren(nextRow, lastRowThisPage);
@@ -1328,21 +1367,23 @@ nsTableRowGroupFrame::Reflow(nsPresConte
 
   // XXXmats The following is just bogus.  We leave it here for now because
   // ReflowChildren should pull up rows from our next-in-flow before returning
   // a Complete status, but doesn't (bug 804888).
   if (GetNextInFlow() && GetNextInFlow()->GetFirstPrincipalChild()) {
     NS_FRAME_SET_INCOMPLETE(aStatus);
   }
 
-  SetHasStyleHeight((NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight()) &&
-                    (aReflowState.ComputedHeight() > 0));
+  SetHasStyleBSize((NS_UNCONSTRAINEDSIZE != aReflowState.ComputedBSize()) &&
+                    (aReflowState.ComputedBSize() > 0));
 
-  // just set our width to what was available. The table will calculate the width and not use our value.
-  aDesiredSize.Width() = aReflowState.AvailableWidth();
+  // Just set our isize to what was available.
+  // The table will calculate the isize and not use our value.
+  WritingMode wm = aReflowState.GetWritingMode();
+  aDesiredSize.ISize(wm) = aReflowState.AvailableISize();
 
   aDesiredSize.UnionOverflowAreasWithDesiredBounds();
 
   // If our parent is in initial reflow, it'll handle invalidating our
   // entire overflow rect.
   if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW) &&
       nsSize(aDesiredSize.Width(), aDesiredSize.Height()) != mRect.Size()) {
     InvalidateFrame();
@@ -1508,36 +1549,36 @@ nsTableRowGroupFrame::GetUsedBorder() co
 
 /* virtual */ nsMargin
 nsTableRowGroupFrame::GetUsedPadding() const
 {
   return nsMargin(0,0,0,0);
 }
 
 nscoord
-nsTableRowGroupFrame::GetHeightBasis(const nsHTMLReflowState& aReflowState)
+nsTableRowGroupFrame::GetBSizeBasis(const nsHTMLReflowState& aReflowState)
 {
   nscoord result = 0;
   nsTableFrame* tableFrame = GetTableFrame();
   int32_t startRowIndex = GetStartRowIndex();
-  if ((aReflowState.ComputedHeight() > 0) && (aReflowState.ComputedHeight() < NS_UNCONSTRAINEDSIZE)) {
+  if ((aReflowState.ComputedBSize() > 0) && (aReflowState.ComputedBSize() < NS_UNCONSTRAINEDSIZE)) {
     nscoord cellSpacing = tableFrame->GetRowSpacing(startRowIndex,
                                                     std::max(startRowIndex,
                                                              startRowIndex + GetRowCount() - 1));
-    result = aReflowState.ComputedHeight() - cellSpacing;
+    result = aReflowState.ComputedBSize() - cellSpacing;
   }
   else {
     const nsHTMLReflowState* parentRS = aReflowState.parentReflowState;
     if (parentRS && (tableFrame != parentRS->frame)) {
       parentRS = parentRS->parentReflowState;
     }
     if (parentRS && (tableFrame == parentRS->frame) &&
-        (parentRS->ComputedHeight() > 0) && (parentRS->ComputedHeight() < NS_UNCONSTRAINEDSIZE)) {
+        (parentRS->ComputedBSize() > 0) && (parentRS->ComputedBSize() < NS_UNCONSTRAINEDSIZE)) {
       nscoord cellSpacing = tableFrame->GetRowSpacing(-1, tableFrame->GetRowCount());
-      result = parentRS->ComputedHeight() - cellSpacing;
+      result = parentRS->ComputedBSize() - cellSpacing;
     }
   }
 
   return result;
 }
 
 bool
 nsTableRowGroupFrame::IsSimpleRowFrame(nsTableFrame* aTableFrame,
@@ -1619,31 +1660,31 @@ nsTableRowGroupFrame::GetBCBorderWidth(W
     border.BStart(aWM) = nsPresContext::
       CSSPixelsToAppUnits(firstRowFrame->GetBStartBCBorderWidth());
     border.BEnd(aWM) = nsPresContext::
       CSSPixelsToAppUnits(lastRowFrame->GetBEndBCBorderWidth());
   }
   return border;
 }
 
-void nsTableRowGroupFrame::SetContinuousBCBorderWidth(uint8_t     aForSide,
+void nsTableRowGroupFrame::SetContinuousBCBorderWidth(LogicalSide aForSide,
                                                       BCPixelSize aPixelValue)
 {
   switch (aForSide) {
-    case NS_SIDE_RIGHT:
-      mRightContBorderWidth = aPixelValue;
+    case eLogicalSideIEnd:
+      mIEndContBorderWidth = aPixelValue;
       return;
-    case NS_SIDE_BOTTOM:
-      mBottomContBorderWidth = aPixelValue;
+    case eLogicalSideBEnd:
+      mBEndContBorderWidth = aPixelValue;
       return;
-    case NS_SIDE_LEFT:
-      mLeftContBorderWidth = aPixelValue;
+    case eLogicalSideIStart:
+      mIStartContBorderWidth = aPixelValue;
       return;
     default:
-      NS_ERROR("invalid NS_SIDE argument");
+      NS_ERROR("invalid LogicalSide argument");
   }
 }
 
 //nsILineIterator methods
 int32_t
 nsTableRowGroupFrame::GetNumLines()
 {
   return GetRowCount();
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -18,28 +18,30 @@
 class nsTableRowFrame;
 
 struct nsRowGroupReflowState {
   const nsHTMLReflowState& reflowState;  // Our reflow state
 
   nsTableFrame* tableFrame;
 
   // The available size (computed from the parent)
-  nsSize availSize;
+  mozilla::LogicalSize availSize;
 
-  // Running y-offset
-  nscoord y;
+  // Running block-offset
+  nscoord bCoord;
 
   nsRowGroupReflowState(const nsHTMLReflowState& aReflowState,
                         nsTableFrame*            aTableFrame)
-      :reflowState(aReflowState), tableFrame(aTableFrame)
+      : reflowState(aReflowState)
+      , tableFrame(aTableFrame)
+      , availSize(aReflowState.GetWritingMode(),
+                  aReflowState.AvailableISize(),
+                  aReflowState.AvailableBSize())
+      , bCoord(0)
   {
-    availSize.width  = reflowState.AvailableWidth();
-    availSize.height = reflowState.AvailableHeight();
-    y = 0;
   }
 
   ~nsRowGroupReflowState() {}
 };
 
 #define MIN_ROWS_NEEDING_CURSOR 20
 
 /**
@@ -93,21 +95,21 @@ public:
   virtual nsMargin GetUsedBorder() const override;
   virtual nsMargin GetUsedPadding() const override;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) override;
 
    /** calls Reflow for all of its child rows.
-    * Rows are all set to the same width and stacked vertically.
+    * Rows are all set to the same isize and stacked in the block direction.
     * <P> rows are not split unless absolutely necessary.
     *
-    * @param aDesiredSize width set to width of rows, height set to
-    *                     sum of height of rows that fit in aMaxSize.height.
+    * @param aDesiredSize isize set to isize of rows, bsize set to
+    *                     sum of bsize of rows that fit in AvailableBSize.
     *
     * @see nsIFrame::Reflow
     */
   virtual void Reflow(nsPresContext*           aPresContext,
                       nsHTMLReflowMetrics&     aDesiredSize,
                       const nsHTMLReflowState& aReflowState,
                       nsReflowStatus&          aStatus) override;
 
@@ -153,46 +155,48 @@ public:
    * @param aHeaderFooterFrame the original header or footer row group frame
    * that was repeated
    */
   nsresult  InitRepeatedFrame(nsPresContext*        aPresContext,
                               nsTableRowGroupFrame* aHeaderFooterFrame);
 
 
   /**
-   * Get the total height of all the row rects
+   * Get the total bsize of all the row rects
    */
-  nscoord GetHeightBasis(const nsHTMLReflowState& aReflowState);
+  nscoord GetBSizeBasis(const nsHTMLReflowState& aReflowState);
 
   mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
 
   /**
    * Gets inner border widths before collapsing with cell borders
-   * Caller must get top border from previous row group or from table
-   * GetContinuousBCBorderWidth will not overwrite aBorder.top
+   * Caller must get bstart border from previous row group or from table
+   * GetContinuousBCBorderWidth will not overwrite aBorder.BStart()
    * see nsTablePainter about continuous borders
    */
-  void GetContinuousBCBorderWidth(nsMargin& aBorder);
+  void GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
+                                  mozilla::LogicalMargin& aBorder);
+
   /**
    * Sets full border widths before collapsing with cell borders
-   * @param aForSide - side to set; only right, left, and bottom valid
+   * @param aForSide - side to set; only IEnd, IStart, BEnd are valid
    */
-  void SetContinuousBCBorderWidth(uint8_t     aForSide,
+  void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide,
                                   BCPixelSize aPixelValue);
   /**
     * Adjust to the effect of visibibility:collapse on the row group and
     * its children
-    * @return              additional shift upward that should be applied to
-    *                      subsequent rowgroups due to rows and this rowgroup
-    *                      being collapsed
-    * @param aYTotalOffset the total amount that the rowgroup is shifted up
-    * @param aWidth        new width of the rowgroup
+    * @return              additional shift bstart-wards that should be applied
+    *                      to subsequent rowgroups due to rows and this
+    *                      rowgroup being collapsed
+    * @param aBTotalOffset the total amount that the rowgroup is shifted
+    * @param aISize        new isize of the rowgroup
     */
-  nscoord CollapseRowGroupIfNecessary(nscoord aYTotalOffset,
-                                      nscoord aWidth);
+  nscoord CollapseRowGroupIfNecessary(nscoord aBTotalOffset,
+                                      nscoord aISize);
 
 // nsILineIterator methods
 public:
   virtual void DisposeLineIterator() override { }
 
   // The table row is the equivalent to a line in block layout.
   // The nsILineIterator assumes that a line resides in a block, this role is
   // fullfilled by the row group. Rows in table are counted relative to the
@@ -342,24 +346,26 @@ protected:
                             bool               aBorderCollapse,
                             nsHTMLReflowState& aReflowState);
 
   virtual LogicalSides GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const override;
 
   void PlaceChild(nsPresContext*         aPresContext,
                   nsRowGroupReflowState& aReflowState,
                   nsIFrame*              aKidFrame,
-                  nsPoint                aKidPosition,
+                  mozilla::WritingMode   aWM,
+                  const mozilla::LogicalPoint& aKidPosition,
+                  nscoord                aContainerWidth,
                   nsHTMLReflowMetrics&   aDesiredSize,
                   const nsRect&          aOriginalKidRect,
                   const nsRect&          aOriginalKidVisualOverflow);
 
-  void CalculateRowHeights(nsPresContext*           aPresContext,
-                           nsHTMLReflowMetrics&     aDesiredSize,
-                           const nsHTMLReflowState& aReflowState);
+  void CalculateRowBSizes(nsPresContext*           aPresContext,
+                          nsHTMLReflowMetrics&     aDesiredSize,
+                          const nsHTMLReflowState& aReflowState);
 
   void DidResizeRows(nsHTMLReflowMetrics& aDesiredSize);
 
   void SlideChild(nsRowGroupReflowState& aReflowState,
                   nsIFrame*              aKidFrame);
 
   /**
    * Reflow the frames we've already created
@@ -400,25 +406,25 @@ protected:
 
   void GetNextRowSibling(nsIFrame** aRowFrame);
 
   void UndoContinuedRow(nsPresContext*   aPresContext,
                         nsTableRowFrame* aRow);
 
 private:
   // border widths in pixels in the collapsing border model
-  BCPixelSize mRightContBorderWidth;
-  BCPixelSize mBottomContBorderWidth;
-  BCPixelSize mLeftContBorderWidth;
+  BCPixelSize mIEndContBorderWidth;
+  BCPixelSize mBEndContBorderWidth;
+  BCPixelSize mIStartContBorderWidth;
 
 public:
   bool IsRepeatable() const;
-  void   SetRepeatable(bool aRepeatable);
-  bool HasStyleHeight() const;
-  void   SetHasStyleHeight(bool aValue);
+  void SetRepeatable(bool aRepeatable);
+  bool HasStyleBSize() const;
+  void SetHasStyleBSize(bool aValue);
   bool HasInternalBreakBefore() const;
   bool HasInternalBreakAfter() const;
 };
 
 
 inline bool nsTableRowGroupFrame::IsRepeatable() const
 {
   return (mState & NS_ROWGROUP_REPEATABLE) == NS_ROWGROUP_REPEATABLE;
@@ -428,35 +434,35 @@ inline void nsTableRowGroupFrame::SetRep
 {
   if (aRepeatable) {
     mState |= NS_ROWGROUP_REPEATABLE;
   } else {
     mState &= ~NS_ROWGROUP_REPEATABLE;
   }
 }
 
-inline bool nsTableRowGroupFrame::HasStyleHeight() const
+inline bool nsTableRowGroupFrame::HasStyleBSize() const
 {
   return (mState & NS_ROWGROUP_HAS_STYLE_HEIGHT) == NS_ROWGROUP_HAS_STYLE_HEIGHT;
 }
 
-inline void nsTableRowGroupFrame::SetHasStyleHeight(bool aValue)
+inline void nsTableRowGroupFrame::SetHasStyleBSize(bool aValue)
 {
   if (aValue) {
     mState |= NS_ROWGROUP_HAS_STYLE_HEIGHT;
   } else {
     mState &= ~NS_ROWGROUP_HAS_STYLE_HEIGHT;
   }
 }
 
 inline void
-nsTableRowGroupFrame::GetContinuousBCBorderWidth(nsMargin& aBorder)
+nsTableRowGroupFrame::GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
+                                                 mozilla::LogicalMargin& aBorder)
 {
   int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
-  aBorder.right = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
-                                             mRightContBorderWidth);
-  aBorder.bottom = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
-                                              mBottomContBorderWidth);
-  aBorder.left = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
-                                          mLeftContBorderWidth);
-  return;
+  aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
+                                                 mIEndContBorderWidth);
+  aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
+                                                 mBEndContBorderWidth);
+  aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
+                                                 mIStartContBorderWidth);
 }
 #endif