Bug 789096 patch 10: make Reflow set nsHTMLReflowMetrics.ISize and BSize instead of Width and Height. r=jfkthame
authorSimon Montagu <smontagu@smontagu.org>
Thu, 24 Jul 2014 01:30:07 -0700
changeset 195819 634d33dc9d3ed1fbd09098b7d76d9a754cc80f69
parent 195818 a4ba6995c87e7cf67a7d513ac7e23dcdab76b408
child 195820 35038c3324ee08b29924059da9b117940e740bd7
push id46710
push usersmontagu@mozilla.com
push dateThu, 24 Jul 2014 08:35:12 +0000
treeherdermozilla-inbound@634d33dc9d3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs789096
milestone34.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 789096 patch 10: make Reflow set nsHTMLReflowMetrics.ISize and BSize instead of Width and Height. r=jfkthame
layout/base/nsPresShell.cpp
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsMeterFrame.cpp
layout/forms/nsProgressFrame.cpp
layout/forms/nsRangeFrame.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/WritingModes.h
layout/generic/nsBRFrame.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockReflowContext.cpp
layout/generic/nsBulletFrame.cpp
layout/generic/nsBulletFrame.h
layout/generic/nsCanvasFrame.cpp
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsFirstLetterFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsFrameSetFrame.h
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsHTMLCanvasFrame.cpp
layout/generic/nsHTMLCanvasFrame.h
layout/generic/nsHTMLReflowMetrics.h
layout/generic/nsIFrame.h
layout/generic/nsInlineFrame.cpp
layout/generic/nsLeafFrame.cpp
layout/generic/nsLeafFrame.h
layout/generic/nsLineLayout.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsPageContentFrame.cpp
layout/generic/nsPageFrame.cpp
layout/generic/nsPlaceholderFrame.cpp
layout/generic/nsTextFrame.cpp
layout/generic/nsViewportFrame.cpp
layout/mathml/nsMathMLContainerFrame.cpp
layout/mathml/nsMathMLSelectedFrame.cpp
layout/mathml/nsMathMLTokenFrame.cpp
layout/mathml/nsMathMLmfencedFrame.cpp
layout/mathml/nsMathMLmrootFrame.cpp
layout/svg/SVGTextFrame.cpp
layout/svg/nsSVGForeignObjectFrame.cpp
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableCellFrame.h
layout/tables/nsTableColFrame.cpp
layout/tables/nsTableColGroupFrame.cpp
layout/tables/nsTableFrame.cpp
layout/tables/nsTableOuterFrame.cpp
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowGroupFrame.cpp
layout/xul/nsBoxFrame.cpp
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -8836,21 +8836,20 @@ PresShell::DoReflow(nsIFrame* target, bo
   nsHTMLReflowMetrics desiredSize(reflowState);
   target->Reflow(mPresContext, desiredSize, reflowState, status);
 
   // If an incremental reflow is initiated at a frame other than the
   // root frame, then its desired size had better not change!  If it's
   // initiated at the root, then the size better not change unless its
   // height was unconstrained to start with.
   nsRect boundsRelativeToTarget = nsRect(0, 0, desiredSize.Width(), desiredSize.Height());
-  DebugOnly<nsSize> physicalSize = size.GetPhysicalSize(wm);
   NS_ASSERTION((target == rootFrame &&
                 size.BSize(wm) == NS_UNCONSTRAINEDSIZE) ||
-               (desiredSize.Width() == nsSize(physicalSize).width &&
-                desiredSize.Height() == nsSize(physicalSize).height),
+               (desiredSize.ISize(wm) == size.ISize(wm) &&
+                desiredSize.BSize(wm) == size.BSize(wm)),
                "non-root frame's desired size changed during an "
                "incremental reflow");
   NS_ASSERTION(target == rootFrame ||
                desiredSize.VisualOverflow().IsEqualInterior(boundsRelativeToTarget),
                "non-root reflow roots must not have visible overflow");
   NS_ASSERTION(target == rootFrame ||
                desiredSize.ScrollableOverflow().IsEqualEdges(boundsRelativeToTarget),
                "non-root reflow roots must not have scrollable overflow");
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -399,17 +399,18 @@ nsFieldSetFrame::Reflow(nsPresContext*  
                                 legendAvailSize);
   }
   if (reflowLegend) {
     nsHTMLReflowMetrics legendDesiredSize(aReflowState);
 
     ReflowChild(legend, aPresContext, legendDesiredSize, legendReflowState.ref(),
                 0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
 #ifdef NOISY_REFLOW
-    printf("  returned (%d, %d)\n", legendDesiredSize.Width(), legendDesiredSize.Height());
+    printf("  returned (%d, %d)\n",
+           legendDesiredSize.Width(), legendDesiredSize.Height());
 #endif
     // figure out the legend's rectangle
     legendMargin = legend->GetUsedMargin();
     mLegendRect.width  = legendDesiredSize.Width() + legendMargin.left + legendMargin.right;
     mLegendRect.height = legendDesiredSize.Height() + legendMargin.top + legendMargin.bottom;
     mLegendRect.x = 0;
     mLegendRect.y = 0;
 
@@ -530,19 +531,21 @@ nsFieldSetFrame::Reflow(nsPresContext*  
     nsPoint actualLegendPos(actualLegendRect.TopLeft());
     legendReflowState.ref().ApplyRelativePositioning(&actualLegendPos);
     legend->SetPosition(actualLegendPos);
     nsContainerFrame::PositionFrameView(legend);
     nsContainerFrame::PositionChildViews(legend);
   }
 
   // Return our size and our result.
-  aDesiredSize.Height() = mLegendSpace + border.TopBottom() +
-                          (inner ? inner->GetRect().height : 0);
-  aDesiredSize.Width() = physicalContentRect.width + border.LeftRight();
+  WritingMode wm = aReflowState.GetWritingMode();
+  nsSize finalSize(physicalContentRect.width + border.LeftRight(),
+                   mLegendSpace + border.TopBottom() +
+                   (inner ? inner->GetRect().height : 0));
+  aDesiredSize.SetSize(wm, LogicalSize(wm, finalSize));
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   if (legend)
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, legend);
   if (inner)
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, inner);
 
   // Merge overflow container bounds and status.
   aDesiredSize.mOverflowAreas.UnionWith(ocBounds);
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -109,20 +109,18 @@ nsMeterFrame::Reflow(nsPresContext*     
     nsFormControlFrame::RegUnRegAccessKey(this, true);
   }
 
   nsIFrame* barFrame = mBarDiv->GetPrimaryFrame();
   NS_ASSERTION(barFrame, "The meter frame should have a child with a frame!");
 
   ReflowBarFrame(barFrame, aPresContext, aReflowState, aStatus);
 
-  aDesiredSize.Width() = aReflowState.ComputedWidth() +
-                       aReflowState.ComputedPhysicalBorderPadding().LeftRight();
-  aDesiredSize.Height() = aReflowState.ComputedHeight() +
-                        aReflowState.ComputedPhysicalBorderPadding().TopBottom();
+  aDesiredSize.SetSize(aReflowState.GetWritingMode(),
+                       aReflowState.ComputedSizeWithBorderPadding());
 
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   ConsiderChildOverflow(aDesiredSize.mOverflowAreas, barFrame);
   FinishAndStoreOverflow(&aDesiredSize);
 
   aStatus = NS_FRAME_COMPLETE;
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -114,21 +114,18 @@ nsProgressFrame::Reflow(nsPresContext*  
     nsFormControlFrame::RegUnRegAccessKey(this, true);
   }
 
   nsIFrame* barFrame = mBarDiv->GetPrimaryFrame();
   NS_ASSERTION(barFrame, "The progress frame should have a child with a frame!");
 
   ReflowBarFrame(barFrame, aPresContext, aReflowState, aStatus);
 
-  aDesiredSize.Width() = aReflowState.ComputedWidth() +
-                       aReflowState.ComputedPhysicalBorderPadding().LeftRight();
-  aDesiredSize.Height() = aReflowState.ComputedHeight() +
-                        aReflowState.ComputedPhysicalBorderPadding().TopBottom();
-
+  aDesiredSize.SetSize(aReflowState.GetWritingMode(),
+                       aReflowState.ComputedSizeWithBorderPadding());
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   ConsiderChildOverflow(aDesiredSize.mOverflowAreas, barFrame);
   FinishAndStoreOverflow(&aDesiredSize);
 
   aStatus = NS_FRAME_COMPLETE;
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 }
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -279,24 +279,28 @@ nsRangeFrame::Reflow(nsPresContext*     
   NS_ASSERTION(!GetPrevContinuation() && !GetNextContinuation(),
                "nsRangeFrame should not have continuations; if it does we "
                "need to call RegUnregAccessKey only for the first.");
 
   if (mState & NS_FRAME_FIRST_REFLOW) {
     nsFormControlFrame::RegUnRegAccessKey(this, true);
   }
 
-  nscoord computedHeight = aReflowState.ComputedHeight();
-  if (computedHeight == NS_AUTOHEIGHT) {
-    computedHeight = 0;
+  WritingMode wm = aReflowState.GetWritingMode();
+  nscoord computedBSize = aReflowState.ComputedBSize();
+  if (computedBSize == NS_AUTOHEIGHT) {
+    computedBSize = 0;
   }
-  aDesiredSize.Width() = aReflowState.ComputedWidth() +
-                       aReflowState.ComputedPhysicalBorderPadding().LeftRight();
-  aDesiredSize.Height() = computedHeight +
-                        aReflowState.ComputedPhysicalBorderPadding().TopBottom();
+  LogicalSize
+    finalSize(wm,
+              aReflowState.ComputedISize() +
+              aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm),
+              computedBSize +
+              aReflowState.ComputedLogicalBorderPadding().BStartEnd(wm));
+  aDesiredSize.SetSize(wm, finalSize);
 
   ReflowAnonymousContent(aPresContext, aDesiredSize, aReflowState);
 
   aDesiredSize.SetOverflowAreasToDesiredBounds();
 
   nsIFrame* trackFrame = mTrackDiv->GetPrimaryFrame();
   if (trackFrame) {
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, trackFrame);
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -471,33 +471,36 @@ nsTextControlFrame::Reflow(nsPresContext
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
 
   // make sure that the form registers itself on the initial/first reflow
   if (mState & NS_FRAME_FIRST_REFLOW) {
     nsFormControlFrame::RegUnRegAccessKey(this, true);
   }
 
   // set values of reflow's out parameters
-  aDesiredSize.Width() = aReflowState.ComputedWidth() +
-                       aReflowState.ComputedPhysicalBorderPadding().LeftRight();
-  aDesiredSize.Height() = aReflowState.ComputedHeight() +
-                        aReflowState.ComputedPhysicalBorderPadding().TopBottom();
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize
+    finalSize(wm,
+              aReflowState.ComputedISize() +
+              aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm),
+              aReflowState.ComputedBSize() +
+              aReflowState.ComputedLogicalBorderPadding().BStartEnd(wm));
+  aDesiredSize.SetSize(wm, finalSize);
 
   // computation of the ascent wrt the input height
-  nscoord lineHeight = aReflowState.ComputedHeight();
+  nscoord lineHeight = aReflowState.ComputedBSize();
   float inflation = nsLayoutUtils::FontSizeInflationFor(this);
   if (!IsSingleLineTextControl()) {
     lineHeight = nsHTMLReflowState::CalcLineHeight(GetContent(), StyleContext(),
                                                    NS_AUTOHEIGHT, inflation);
   }
   nsRefPtr<nsFontMetrics> fontMet;
   nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet),
                                         inflation);
   // now adjust for our borders and padding
-  WritingMode wm = aReflowState.GetWritingMode();
   aDesiredSize.SetBlockStartAscent(
     nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight) +
     aReflowState.ComputedLogicalBorderPadding().BStart(wm));
 
   // overflow handling
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   // perform reflow on all kids
   nsIFrame* kid = mFrames.FirstChild();
--- a/layout/generic/WritingModes.h
+++ b/layout/generic/WritingModes.h
@@ -273,16 +273,21 @@ public:
   /**
    * Compare two WritingModes for equality.
    */
   bool operator==(const WritingMode& aOther) const
   {
     return mWritingMode == aOther.mWritingMode;
   }
 
+  bool operator!=(const WritingMode& aOther) const
+  {
+    return mWritingMode != aOther.mWritingMode;
+  }
+
 private:
   friend class LogicalPoint;
   friend class LogicalSize;
   friend class LogicalMargin;
   friend class LogicalRect;
 
   /**
    * Return a WritingMode representing an unknown value.
@@ -589,16 +594,22 @@ public:
       ISize() = aPhysicalSize.height;
       BSize() = aPhysicalSize.width;
     } else {
       ISize() = aPhysicalSize.width;
       BSize() = aPhysicalSize.height;
     }
   }
 
+  void SizeTo(WritingMode aWritingMode, nscoord aISize, nscoord aBSize)
+  {
+    CHECK_WRITING_MODE(aWritingMode);
+    mSize.SizeTo(aISize, aBSize);
+  }
+
   /**
    * Dimensions in logical and physical terms
    */
   nscoord ISize(WritingMode aWritingMode) const // inline-size
   {
     CHECK_WRITING_MODE(aWritingMode);
     return mSize.width;
   }
@@ -670,16 +681,26 @@ public:
    */
   LogicalSize ConvertTo(WritingMode aToMode, WritingMode aFromMode) const
   {
     CHECK_WRITING_MODE(aFromMode);
     return aToMode == aFromMode ?
       *this : LogicalSize(aToMode, GetPhysicalSize(aFromMode));
   }
 
+  bool operator==(const LogicalSize& aOther) const
+  {
+    return mWritingMode == aOther.mWritingMode && mSize == aOther.mSize;
+  }
+
+  bool operator!=(const LogicalSize& aOther) const
+  {
+    return mWritingMode != aOther.mWritingMode || mSize != aOther.mSize;
+  }
+
 private:
   friend class LogicalRect;
 
   LogicalSize() MOZ_DELETE;
 
 #ifdef DEBUG
   WritingMode GetWritingMode() const { return mWritingMode; }
 #else
@@ -1232,16 +1253,18 @@ public:
             mRect.width == 0 && mRect.height == 0);
   }
 
   bool IsZeroSize() const
   {
     return (mRect.width == 0 && mRect.height == 0);
   }
 
+  void SetEmpty() { mRect.SetEmpty(); }
+
 /* XXX are these correct?
   nscoord ILeft(WritingMode aWritingMode) const
   {
     CHECK_WRITING_MODE(aWritingMode);
     return aWritingMode.IsBidiLTR() ? IStart() : IEnd();
   }
   nscoord IRight(WritingMode aWritingMode) const
   {
--- a/layout/generic/nsBRFrame.cpp
+++ b/layout/generic/nsBRFrame.cpp
@@ -80,20 +80,22 @@ BRFrame::~BRFrame()
 void
 BRFrame::Reflow(nsPresContext* aPresContext,
                 nsHTMLReflowMetrics& aMetrics,
                 const nsHTMLReflowState& aReflowState,
                 nsReflowStatus& aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("BRFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aMetrics, aStatus);
-  aMetrics.Height() = 0; // BR frames with height 0 are ignored in quirks
-                       // mode by nsLineLayout::VerticalAlignFrames .
-                       // However, it's not always 0.  See below.
-  aMetrics.Width() = 0;
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize finalSize(wm);
+  finalSize.BSize(wm) = 0; // BR frames with block size 0 are ignored in quirks
+                           // mode by nsLineLayout::VerticalAlignFrames .
+                           // However, it's not always 0.  See below.
+  finalSize.ISize(wm) = 0;
   aMetrics.SetBlockStartAscent(0);
 
   // Only when the BR is operating in a line-layout situation will it
   // behave like a BR.
   nsLineLayout* ll = aReflowState.mLineLayout;
   if (ll) {
     // Note that the compatibility mode check excludes AlmostStandards
     // mode, since this is the inline box model.  See bug 161691.
@@ -114,46 +116,47 @@ BRFrame::Reflow(nsPresContext* aPresCont
       // normal inline frame.  That line-height is used is important
       // here for cases where the line-height is less than 1.
       nsRefPtr<nsFontMetrics> fm;
       nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm),
         nsLayoutUtils::FontSizeInflationFor(this));
       aReflowState.rendContext->SetFont(fm); // FIXME: maybe not needed?
       if (fm) {
         nscoord logicalHeight = aReflowState.CalcLineHeight();
-        aMetrics.Height() = logicalHeight;
+        finalSize.BSize(wm) = logicalHeight;
         aMetrics.SetBlockStartAscent(nsLayoutUtils::GetCenteredFontBaseline(fm, logicalHeight));
       }
       else {
-        aMetrics.SetBlockStartAscent(aMetrics.Height() = 0);
+        aMetrics.SetBlockStartAscent(aMetrics.BSize(wm) = 0);
       }
 
       // XXX temporary until I figure out a better solution; see the
       // code in nsLineLayout::VerticalAlignFrames that zaps minY/maxY
       // if the width is zero.
       // XXX This also fixes bug 10036!
       // Warning: nsTextControlFrame::CalculateSizeStandard depends on
       // the following line, see bug 228752.
-      aMetrics.Width() = 1;
+      finalSize.ISize(wm) = 1;
     }
 
     // Return our reflow status
     uint32_t breakType = aReflowState.mStyleDisplay->mBreakType;
     if (NS_STYLE_CLEAR_NONE == breakType) {
       breakType = NS_STYLE_CLEAR_LINE;
     }
 
     aStatus = NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER |
       NS_INLINE_MAKE_BREAK_TYPE(breakType);
     ll->SetLineEndsInBR(true);
   }
   else {
     aStatus = NS_FRAME_COMPLETE;
   }
 
+  aMetrics.SetSize(wm, finalSize);
   aMetrics.SetOverflowAreasToDesiredBounds();
 
   mAscent = aMetrics.BlockStartAscent();
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
 }
 
 /* virtual */ void
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1246,16 +1246,17 @@ nsBlockFrame::Reflow(nsPresContext*     
   // condition 1.
   // XXX checking oldSize is bogus, there are various reasons we might have
   // reflowed but our size might not have been changed to what we
   // asked for (e.g., we ended up being pushed to a new page)
   // When WillReflowAgainForClearance is true, we will reflow again without
   // resetting the size. Because of this, we must not reflow our abs-pos children
   // in that situation --- what we think is our "new size"
   // will not be our real new size. This also happens to be more efficient.
+  WritingMode parentWM = aMetrics.GetWritingMode();
   if (HasAbsolutelyPositionedChildren()) {
     nsAbsoluteContainingBlock* absoluteContainer = GetAbsoluteContainingBlock();
     bool haveInterrupt = aPresContext->HasPendingInterrupt();
     if (reflowState->WillReflowAgainForClearance() ||
         haveInterrupt) {
       // Make sure that when we reflow again we'll actually reflow all the abs
       // pos frames that might conceivably depend on our size (or all of them,
       // if we're dirty right now and interrupted; in that case we also need
@@ -1263,17 +1264,16 @@ nsBlockFrame::Reflow(nsPresContext*     
       // better than that, because we don't really know what our size will be,
       // and it might in fact not change on the followup reflow!
       if (haveInterrupt && (GetStateBits() & NS_FRAME_IS_DIRTY)) {
         absoluteContainer->MarkAllFramesDirty();
       } else {
         absoluteContainer->MarkSizeDependentFramesDirty();
       }
     } else {
-      WritingMode parentWM = aMetrics.GetWritingMode();
       LogicalSize containingBlockSize =
         CalculateContainingBlockSizeForAbsolutes(parentWM, *reflowState,
                                                  aMetrics.Size(parentWM));
 
       // Mark frames that depend on changes we just made to this frame as dirty:
       // Now we can assume that the padding edge hasn't moved.
       // We need to reflow the absolutes if one of them depends on
       // its placeholder position, or the containing block size in a
@@ -1320,17 +1320,17 @@ nsBlockFrame::Reflow(nsPresContext*     
   // outside that time.
   nsLayoutUtils::AssertNoDuplicateContinuations(this, mFloats);
 
   if (gNoisyReflow) {
     IndentBy(stdout, gNoiseIndent);
     ListTag(stdout);
     printf(": status=%x (%scomplete) metrics=%d,%d carriedMargin=%d",
            aStatus, NS_FRAME_IS_COMPLETE(aStatus) ? "" : "not ",
-           aMetrics.Width(), aMetrics.Height(),
+           aMetrics.ISize(parentWM), aMetrics.BSize(parentWM),
            aMetrics.mCarriedOutBottomMargin.get());
     if (HasOverflowAreas()) {
       printf(" overflow-vis={%d,%d,%d,%d}",
              aMetrics.VisualOverflow().x,
              aMetrics.VisualOverflow().y,
              aMetrics.VisualOverflow().width,
              aMetrics.VisualOverflow().height);
       printf(" overflow-scr={%d,%d,%d,%d}",
@@ -5877,17 +5877,18 @@ nsBlockFrame::ReflowFloat(nsBlockReflowS
   const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
 
   // Set the rect, make sure the view is properly sized and positioned,
   // and tell the frame we're done reflowing it
   // XXXldb This seems like the wrong place to be doing this -- shouldn't
   // we be doing this in nsBlockReflowState::FlowAndPlaceFloat after
   // we've positioned the float, and shouldn't we be doing the equivalent
   // of |PlaceFrameView| here?
-  aFloat->SetSize(nsSize(metrics.Width(), metrics.Height()));
+  WritingMode wm = metrics.GetWritingMode();
+  aFloat->SetSize(wm, metrics.Size(wm));
   if (aFloat->HasView()) {
     nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, aFloat,
                                                aFloat->GetView(),
                                                metrics.VisualOverflow(),
                                                NS_FRAME_NO_MOVE_VIEW);
   }
   // Pass floatRS so the frame hierarchy can be used (redoFloatRS has the same hierarchy)  
   aFloat->DidReflow(aState.mPresContext, &floatRS,
--- a/layout/generic/nsBlockReflowContext.cpp
+++ b/layout/generic/nsBlockReflowContext.cpp
@@ -271,36 +271,39 @@ nsBlockReflowContext::ReflowBlock(const 
       aFrameRS.mBlockDelta =
         mOuterReflowState.mBlockDelta + mBCoord - aLine->BStart();
   }
 
   // Let frame know that we are reflowing it
   mFrame->WillReflow(mPresContext);
 
 #ifdef DEBUG
-  mMetrics.Width() = nscoord(0xdeadbeef);
-  mMetrics.Height() = nscoord(0xdeadbeef);
+  mMetrics.ISize(mWritingMode) = nscoord(0xdeadbeef);
+  mMetrics.BSize(mWritingMode) = nscoord(0xdeadbeef);
 #endif
 
   mOuterReflowState.mFloatManager->Translate(tI, tB);
   mFrame->Reflow(mPresContext, mMetrics, aFrameRS, aFrameReflowStatus);
   mOuterReflowState.mFloatManager->Translate(-tI, -tB);
 
 #ifdef DEBUG
   if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) {
-    if (CRAZY_SIZE(mMetrics.Width()) || CRAZY_SIZE(mMetrics.Height())) {
+    if (CRAZY_SIZE(mMetrics.ISize(mWritingMode)) ||
+        CRAZY_SIZE(mMetrics.BSize(mWritingMode))) {
       printf("nsBlockReflowContext: ");
       nsFrame::ListTag(stdout, mFrame);
-      printf(" metrics=%d,%d!\n", mMetrics.Width(), mMetrics.Height());
+      printf(" metrics=%d,%d!\n",
+             mMetrics.ISize(mWritingMode), mMetrics.BSize(mWritingMode));
     }
-    if ((mMetrics.Width() == nscoord(0xdeadbeef)) ||
-        (mMetrics.Height() == nscoord(0xdeadbeef))) {
+    if ((mMetrics.ISize(mWritingMode) == nscoord(0xdeadbeef)) ||
+        (mMetrics.BSize(mWritingMode) == nscoord(0xdeadbeef))) {
       printf("nsBlockReflowContext: ");
       nsFrame::ListTag(stdout, mFrame);
-      printf(" didn't set w/h %d,%d!\n", mMetrics.Width(), mMetrics.Height());
+      printf(" didn't set i/b %d,%d!\n",
+             mMetrics.ISize(mWritingMode), mMetrics.BSize(mWritingMode));
     }
   }
 #endif
 
   if (!mFrame->HasOverflowAreas()) {
     mMetrics.SetOverflowAreasToDesiredBounds();
   }
 
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -285,28 +285,29 @@ nsBulletFrame::BuildDisplayList(nsDispla
 }
 
 void
 nsBulletFrame::PaintBullet(nsRenderingContext& aRenderingContext, nsPoint aPt,
                            const nsRect& aDirtyRect, uint32_t aFlags)
 {
   const nsStyleList* myList = StyleList();
   CounterStyle* listStyleType = myList->GetCounterStyle();
+  nsMargin padding = mPadding.GetPhysicalMargin(GetWritingMode());
 
   if (myList->GetListStyleImage() && mImageRequest) {
     uint32_t status;
     mImageRequest->GetImageStatus(&status);
     if (status & imgIRequest::STATUS_LOAD_COMPLETE &&
         !(status & imgIRequest::STATUS_ERROR)) {
       nsCOMPtr<imgIContainer> imageCon;
       mImageRequest->GetImage(getter_AddRefs(imageCon));
       if (imageCon) {
-        nsRect dest(mPadding.left, mPadding.top,
-                    mRect.width - (mPadding.left + mPadding.right),
-                    mRect.height - (mPadding.top + mPadding.bottom));
+        nsRect dest(padding.left, padding.top,
+                    mRect.width - (padding.left + padding.right),
+                    mRect.height - (padding.top + padding.bottom));
         nsLayoutUtils::DrawSingleImage(&aRenderingContext, PresContext(),
              imageCon, nsLayoutUtils::GetGraphicsFilterForFrame(this),
              dest + aPt, aDirtyRect, nullptr, aFlags);
         return;
       }
     }
   }
 
@@ -314,31 +315,31 @@ nsBulletFrame::PaintBullet(nsRenderingCo
   aRenderingContext.SetColor(nsLayoutUtils::GetColor(this, eCSSProperty_color));
 
   nsAutoString text;
   switch (listStyleType->GetStyle()) {
   case NS_STYLE_LIST_STYLE_NONE:
     break;
 
   case NS_STYLE_LIST_STYLE_DISC:
-    aRenderingContext.FillEllipse(mPadding.left + aPt.x, mPadding.top + aPt.y,
-                                  mRect.width - (mPadding.left + mPadding.right),
-                                  mRect.height - (mPadding.top + mPadding.bottom));
+    aRenderingContext.FillEllipse(padding.left + aPt.x, padding.top + aPt.y,
+                                  mRect.width - (padding.left + padding.right),
+                                  mRect.height - (padding.top + padding.bottom));
     break;
 
   case NS_STYLE_LIST_STYLE_CIRCLE:
-    aRenderingContext.DrawEllipse(mPadding.left + aPt.x, mPadding.top + aPt.y,
-                                  mRect.width - (mPadding.left + mPadding.right),
-                                  mRect.height - (mPadding.top + mPadding.bottom));
+    aRenderingContext.DrawEllipse(padding.left + aPt.x, padding.top + aPt.y,
+                                  mRect.width - (padding.left + padding.right),
+                                  mRect.height - (padding.top + padding.bottom));
     break;
 
   case NS_STYLE_LIST_STYLE_SQUARE:
     {
       nsRect rect(aPt, mRect.Size());
-      rect.Deflate(mPadding);
+      rect.Deflate(padding);
 
       // Snap the height and the width of the rectangle to device pixels,
       // and then center the result within the original rectangle, so that
       // all square bullets at the same font size have the same visual
       // size (bug 376690).
       // FIXME: We should really only do this if we're not transformed
       // (like gfxContext::UserToDevicePixelSnapped does).
       nsPresContext *pc = PresContext();
@@ -351,17 +352,17 @@ nsBulletFrame::PaintBullet(nsRenderingCo
                                  snapRect.width, snapRect.height);
     }
     break;
 
   case NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED:
   case NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN:
     {
       nsRect rect(aPt, mRect.Size());
-      rect.Deflate(mPadding);
+      rect.Deflate(padding);
 
       WritingMode wm = GetWritingMode();
       bool isVertical = wm.IsVertical();
       bool isClosed =
         listStyleType->GetStyle() == NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED;
       bool isDown = (!isVertical && !isClosed) || (isVertical && isClosed);
       nscoord diff = NSToCoordRound(0.1f * rect.height);
       if (isDown) {
@@ -399,17 +400,17 @@ nsBulletFrame::PaintBullet(nsRenderingCo
     break;
 
   default:
     nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm),
                                           GetFontSizeInflation());
     GetListItemText(text);
     aRenderingContext.SetFont(fm);
     nscoord ascent = fm->MaxAscent();
-    aPt.MoveBy(mPadding.left, mPadding.top);
+    aPt.MoveBy(padding.left, padding.top);
     aPt.y = NSToCoordRound(nsLayoutUtils::GetSnappedBaselineY(
             this, aRenderingContext.ThebesContext(), aPt.y, ascent));
     nsPresContext* presContext = PresContext();
     if (!presContext->BidiEnabled() && HasRTLChars(text)) {
       presContext->SetBidiEnabled();
     }
     nsLayoutUtils::DrawString(this, &aRenderingContext,
                               text.get(), text.Length(), aPt);
@@ -482,115 +483,112 @@ nsBulletFrame::GetListItemText(nsAString
   aResult.Append(suffix);
 }
 
 #define MIN_BULLET_SIZE 1
 
 void
 nsBulletFrame::AppendSpacingToPadding(nsFontMetrics* aFontMetrics)
 {
-  nscoord halfEm = aFontMetrics->EmHeight() / 2;
-  WritingMode wm = GetWritingMode();
-  if (wm.IsVertical()) {
-    mPadding.bottom += halfEm;
-  } else if (wm.IsBidiLTR()) {
-    mPadding.right += halfEm;
-  } else {
-    mPadding.left += halfEm;
-  }
+  mPadding.IEnd(GetWritingMode()) += aFontMetrics->EmHeight() / 2;
 }
 
 void
 nsBulletFrame::GetDesiredSize(nsPresContext*  aCX,
                               nsRenderingContext *aRenderingContext,
                               nsHTMLReflowMetrics& aMetrics,
                               float aFontSizeInflation)
 {
   // Reset our padding.  If we need it, we'll set it below.
-  mPadding.SizeTo(0, 0, 0, 0);
-  
+  WritingMode wm = GetWritingMode();
+  mPadding.SizeTo(wm, 0, 0, 0, 0);
+  LogicalSize finalSize(wm);
+
   const nsStyleList* myList = StyleList();
   nscoord ascent;
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm),
                                         aFontSizeInflation);
 
   RemoveStateBits(BULLET_FRAME_IMAGE_LOADING);
 
   if (myList->GetListStyleImage() && mImageRequest) {
     uint32_t status;
     mImageRequest->GetImageStatus(&status);
     if (status & imgIRequest::STATUS_SIZE_AVAILABLE &&
         !(status & imgIRequest::STATUS_ERROR)) {
       // auto size the image
-      aMetrics.Width() = mIntrinsicSize.width;
-      aMetrics.SetBlockStartAscent(aMetrics.Height() = mIntrinsicSize.height);
+      finalSize.ISize(wm) = mIntrinsicSize.ISize(wm);
+      aMetrics.SetBlockStartAscent(finalSize.BSize(wm) =
+                                   mIntrinsicSize.BSize(wm));
+      aMetrics.SetSize(wm, finalSize);
 
       AppendSpacingToPadding(fm);
 
       AddStateBits(BULLET_FRAME_IMAGE_LOADING);
 
       return;
     }
   }
 
   // If we're getting our desired size and don't have an image, reset
   // mIntrinsicSize to (0,0).  Otherwise, if we used to have an image, it
   // changed, and the new one is coming in, but we're reflowing before it's
   // fully there, we'll end up with mIntrinsicSize not matching our size, but
   // won't trigger a reflow in OnStartContainer (because mIntrinsicSize will
   // match the image size).
-  mIntrinsicSize.SizeTo(0, 0);
+  mIntrinsicSize.SizeTo(wm, 0, 0);
 
   nscoord bulletSize;
 
   nsAutoString text;
   switch (myList->GetCounterStyle()->GetStyle()) {
     case NS_STYLE_LIST_STYLE_NONE:
-      aMetrics.Width() = aMetrics.Height() = 0;
+      finalSize.ISize(wm) = finalSize.BSize(wm) = 0;
       aMetrics.SetBlockStartAscent(0);
       break;
 
     case NS_STYLE_LIST_STYLE_DISC:
     case NS_STYLE_LIST_STYLE_CIRCLE:
     case NS_STYLE_LIST_STYLE_SQUARE: {
       ascent = fm->MaxAscent();
       bulletSize = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
                           NSToCoordRound(0.8f * (float(ascent) / 2.0f)));
-      mPadding.bottom = NSToCoordRound(float(ascent) / 8.0f);
-      aMetrics.Width() = aMetrics.Height() = bulletSize;
-      aMetrics.SetBlockStartAscent(bulletSize + mPadding.bottom);
+      mPadding.BEnd(wm) = NSToCoordRound(float(ascent) / 8.0f);
+      finalSize.ISize(wm) = finalSize.BSize(wm) = bulletSize;
+      aMetrics.SetBlockStartAscent(bulletSize + mPadding.BEnd(wm));
       AppendSpacingToPadding(fm);
       break;
     }
 
     case NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED:
     case NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN:
       ascent = fm->EmAscent();
       bulletSize = std::max(
           nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
           NSToCoordRound(0.75f * ascent));
-      mPadding.bottom = NSToCoordRound(0.125f * ascent);
-      aMetrics.Width() = aMetrics.Height() = bulletSize;
-      if (!GetWritingMode().IsVertical()) {
-        aMetrics.SetBlockStartAscent(bulletSize + mPadding.bottom);
+      mPadding.BEnd(wm) = NSToCoordRound(0.125f * ascent);
+      finalSize.ISize(wm) = finalSize.BSize(wm) = bulletSize;
+      if (!wm.IsVertical()) {
+        aMetrics.SetBlockStartAscent(bulletSize + mPadding.BEnd(wm));
       }
       AppendSpacingToPadding(fm);
       break;
 
     default:
       GetListItemText(text);
-      aMetrics.Height() = fm->MaxHeight();
+      finalSize.BSize(wm) = fm->MaxHeight();
       aRenderingContext->SetFont(fm);
-      aMetrics.Width() =
+      finalSize.ISize(wm) =
         nsLayoutUtils::GetStringWidth(this, aRenderingContext,
                                       text.get(), text.Length());
       aMetrics.SetBlockStartAscent(fm->MaxAscent());
       break;
   }
+  aMetrics.SetSize(wm, finalSize);
 }
 
 void
 nsBulletFrame::Reflow(nsPresContext* aPresContext,
                       nsHTMLReflowMetrics& aMetrics,
                       const nsHTMLReflowState& aReflowState,
                       nsReflowStatus& aStatus)
 {
@@ -600,51 +598,58 @@ nsBulletFrame::Reflow(nsPresContext* aPr
   float inflation = nsLayoutUtils::FontSizeInflationFor(this);
   SetFontSizeInflation(inflation);
 
   // Get the base size
   GetDesiredSize(aPresContext, aReflowState.rendContext, aMetrics, inflation);
 
   // Add in the border and padding; split the top/bottom between the
   // ascent and descent to make things look nice
-  const nsMargin& borderPadding = aReflowState.ComputedPhysicalBorderPadding();
-  mPadding.top += NSToCoordRound(borderPadding.top * inflation);
-  mPadding.right += NSToCoordRound(borderPadding.right * inflation);
-  mPadding.bottom += NSToCoordRound(borderPadding.bottom * inflation);
-  mPadding.left += NSToCoordRound(borderPadding.left * inflation);
-  aMetrics.Width() += mPadding.left + mPadding.right;
-  aMetrics.Height() += mPadding.top + mPadding.bottom;
-  aMetrics.SetBlockStartAscent(aMetrics.BlockStartAscent() + mPadding.top);
+  WritingMode wm = aReflowState.GetWritingMode();
+  const LogicalMargin& bp = aReflowState.ComputedLogicalBorderPadding();
+  mPadding.BStart(wm) += NSToCoordRound(bp.BStart(wm) * inflation);
+  mPadding.IEnd(wm) += NSToCoordRound(bp.IEnd(wm) * inflation);
+  mPadding.BEnd(wm) += NSToCoordRound(bp.BEnd(wm) * inflation);
+  mPadding.IStart(wm) += NSToCoordRound(bp.IStart(wm) * inflation);
+
+  WritingMode lineWM = aMetrics.GetWritingMode();
+  LogicalMargin linePadding = mPadding.ConvertTo(lineWM, wm);
+  aMetrics.ISize(lineWM) += linePadding.IStartEnd(lineWM);
+  aMetrics.BSize(lineWM) += linePadding.BStartEnd(lineWM);
+  aMetrics.SetBlockStartAscent(aMetrics.BlockStartAscent() +
+                               linePadding.BStart(lineWM));
 
   // XXX this is a bit of a hack, we're assuming that no glyphs used for bullets
   // overflow their font-boxes. It'll do for now; to fix it for real, we really
   // should rewrite all the text-handling code here to use gfxTextRun (bug
   // 397294).
   aMetrics.SetOverflowAreasToDesiredBounds();
 
   aStatus = NS_FRAME_COMPLETE;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
 }
 
 /* virtual */ nscoord
 nsBulletFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
 {
-  nsHTMLReflowMetrics metrics(GetWritingMode());
-  DISPLAY_MIN_WIDTH(this, metrics.Width());
+  WritingMode wm = GetWritingMode();
+  nsHTMLReflowMetrics metrics(wm);
+  DISPLAY_MIN_WIDTH(this, metrics.ISize(wm));
   GetDesiredSize(PresContext(), aRenderingContext, metrics, 1.0f);
-  return metrics.Width();
+  return metrics.ISize(wm);
 }
 
 /* virtual */ nscoord
 nsBulletFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
 {
-  nsHTMLReflowMetrics metrics(GetWritingMode());
-  DISPLAY_PREF_WIDTH(this, metrics.Width());
+  WritingMode wm = GetWritingMode();
+  nsHTMLReflowMetrics metrics(wm);
+  DISPLAY_PREF_WIDTH(this, metrics.ISize(wm));
   GetDesiredSize(PresContext(), aRenderingContext, metrics, 1.0f);
-  return metrics.Width();
+  return metrics.ISize(wm);
 }
 
 NS_IMETHODIMP
 nsBulletFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
 {
   if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
     nsCOMPtr<imgIContainer> image;
     aRequest->GetImage(getter_AddRefs(image));
@@ -683,18 +688,19 @@ nsresult nsBulletFrame::OnStartContainer
   }
   
   nscoord w, h;
   aImage->GetWidth(&w);
   aImage->GetHeight(&h);
 
   nsPresContext* presContext = PresContext();
 
-  nsSize newsize(nsPresContext::CSSPixelsToAppUnits(w),
-                 nsPresContext::CSSPixelsToAppUnits(h));
+  LogicalSize newsize(GetWritingMode(),
+                      nsSize(nsPresContext::CSSPixelsToAppUnits(w),
+                             nsPresContext::CSSPixelsToAppUnits(h)));
 
   if (mIntrinsicSize != newsize) {
     mIntrinsicSize = newsize;
 
     // Now that the size is available (or an error occurred), trigger
     // a reflow of the bullet frame.
     nsIPresShell *shell = presContext->GetPresShell();
     if (shell) {
@@ -778,46 +784,46 @@ nsBulletFrame::GetImage() const
   }
 
   return nullptr;
 }
 
 nscoord
 nsBulletFrame::GetLogicalBaseline(WritingMode aWritingMode) const
 {
-  nscoord ascent = 0, bottomPadding;
+  nscoord ascent = 0, baselinePadding;
   if (GetStateBits() & BULLET_FRAME_IMAGE_LOADING) {
     ascent = BSize(aWritingMode);
   } else {
     nsRefPtr<nsFontMetrics> fm;
     nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm),
                                           GetFontSizeInflation());
     CounterStyle* listStyleType = StyleList()->GetCounterStyle();
     switch (listStyleType->GetStyle()) {
       case NS_STYLE_LIST_STYLE_NONE:
         break;
 
       case NS_STYLE_LIST_STYLE_DISC:
       case NS_STYLE_LIST_STYLE_CIRCLE:
       case NS_STYLE_LIST_STYLE_SQUARE:
         ascent = fm->MaxAscent();
-        bottomPadding = NSToCoordRound(float(ascent) / 8.0f);
+        baselinePadding = NSToCoordRound(float(ascent) / 8.0f);
         ascent = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
                         NSToCoordRound(0.8f * (float(ascent) / 2.0f)));
-        ascent += bottomPadding;
+        ascent += baselinePadding;
         break;
 
       case NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED:
       case NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN:
         ascent = fm->EmAscent();
-        bottomPadding = NSToCoordRound(0.125f * ascent);
+        baselinePadding = NSToCoordRound(0.125f * ascent);
         ascent = std::max(
             nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
             NSToCoordRound(0.75f * ascent));
-        ascent += bottomPadding;
+        ascent += baselinePadding;
         break;
 
       default:
         ascent = fm->MaxAscent();
         break;
     }
   }
   return ascent +
--- a/layout/generic/nsBulletFrame.h
+++ b/layout/generic/nsBulletFrame.h
@@ -43,16 +43,18 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 #ifdef DEBUG
   NS_DECL_QUERYFRAME_TARGET(nsBulletFrame)
   NS_DECL_QUERYFRAME
 #endif
 
   nsBulletFrame(nsStyleContext* aContext)
     : nsFrame(aContext)
+    , mPadding(GetWritingMode())
+    , mIntrinsicSize(GetWritingMode())
   {
   }
   virtual ~nsBulletFrame();
 
   NS_IMETHOD Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
 
   // nsIFrame
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
@@ -105,21 +107,21 @@ protected:
   void AppendSpacingToPadding(nsFontMetrics* aFontMetrics);
   void GetDesiredSize(nsPresContext* aPresContext,
                       nsRenderingContext *aRenderingContext,
                       nsHTMLReflowMetrics& aMetrics,
                       float aFontSizeInflation);
 
   void GetLoadGroup(nsPresContext *aPresContext, nsILoadGroup **aLoadGroup);
 
-  nsMargin mPadding;
+  mozilla::LogicalMargin mPadding;
   nsRefPtr<imgRequestProxy> mImageRequest;
   nsRefPtr<nsBulletListener> mListener;
 
-  nsSize mIntrinsicSize;
+  mozilla::LogicalSize mIntrinsicSize;
   int32_t mOrdinal;
 
 private:
 
   // This is a boolean flag indicating whether or not the current image request
   // has been registered with the refresh driver.
   bool mRequestRegistered;
 };
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -594,24 +594,27 @@ nsCanvasFrame::Reflow(nsPresContext*    
       // which doesn't need to be painted.
       nsIFrame* viewport = PresContext()->GetPresShell()->GetRootFrame();
       viewport->InvalidateFrame();
     }
     
     // Return our desired size. Normally it's what we're told, but
     // sometimes we can be given an unconstrained height (when a window
     // is sizing-to-content), and we should compute our desired height.
-    aDesiredSize.Width() = aReflowState.ComputedWidth();
-    if (aReflowState.ComputedHeight() == NS_UNCONSTRAINEDSIZE) {
-      aDesiredSize.Height() = kidFrame->GetRect().height +
-        kidReflowState.ComputedPhysicalMargin().TopBottom();
+    WritingMode wm = aReflowState.GetWritingMode();
+    LogicalSize finalSize(wm);
+    finalSize.ISize(wm) = aReflowState.ComputedISize();
+    if (aReflowState.ComputedBSize() == NS_UNCONSTRAINEDSIZE) {
+      finalSize.BSize(wm) = kidFrame->GetLogicalSize(wm).BSize(wm) +
+        kidReflowState.ComputedLogicalMargin().BStartEnd(wm);
     } else {
-      aDesiredSize.Height() = aReflowState.ComputedHeight();
+      finalSize.BSize(wm) = aReflowState.ComputedBSize();
     }
 
+    aDesiredSize.SetSize(wm, finalSize);
     aDesiredSize.SetOverflowAreasToDesiredBounds();
     aDesiredSize.mOverflowAreas.UnionWith(
       kidDesiredSize.mOverflowAreas + kidPt);
   }
 
   if (prevCanvasFrame) {
     ReflowOverflowContainerChildren(aPresContext, aReflowState,
                                     aDesiredSize.mOverflowAreas, 0,
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -707,46 +707,50 @@ nsColumnSetFrame::ReflowChildren(nsHTMLR
   }
   
   aColData.mMaxHeight = contentBEnd;
   contentRect.height = std::max(contentRect.height, contentBEnd);
   mLastFrameStatus = aStatus;
   
   // contentRect included the borderPadding.left,borderPadding.top of the child rects
   contentRect -= nsPoint(borderPadding.left, borderPadding.top);
-  
-  nsSize contentSize = nsSize(contentRect.XMost(), contentRect.YMost());
+
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize contentSize(wm, nsSize(contentRect.XMost(), contentRect.YMost()));
 
   // Apply computed and min/max values
+  // (aConfig members need to be converted from Width/Height to ISize/BSize)
   if (aConfig.mComputedHeight != NS_INTRINSICSIZE) {
     if (aReflowState.AvailableHeight() != NS_INTRINSICSIZE) {
-      contentSize.height = std::min(contentSize.height,
-                                    aConfig.mComputedHeight);
+      contentSize.BSize(wm) = std::min(contentSize.BSize(wm),
+                                       aConfig.mComputedHeight);
     } else {
-      contentSize.height = aConfig.mComputedHeight;
+      contentSize.BSize(wm) = aConfig.mComputedHeight;
     }
   } else {
     // We add the "consumed" height back in so that we're applying
     // constraints to the correct height value, then subtract it again
     // after we've finished with the min/max calculation. This prevents us from
     // having a last continuation that is smaller than the min height. but which
     // has prev-in-flows, trigger a larger height than actually required.
-    contentSize.height = aReflowState.ApplyMinMaxHeight(contentSize.height,
-                                                        aConfig.mConsumedHeight);
+    contentSize.BSize(wm) =
+      aReflowState.ApplyMinMaxHeight(contentSize.BSize(wm),
+                                     aConfig.mConsumedHeight);
   }
-  if (aReflowState.ComputedWidth() != NS_INTRINSICSIZE) {
-    contentSize.width = aReflowState.ComputedWidth();
+  if (aReflowState.ComputedISize() != NS_INTRINSICSIZE) {
+    contentSize.ISize(wm) = aReflowState.ComputedISize();
   } else {
-    contentSize.width = aReflowState.ApplyMinMaxWidth(contentSize.width);
+    contentSize.ISize(wm) =
+      aReflowState.ApplyMinMaxWidth(contentSize.ISize(wm));
   }
 
-  aDesiredSize.Height() = contentSize.height +
-                        borderPadding.TopBottom();
-  aDesiredSize.Width() = contentSize.width +
-                       borderPadding.LeftRight();
+  LogicalMargin bp(wm, borderPadding);
+  contentSize.ISize(wm) += bp.IStartEnd(wm);
+  contentSize.BSize(wm) += bp.BStartEnd(wm);
+  aDesiredSize.SetSize(wm, contentSize);
   aDesiredSize.mOverflowAreas = overflowRects;
   aDesiredSize.UnionOverflowAreasWithDesiredBounds();
 
 #ifdef DEBUG_roc
   printf("*** DONE PASS feasible=%d\n", allFit && NS_FRAME_IS_FULLY_COMPLETE(aStatus)
          && !NS_FRAME_IS_TRUNCATED(aStatus));
 #endif
   return allFit && NS_FRAME_IS_FULLY_COMPLETE(aStatus)
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -217,17 +217,18 @@ nsFirstLetterFrame::Reflow(nsPresContext
     ll->BeginSpan(this, &aReflowState, bp.IStart(wm),
                   availSize.ISize(wm), &mBaseline);
     ll->ReflowFrame(kid, aReflowStatus, &aMetrics, pushedFrame);
     ll->EndSpan(this);
     ll->SetInFirstLetter(false);
   }
 
   // Place and size the child and update the output metrics
-  LogicalSize convertedSize(wm, nsSize(aMetrics.Width(), aMetrics.Height()));
+  WritingMode lineWM = aMetrics.GetWritingMode();
+  LogicalSize convertedSize = aMetrics.Size(lineWM).ConvertTo(wm, lineWM);
   kid->SetRect(nsRect(bp.IStart(wm), bp.BStart(wm),
                       convertedSize.ISize(wm), convertedSize.BSize(wm)));
   kid->FinishAndStoreOverflow(&aMetrics);
   kid->DidReflow(aPresContext, nullptr, nsDidReflowStatus::FINISHED);
 
   convertedSize.ISize(wm) += bp.IStartEnd(wm);
   convertedSize.BSize(wm) += bp.BStartEnd(wm);
   aMetrics.SetSize(wm, convertedSize);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4358,18 +4358,17 @@ nsFrame::CanContinueTextRun() const
 
 void
 nsFrame::Reflow(nsPresContext*          aPresContext,
                 nsHTMLReflowMetrics&     aDesiredSize,
                 const nsHTMLReflowState& aReflowState,
                 nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsFrame");
-  aDesiredSize.Width() = 0;
-  aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
   aStatus = NS_FRAME_COMPLETE;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 }
 
 nsresult
 nsFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
 {
   NS_NOTREACHED("should only be called for text frames");
@@ -5332,18 +5331,17 @@ bool
 nsFrame::IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
                             nsHTMLReflowMetrics& aMetrics,
                             nsReflowStatus& aStatus)
 {
   if (aReflowState.mReflowDepth >  MAX_FRAME_DEPTH) {
     NS_WARNING("frame tree too deep; setting zero size and returning");
     mState |= NS_FRAME_TOO_DEEP_IN_FRAME_TREE;
     ClearOverflowRects();
-    aMetrics.Width() = 0;
-    aMetrics.Height() = 0;
+    aMetrics.ClearSize();
     aMetrics.SetBlockStartAscent(0);
     aMetrics.mCarriedOutBottomMargin.Zero();
     aMetrics.mOverflowAreas.Clear();
 
     if (GetNextInFlow()) {
       // Reflow depth might vary between reflows, so we might have
       // successfully reflowed and split this frame before.  If so, we
       // shouldn't delete its continuations.
@@ -8092,81 +8090,85 @@ nsFrame::GetBoxAscent(nsBoxLayoutState& 
 
 nsresult
 nsFrame::DoLayout(nsBoxLayoutState& aState)
 {
   nsRect ourRect(mRect);
 
   nsRenderingContext* rendContext = aState.GetRenderingContext();
   nsPresContext* presContext = aState.PresContext();
-  const WritingMode wm = aState.OuterReflowState() ?
-    aState.OuterReflowState()->GetWritingMode() : GetWritingMode();
-  nsHTMLReflowMetrics desiredSize(wm);
- 
+  WritingMode ourWM = GetWritingMode();
+  const WritingMode outerWM = aState.OuterReflowState() ?
+    aState.OuterReflowState()->GetWritingMode() : ourWM;
+  nsHTMLReflowMetrics desiredSize(outerWM);
+  LogicalSize ourSize = GetLogicalSize().ConvertTo(outerWM, ourWM);
+
   if (rendContext) {
 
     BoxReflow(aState, presContext, desiredSize, rendContext,
               ourRect.x, ourRect.y, ourRect.width, ourRect.height);
 
     if (IsCollapsed()) {
       SetSize(nsSize(0, 0));
     } else {
 
       // if our child needs to be bigger. This might happend with
       // wrapping text. There is no way to predict its height until we
       // reflow it. Now that we know the height reshuffle upward.
-      if (desiredSize.Width() > ourRect.width ||
-          desiredSize.Height() > ourRect.height) {
+      if (desiredSize.ISize(outerWM) > ourSize.ISize(outerWM) ||
+          desiredSize.BSize(outerWM) > ourSize.BSize(outerWM)) {
 
 #ifdef DEBUG_GROW
         DumpBox(stdout);
         printf(" GREW from (%d,%d) -> (%d,%d)\n",
-               ourRect.width, ourRect.height,
-               desiredSize.Width(), desiredSize.Height());
+               ourSize.ISize(outerWM), ourSize.BSize(outerWM),
+               desiredSize.ISize(outerWM), desiredSize.BSize(outerWM));
 #endif
 
-        if (desiredSize.Width() > ourRect.width)
-          ourRect.width = desiredSize.Width();
-
-        if (desiredSize.Height() > ourRect.height)
-          ourRect.height = desiredSize.Height();
+        if (desiredSize.ISize(outerWM) > ourSize.ISize(outerWM)) {
+          ourSize.ISize(outerWM) = desiredSize.ISize(outerWM);
+        }
+
+        if (desiredSize.BSize(outerWM) > ourSize.BSize(outerWM)) {
+          ourSize.BSize(outerWM) = desiredSize.BSize(outerWM);
+        }
       }
 
       // ensure our size is what we think is should be. Someone could have
       // reset the frame to be smaller or something dumb like that. 
-      SetSize(ourRect.Size());
+      SetSize(ourSize.ConvertTo(ourWM, outerWM));
     }
   }
 
   // Should we do this if IsCollapsed() is true?
-  nsSize size(GetSize());
-  desiredSize.Width() = size.width;
-  desiredSize.Height() = size.height;
+  LogicalSize size(GetLogicalSize().ConvertTo(outerWM, ourWM));
+  desiredSize.ISize(outerWM) = size.ISize(outerWM);
+  desiredSize.BSize(outerWM) = size.BSize(outerWM);
   desiredSize.UnionOverflowAreasWithDesiredBounds();
 
   if (HasAbsolutelyPositionedChildren()) {
     // Set up a |reflowState| to pass into ReflowAbsoluteFrames
-    WritingMode wm = GetWritingMode();
     nsHTMLReflowState reflowState(aState.PresContext(), this,
                                   aState.GetRenderingContext(),
-                                  LogicalSize(wm, GetLogicalSize().ISize(wm),
+                                  LogicalSize(ourWM, size.ISize(ourWM),
                                               NS_UNCONSTRAINEDSIZE),
                                   nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
 
     AddStateBits(NS_FRAME_IN_REFLOW);
     // Set up a |reflowStatus| to pass into ReflowAbsoluteFrames
     // (just a dummy value; hopefully that's OK)
     nsReflowStatus reflowStatus = NS_FRAME_COMPLETE;
     ReflowAbsoluteFrames(aState.PresContext(), desiredSize,
                          reflowState, reflowStatus);
     RemoveStateBits(NS_FRAME_IN_REFLOW);
   }
 
   nsSize oldSize(ourRect.Size());
-  FinishAndStoreOverflow(desiredSize.mOverflowAreas, size, &oldSize);
+  FinishAndStoreOverflow(desiredSize.mOverflowAreas,
+                         size.GetPhysicalSize(outerWM), &oldSize);
 
   SyncLayout(aState);
 
   return NS_OK;
 }
 
 void
 nsFrame::BoxReflow(nsBoxLayoutState&        aState,
@@ -8186,31 +8188,32 @@ nsFrame::BoxReflow(nsBoxLayoutState&    
   printf("Reflowing: ");
   nsFrame::ListTag(stdout, mFrame);
   printf("\n");
   gIndent2++;
 #endif
 
   nsBoxLayoutMetrics *metrics = BoxMetrics();
   nsReflowStatus status = NS_FRAME_COMPLETE;
+  WritingMode wm = aDesiredSize.GetWritingMode();
 
   bool needsReflow = NS_SUBTREE_DIRTY(this);
 
   // if we don't need a reflow then 
   // lets see if we are already that size. Yes? then don't even reflow. We are done.
   if (!needsReflow) {
       
       if (aWidth != NS_INTRINSICSIZE && aHeight != NS_INTRINSICSIZE) {
       
           // if the new calculated size has a 0 width or a 0 height
           if ((metrics->mLastSize.width == 0 || metrics->mLastSize.height == 0) && (aWidth == 0 || aHeight == 0)) {
                needsReflow = false;
                aDesiredSize.Width() = aWidth; 
                aDesiredSize.Height() = aHeight; 
-               SetSize(nsSize(aDesiredSize.Width(), aDesiredSize.Height()));
+               SetSize(aDesiredSize.Size(wm).ConvertTo(GetWritingMode(), wm));
           } else {
             aDesiredSize.Width() = metrics->mLastSize.width;
             aDesiredSize.Height() = metrics->mLastSize.height;
 
             // remove the margin. The rect of our child does not include it but our calculated size does.
             // don't reflow if we are already the right size
             if (metrics->mLastSize.width == aWidth && metrics->mLastSize.height == aHeight)
                   needsReflow = false;
@@ -8223,38 +8226,37 @@ nsFrame::BoxReflow(nsBoxLayoutState&    
           // we don't know what it should be.
          needsReflow = true;
       }
   }
 
   // ok now reflow the child into the spacers calculated space
   if (needsReflow) {
 
-    aDesiredSize.Width() = 0;
-    aDesiredSize.Height() = 0;
+    aDesiredSize.ClearSize();
 
     // create a reflow state to tell our child to flow at the given size.
 
     // Construct a bogus parent reflow state so that there's a usable
     // containing block reflow state.
     nsMargin margin(0,0,0,0);
     GetMargin(margin);
 
     nsSize parentSize(aWidth, aHeight);
     if (parentSize.height != NS_INTRINSICSIZE)
       parentSize.height += margin.TopBottom();
     if (parentSize.width != NS_INTRINSICSIZE)
       parentSize.width += margin.LeftRight();
 
     nsIFrame *parentFrame = GetParent();
     nsFrameState savedState = parentFrame->GetStateBits();
+    WritingMode parentWM = parentFrame->GetWritingMode();
     nsHTMLReflowState
       parentReflowState(aPresContext, parentFrame, aRenderingContext,
-                        LogicalSize(parentFrame->GetWritingMode(),
-                                    parentSize),
+                        LogicalSize(parentWM, parentSize),
                         nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
     parentFrame->RemoveStateBits(~nsFrameState(0));
     parentFrame->AddStateBits(savedState);
 
     // This may not do very much useful, but it's probably worth trying.
     if (parentSize.width != NS_INTRINSICSIZE)
       parentReflowState.SetComputedWidth(std::max(parentSize.width, 0));
     if (parentSize.height != NS_INTRINSICSIZE)
@@ -8376,17 +8378,16 @@ nsFrame::BoxReflow(nsBoxLayoutState&    
                                         &reflowState, aX, aY, layoutFlags | NS_FRAME_NO_MOVE_FRAME);
 
     // Save the ascent.  (bug 103925)
     if (IsCollapsed()) {
       metrics->mAscent = 0;
     } else {
       if (aDesiredSize.BlockStartAscent() ==
           nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
-        WritingMode wm = aDesiredSize.GetWritingMode();
         if (!nsLayoutUtils::GetFirstLineBaseline(wm, this, &metrics->mAscent))
           metrics->mAscent = GetLogicalBaseline(wm);
       } else
         metrics->mAscent = aDesiredSize.BlockStartAscent();
     }
 
   } else {
     aDesiredSize.SetBlockStartAscent(metrics->mBlockAscent);
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -614,72 +614,76 @@ int32_t nsHTMLFramesetFrame::GetBorderWi
   return nsPresContext::CSSPixelsToAppUnits(DEFAULT_BORDER_WIDTH_PX);
 }
 
 void
 nsHTMLFramesetFrame::GetDesiredSize(nsPresContext*           aPresContext,
                                     const nsHTMLReflowState& aReflowState,
                                     nsHTMLReflowMetrics&     aDesiredSize)
 {
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize desiredSize(wm);
   nsHTMLFramesetFrame* framesetParent = do_QueryFrame(GetParent());
   if (nullptr == framesetParent) {
     if (aPresContext->IsPaginated()) {
       // XXX This needs to be changed when framesets paginate properly
-      aDesiredSize.Width() = aReflowState.AvailableWidth();
-      aDesiredSize.Height() = aReflowState.AvailableHeight();
+      desiredSize.ISize(wm) = aReflowState.AvailableISize();
+      desiredSize.BSize(wm) = aReflowState.AvailableBSize();
     } else {
-      nsRect area = aPresContext->GetVisibleArea();
+      LogicalSize area(wm, aPresContext->GetVisibleArea().Size());
 
-      aDesiredSize.Width() = area.width;
-      aDesiredSize.Height() = area.height;
+      desiredSize.ISize(wm) = area.ISize(wm);
+      desiredSize.BSize(wm) = area.BSize(wm);
     }
   } else {
-    nsSize size;
-    framesetParent->GetSizeOfChild(this, size);
-    aDesiredSize.Width() = size.width;
-    aDesiredSize.Height() = size.height;
+    LogicalSize size(wm);
+    framesetParent->GetSizeOfChild(this, wm, size);
+    desiredSize.ISize(wm) = size.ISize(wm);
+    desiredSize.BSize(wm) = size.BSize(wm);
   }
+  aDesiredSize.SetSize(wm, desiredSize);
 }
 
 // only valid for non border children
 void nsHTMLFramesetFrame::GetSizeOfChildAt(int32_t  aIndexInParent,
-                                           nsSize&  aSize,
+                                           WritingMode aWM,
+                                           LogicalSize&  aSize,
                                            nsIntPoint& aCellIndex)
 {
   int32_t row = aIndexInParent / mNumCols;
   int32_t col = aIndexInParent - (row * mNumCols); // remainder from dividing index by mNumCols
   if ((row < mNumRows) && (col < mNumCols)) {
-    aSize.width  = mColSizes[col];
-    aSize.height = mRowSizes[row];
+    aSize.ISize(aWM) = mColSizes[col];
+    aSize.BSize(aWM) = mRowSizes[row];
     aCellIndex.x = col;
     aCellIndex.y = row;
   } else {
-    aSize.width = aSize.height = 0;
+    aSize.SizeTo(aWM, 0, 0);
     aCellIndex.x = aCellIndex.y = 0;
   }
 }
 
 // only valid for non border children
 void nsHTMLFramesetFrame::GetSizeOfChild(nsIFrame* aChild,
-                                         nsSize&   aSize)
+                                         WritingMode aWM,
+                                         LogicalSize& aSize)
 {
   // Reflow only creates children frames for <frameset> and <frame> content.
   // this assumption is used here
   int i = 0;
   for (nsIFrame* child = mFrames.FirstChild(); child;
        child = child->GetNextSibling()) {
     if (aChild == child) {
       nsIntPoint ignore;
-      GetSizeOfChildAt(i, aSize, ignore);
+      GetSizeOfChildAt(i, aWM, aSize, ignore);
       return;
     }
     i++;
   }
-  aSize.width  = 0;
-  aSize.height = 0;
+  aSize.SizeTo(aWM, 0, 0);
 }
 
 
 nsresult nsHTMLFramesetFrame::HandleEvent(nsPresContext* aPresContext,
                                            WidgetGUIEvent* aEvent,
                                            nsEventStatus* aEventStatus)
 {
   NS_ENSURE_ARG_POINTER(aEventStatus);
@@ -930,21 +934,24 @@ nsHTMLFramesetFrame::Reflow(nsPresContex
 
   // reflow the children
   int32_t lastRow = 0;
   int32_t lastCol = 0;
   int32_t borderChildX = mNonBorderChildCount; // index of border children
   nsHTMLFramesetBorderFrame* borderFrame = nullptr;
   nsPoint offset(0,0);
   nsSize size, lastSize;
+  WritingMode wm = GetWritingMode();
+  LogicalSize logicalSize(wm);
   nsIFrame* child = mFrames.FirstChild();
 
   for (int32_t childX = 0; childX < mNonBorderChildCount; childX++) {
     nsIntPoint cellIndex;
-    GetSizeOfChildAt(childX, size, cellIndex);
+    GetSizeOfChildAt(childX, wm, logicalSize, cellIndex);
+    size = logicalSize.GetPhysicalSize(wm);
 
     if (lastRow != cellIndex.y) {  // changed to next row
       offset.x = 0;
       offset.y += lastSize.height;
       if (firstTime) { // create horizontal border
 
         nsRefPtr<nsStyleContext> pseudoStyleContext;
         pseudoStyleContext = styleSet->
--- a/layout/generic/nsFrameSetFrame.h
+++ b/layout/generic/nsFrameSetFrame.h
@@ -76,20 +76,22 @@ public:
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow) MOZ_OVERRIDE;
 
   virtual void SetInitialChildList(ChildListID  aListID,
                                    nsFrameList& aChildList) MOZ_OVERRIDE;
 
   static bool    gDragInProgress;
 
-  void GetSizeOfChild(nsIFrame* aChild, nsSize& aSize);
+  void GetSizeOfChild(nsIFrame* aChild, mozilla::WritingMode aWM,
+                      mozilla::LogicalSize& aSize);
 
-  void GetSizeOfChildAt(int32_t  aIndexInParent, 
-                        nsSize&  aSize, 
+  void GetSizeOfChildAt(int32_t  aIndexInParent,
+                        mozilla::WritingMode aWM,
+                        mozilla::LogicalSize&  aSize,
                         nsIntPoint& aCellIndex);
 
   virtual nsresult HandleEvent(nsPresContext* aPresContext, 
                                mozilla::WidgetGUIEvent* aEvent,
                                nsEventStatus* aEventStatus) MOZ_OVERRIDE;
 
   virtual nsresult GetCursor(const nsPoint&    aPoint,
                              nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -7,16 +7,18 @@
 /* rendering object for CSS "display: grid | inline-grid" */
 
 #include "nsGridContainerFrame.h"
 
 #include "nsCSSAnonBoxes.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 
+using namespace mozilla;
+
 //----------------------------------------------------------------------
 
 // Frame class boilerplate
 // =======================
 
 NS_QUERYFRAME_HEAD(nsGridContainerFrame)
   NS_QUERYFRAME_ENTRY(nsGridContainerFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
@@ -48,24 +50,27 @@ nsGridContainerFrame::Reflow(nsPresConte
   if (IsFrameTreeTooDeep(aReflowState, aDesiredSize, aStatus)) {
     return;
   }
 
 #ifdef DEBUG
   SanityCheckAnonymousGridItems();
 #endif // DEBUG
 
-  nsMargin bp = aReflowState.ComputedPhysicalBorderPadding();
-  bp.ApplySkipSides(GetSkipSides());
-  nscoord contentHeight = GetEffectiveComputedBSize(aReflowState);
-  if (contentHeight == NS_AUTOHEIGHT) {
-    contentHeight = 0;
+  LogicalMargin bp = aReflowState.ComputedLogicalBorderPadding();
+  bp.ApplySkipSides(GetLogicalSkipSides());
+  nscoord contentBSize = GetEffectiveComputedBSize(aReflowState);
+  if (contentBSize == NS_AUTOHEIGHT) {
+    contentBSize = 0;
   }
-  aDesiredSize.Width() = aReflowState.ComputedWidth() + bp.LeftRight();
-  aDesiredSize.Height() = contentHeight + bp.TopBottom();
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize finalSize(wm,
+                        aReflowState.ComputedISize() + bp.IStartEnd(wm),
+                        contentBSize + bp.BStartEnd(wm));
+  aDesiredSize.SetSize(wm, finalSize);
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   aStatus = NS_FRAME_COMPLETE;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 }
 
 nsIAtom*
 nsGridContainerFrame::GetType() const
 {
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -182,65 +182,69 @@ nsHTMLCanvasFrame::Reflow(nsPresContext*
   NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
                   ("enter nsHTMLCanvasFrame::Reflow: availSize=%d,%d",
                   aReflowState.AvailableWidth(), aReflowState.AvailableHeight()));
 
   NS_PRECONDITION(mState & NS_FRAME_IN_REFLOW, "frame is not in reflow");
 
   aStatus = NS_FRAME_COMPLETE;
 
-  aMetrics.Width() = aReflowState.ComputedWidth();
-  aMetrics.Height() = aReflowState.ComputedHeight();
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize finalSize(wm,
+                        aReflowState.ComputedISize(),
+                        aReflowState.ComputedBSize());
 
   // stash this away so we can compute our inner area later
-  mBorderPadding   = aReflowState.ComputedPhysicalBorderPadding();
+  mBorderPadding   = aReflowState.ComputedLogicalBorderPadding();
 
-  aMetrics.Width() += mBorderPadding.left + mBorderPadding.right;
-  aMetrics.Height() += mBorderPadding.top + mBorderPadding.bottom;
+  finalSize.ISize(wm) += mBorderPadding.IStartEnd(wm);
+  finalSize.BSize(wm) += mBorderPadding.BStartEnd(wm);
 
   if (GetPrevInFlow()) {
-    nscoord y = GetContinuationOffset(&aMetrics.Width());
-    aMetrics.Height() -= y + mBorderPadding.top;
-    aMetrics.Height() = std::max(0, aMetrics.Height());
+    nscoord y = GetContinuationOffset(&finalSize.ISize(wm));
+    finalSize.BSize(wm) -= y + mBorderPadding.BStart(wm);
+    finalSize.BSize(wm) = std::max(0, finalSize.BSize(wm));
   }
 
+  aMetrics.SetSize(wm, finalSize);
   aMetrics.SetOverflowAreasToDesiredBounds();
   FinishAndStoreOverflow(&aMetrics);
 
   // Reflow the single anon block child.
   nsReflowStatus childStatus;
   nsIFrame* childFrame = mFrames.FirstChild();
-  WritingMode wm = childFrame->GetWritingMode();
-  LogicalSize availSize = aReflowState.ComputedSize(wm);
-  availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
+  WritingMode childWM = childFrame->GetWritingMode();
+  LogicalSize availSize = aReflowState.ComputedSize(childWM);
+  availSize.BSize(childWM) = NS_UNCONSTRAINEDSIZE;
   NS_ASSERTION(!childFrame->GetNextSibling(), "HTML canvas should have 1 kid");
   nsHTMLReflowMetrics childDesiredSize(aReflowState.GetWritingMode(), aMetrics.mFlags);
   nsHTMLReflowState childReflowState(aPresContext, aReflowState, childFrame,
                                      availSize);
   ReflowChild(childFrame, aPresContext, childDesiredSize, childReflowState,
               0, 0, 0, childStatus, nullptr);
   FinishReflowChild(childFrame, aPresContext, childDesiredSize,
                     &childReflowState, 0, 0, 0);
 
   NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
                   ("exit nsHTMLCanvasFrame::Reflow: size=%d,%d",
-                  aMetrics.Width(), aMetrics.Height()));
+                   aMetrics.ISize(wm), aMetrics.BSize(wm)));
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
 }
 
 // FIXME taken from nsImageFrame, but then had splittable frame stuff
 // removed.  That needs to be fixed.
 nsRect 
 nsHTMLCanvasFrame::GetInnerArea() const
 {
+  nsMargin bp = mBorderPadding.GetPhysicalMargin(GetWritingMode());
   nsRect r;
-  r.x = mBorderPadding.left;
-  r.y = mBorderPadding.top;
-  r.width = mRect.width - mBorderPadding.left - mBorderPadding.right;
-  r.height = mRect.height - mBorderPadding.top - mBorderPadding.bottom;
+  r.x = bp.left;
+  r.y = bp.top;
+  r.width = mRect.width - bp.left - bp.right;
+  r.height = mRect.height - bp.top - bp.bottom;
   return r;
 }
 
 already_AddRefed<Layer>
 nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
                               LayerManager* aManager,
                               nsDisplayItem* aItem,
                               const ContainerLayerParameters& aContainerParameters)
@@ -316,17 +320,17 @@ nsHTMLCanvasFrame::GetContinuationOffset
   if (GetPrevInFlow()) {
     for (nsIFrame* prevInFlow = GetPrevInFlow() ; prevInFlow; prevInFlow = prevInFlow->GetPrevInFlow()) {
       nsRect rect = prevInFlow->GetRect();
       if (aWidth) {
         *aWidth = rect.width;
       }
       offset += rect.height;
     }
-    offset -= mBorderPadding.top;
+    offset -= mBorderPadding.GetPhysicalMargin(GetWritingMode()).top;
     offset = std::max(0, offset);
   }
   return offset;
 }
 
 #ifdef ACCESSIBILITY
 a11y::AccType
 nsHTMLCanvasFrame::AccessibleType()
--- a/layout/generic/nsHTMLCanvasFrame.h
+++ b/layout/generic/nsHTMLCanvasFrame.h
@@ -31,17 +31,19 @@ public:
   typedef mozilla::layers::Layer Layer;
   typedef mozilla::layers::LayerManager LayerManager;
   typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
 
   NS_DECL_QUERYFRAME_TARGET(nsHTMLCanvasFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
-  nsHTMLCanvasFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) {}
+  nsHTMLCanvasFrame(nsStyleContext* aContext)
+  : nsContainerFrame(aContext)
+    , mBorderPadding(GetWritingMode()) {}
 
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
@@ -90,12 +92,12 @@ public:
     return GetFirstPrincipalChild()->GetContentInsertionFrame();
   }
 
 protected:
   virtual ~nsHTMLCanvasFrame();
 
   nscoord GetContinuationOffset(nscoord* aWidth = 0) const;
 
-  nsMargin mBorderPadding;
+  mozilla::LogicalMargin mBorderPadding;
 };
 
 #endif /* nsHTMLCanvasFrame_h___ */
--- a/layout/generic/nsHTMLReflowMetrics.h
+++ b/layout/generic/nsHTMLReflowMetrics.h
@@ -244,16 +244,22 @@ public:
   // writing mode as necessary.
   void SetSize(mozilla::WritingMode aWM, mozilla::LogicalSize aSize)
   {
     mozilla::LogicalSize convertedSize = aSize.ConvertTo(mWritingMode, aWM);
     mBSize = convertedSize.BSize(mWritingMode);
     mISize = convertedSize.ISize(mWritingMode);
   }
 
+  // Set both inline and block size to zero -- no need for a writing mode!
+  void ClearSize()
+  {
+    mISize = mBSize = 0;
+  }
+
   // Width and Height are physical dimensions, independent of writing mode.
   // Accessing these is slightly more expensive than accessing the logical
   // dimensions (once vertical writing mode support is enabled); as far as
   // possible, client code should work purely with logical dimensions.
   nscoord Width() const { return mWritingMode.IsVertical() ? mBSize : mISize; }
   nscoord Height() const { return mWritingMode.IsVertical() ? mISize : mBSize; }
 
   // It's only meaningful to consider "ascent" on the block-start side of the
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -707,16 +707,30 @@ public:
    * Set this frame's rect from a logical rect in a different writing direction
    * (GetPhysicalRect will assert if the writing mode doesn't match)
    */
   void SetRect(mozilla::WritingMode aWritingMode,
                const mozilla::LogicalRect& aRect,
                nscoord aContainerWidth) {
     SetRect(aRect.GetPhysicalRect(aWritingMode, aContainerWidth));
   }
+
+  /**
+   * Set this frame's size from a logical size in its own writing direction
+   */
+  void SetSize(const mozilla::LogicalSize& aSize) {
+    SetSize(GetWritingMode(), aSize);
+  }
+  /*
+   * Set this frame's size from a logical size in a different writing direction
+   */
+  void SetSize(mozilla::WritingMode aWritingMode,
+               const mozilla::LogicalSize& aSize) {
+    SetSize(aSize.GetPhysicalSize(aWritingMode));
+  }
   void SetSize(const nsSize& aSize) {
     SetRect(nsRect(mRect.TopLeft(), aSize));
   }
   void SetPosition(const nsPoint& aPt) { mRect.MoveTo(aPt); }
 
   /**
    * Move the frame, accounting for relative positioning. Use this when
    * adjusting the frame's position by a known amount, to properly update its
@@ -1413,16 +1427,20 @@ public:
 
   /**
    * Return the last frame in our current flow.
    */
   virtual nsIFrame* LastInFlow() const {
     return const_cast<nsIFrame*>(this);
   }
 
+  /**
+   * Note: "width" in the names and comments on the following methods
+   * means inline-size, which could be height in vertical layout
+   */
 
   /**
    * Mark any stored intrinsic width information as dirty (requiring
    * re-calculation).  Note that this should generally not be called
    * directly; nsPresShell::FrameNeedsReflow will call it instead.
    */
   virtual void MarkIntrinsicWidthsDirty() = 0;
 
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -720,17 +720,17 @@ nsInlineFrame::ReflowFrames(nsPresContex
     //
     // The height of our box is the sum of our font size plus the top
     // and bottom border and padding. The height of children do not
     // affect our height.
     aMetrics.SetBlockStartAscent(fm->MaxAscent());
     aMetrics.BSize(lineWM) = fm->MaxHeight();
   } else {
     NS_WARNING("Cannot get font metrics - defaulting sizes to 0");
-    aMetrics.SetBlockStartAscent(aMetrics.Height() = 0);
+    aMetrics.SetBlockStartAscent(aMetrics.BSize(lineWM) = 0);
   }
   aMetrics.SetBlockStartAscent(aMetrics.BlockStartAscent() +
                                framePadding.BStart(frameWM));
   aMetrics.BSize(lineWM) +=
     aReflowState.ComputedLogicalBorderPadding().BStartEnd(frameWM);
 
   // For now our overflow area is zero. The real value will be
   // computed in |nsLineLayout::RelativePositionFrames|.
--- a/layout/generic/nsLeafFrame.cpp
+++ b/layout/generic/nsLeafFrame.cpp
@@ -3,16 +3,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* base class for rendering objects that do not have child lists */
 
 #include "nsLeafFrame.h"
 #include "nsPresContext.h"
 
+using namespace mozilla;
+
 nsLeafFrame::~nsLeafFrame()
 {
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsLeafFrame)
 
 /* virtual */ nscoord
 nsLeafFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
@@ -66,50 +68,57 @@ nsLeafFrame::DoReflow(nsPresContext* aPr
                       const nsHTMLReflowState& aReflowState,
                       nsReflowStatus& aStatus)
 {
   NS_ASSERTION(aReflowState.ComputedWidth() != NS_UNCONSTRAINEDSIZE,
                "Shouldn't have unconstrained stuff here "
                "Thanks to the rules of reflow");
   NS_ASSERTION(NS_INTRINSICSIZE != aReflowState.ComputedHeight(),
                "Shouldn't have unconstrained stuff here "
-               "thanks to ComputeAutoSize");  
+               "thanks to ComputeAutoSize");
 
-  aMetrics.Width() = aReflowState.ComputedWidth();
-  aMetrics.Height() = aReflowState.ComputedHeight();
-  
-  AddBordersAndPadding(aReflowState, aMetrics);
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize finalSize(wm,
+                        aReflowState.ComputedISize(),
+                        aReflowState.ComputedBSize());
+
+  AddBordersAndPadding(aReflowState, finalSize);
+  aMetrics.SetSize(wm, finalSize);
+
   aStatus = NS_FRAME_COMPLETE;
 
   NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
                  ("exit nsLeafFrame::DoReflow: size=%d,%d",
-                  aMetrics.Width(), aMetrics.Height()));
+                  aMetrics.ISize(wm), aMetrics.BSize(wm)));
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
 
   aMetrics.SetOverflowAreasToDesiredBounds();
 }
 
 nscoord
 nsLeafFrame::GetIntrinsicHeight()
 {
   NS_NOTREACHED("Someone didn't override Reflow or ComputeAutoSize");
   return 0;
 }
 
 // XXX how should border&padding effect baseline alignment?
 // => descent = borderPadding.bottom for example
 void
 nsLeafFrame::AddBordersAndPadding(const nsHTMLReflowState& aReflowState,
-                                  nsHTMLReflowMetrics& aMetrics)
+                                  LogicalSize& aSize)
 {
-  aMetrics.Width() += aReflowState.ComputedPhysicalBorderPadding().LeftRight();
-  aMetrics.Height() += aReflowState.ComputedPhysicalBorderPadding().TopBottom();
+  WritingMode wm = aReflowState.GetWritingMode();
+  aSize.ISize(wm) += aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm);
+  aSize.BSize(wm) += aReflowState.ComputedLogicalBorderPadding().BStartEnd(wm);
 }
 
 void
 nsLeafFrame::SizeToAvailSize(const nsHTMLReflowState& aReflowState,
                              nsHTMLReflowMetrics& aDesiredSize)
 {
-  aDesiredSize.Width() = aReflowState.AvailableWidth(); // FRAME
-  aDesiredSize.Height() = aReflowState.AvailableHeight();
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize size(wm, aReflowState.AvailableISize(), // FRAME
+                   aReflowState.AvailableBSize());
+  aDesiredSize.SetSize(wm, size);
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   FinishAndStoreOverflow(&aDesiredSize);  
 }
--- a/layout/generic/nsLeafFrame.h
+++ b/layout/generic/nsLeafFrame.h
@@ -90,17 +90,17 @@ protected:
    * call this method.
    */
   virtual nscoord GetIntrinsicHeight();
 
   /**
    * Subroutine to add in borders and padding
    */
   void AddBordersAndPadding(const nsHTMLReflowState& aReflowState,
-                            nsHTMLReflowMetrics& aDesiredSize);
+                            mozilla::LogicalSize& aDesiredSize);
 
   /**
    * Set aDesiredSize to be the available size
    */
   void SizeToAvailSize(const nsHTMLReflowState& aReflowState,
                        nsHTMLReflowMetrics& aDesiredSize);
 };
 
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -832,18 +832,18 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra
   // Let frame know that are reflowing it. Note that we don't bother
   // positioning the frame yet, because we're probably going to end up
   // moving it when we do the block-direction alignment
   aFrame->WillReflow(mPresContext);
 
   // Adjust spacemanager coordinate system for the frame.
   nsHTMLReflowMetrics metrics(lineWM);
 #ifdef DEBUG
-  metrics.Width() = nscoord(0xdeadbeef);
-  metrics.Height() = nscoord(0xdeadbeef);
+  metrics.ISize(lineWM) = nscoord(0xdeadbeef);
+  metrics.BSize(lineWM) = nscoord(0xdeadbeef);
 #endif
   nsRect physicalBounds = pfd->mBounds.GetPhysicalRect(lineWM, mContainerWidth);
   nscoord tx = physicalBounds.x;
   nscoord ty = physicalBounds.y;
   mFloatManager->Translate(tx, ty);
 
   int32_t savedOptionalBreakOffset;
   gfxBreakPriority savedOptionalBreakPriority;
@@ -926,26 +926,31 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra
       } else {
         isEmpty = pfd->mFrame->IsEmpty();
       }
     }
   }
 
   mFloatManager->Translate(-tx, -ty);
 
-  NS_ASSERTION(metrics.Width() >= 0, "bad width");
-  NS_ASSERTION(metrics.Height() >= 0,"bad height");
-  if (metrics.Width() < 0) metrics.Width() = 0;
-  if (metrics.Height() < 0) metrics.Height() = 0;
+  NS_ASSERTION(metrics.ISize(lineWM) >= 0, "bad inline size");
+  NS_ASSERTION(metrics.BSize(lineWM) >= 0,"bad block size");
+  if (metrics.ISize(lineWM) < 0) {
+    metrics.ISize(lineWM) = 0;
+  }
+  if (metrics.BSize(lineWM) < 0) {
+    metrics.BSize(lineWM) = 0;
+  }
 
 #ifdef DEBUG
   // Note: break-before means ignore the reflow metrics since the
   // frame will be reflowed another time.
   if (!NS_INLINE_IS_BREAK_BEFORE(aReflowStatus)) {
-    if (CRAZY_SIZE(metrics.Width()) || CRAZY_SIZE(metrics.Height())) {
+    if (CRAZY_SIZE(metrics.ISize(lineWM)) ||
+        CRAZY_SIZE(metrics.BSize(lineWM))) {
       printf("nsLineLayout: ");
       nsFrame::ListTag(stdout, aFrame);
       printf(" metrics=%d,%d!\n", metrics.Width(), metrics.Height());
     }
     if ((metrics.Width() == nscoord(0xdeadbeef)) ||
         (metrics.Height() == nscoord(0xdeadbeef))) {
       printf("nsLineLayout: ");
       nsFrame::ListTag(stdout, aFrame);
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -432,23 +432,22 @@ nsObjectFrame::GetPrefWidth(nsRenderingC
 }
 
 void
 nsObjectFrame::GetDesiredSize(nsPresContext* aPresContext,
                               const nsHTMLReflowState& aReflowState,
                               nsHTMLReflowMetrics& aMetrics)
 {
   // By default, we have no area
-  aMetrics.Width() = 0;
-  aMetrics.Height() = 0;
+  aMetrics.ClearSize();
 
   if (IsHidden(false)) {
     return;
   }
-  
+
   aMetrics.Width() = aReflowState.ComputedWidth();
   aMetrics.Height() = aReflowState.ComputedHeight();
 
   // for EMBED and APPLET, default to 240x200 for compatibility
   nsIAtom *atom = mContent->Tag();
   if (atom == nsGkAtoms::applet || atom == nsGkAtoms::embed) {
     if (aMetrics.Width() == NS_UNCONSTRAINEDSIZE) {
       aMetrics.Width() = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_WIDTH),
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -93,21 +93,23 @@ nsPageContentFrame::Reflow(nsPresContext
   }
 
   // Reflow our fixed frames
   nsReflowStatus fixedStatus = NS_FRAME_COMPLETE;
   ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, fixedStatus);
   NS_ASSERTION(NS_FRAME_IS_COMPLETE(fixedStatus), "fixed frames can be truncated, but not incomplete");
 
   // Return our desired size
-  aDesiredSize.Width() = aReflowState.ComputedWidth();
-  if (aReflowState.ComputedHeight() != NS_UNCONSTRAINEDSIZE) {
-    aDesiredSize.Height() = aReflowState.ComputedHeight();
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize finalSize(wm);
+  finalSize.ISize(wm) = aReflowState.ComputedISize();
+  if (aReflowState.ComputedBSize() != NS_UNCONSTRAINEDSIZE) {
+    finalSize.BSize(wm) = aReflowState.ComputedBSize();
   }
-
+  aDesiredSize.SetSize(wm, finalSize);
   FinishAndStoreOverflow(&aDesiredSize);
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 }
 
 nsIAtom*
 nsPageContentFrame::GetType() const
 {
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -77,18 +77,17 @@ nsPageFrame::Reflow(nsPresContext*      
       maxSize.height = NSToCoordCeil(maxSize.height / scale);
     }
     // Get the number of Twips per pixel from the PresContext
     nscoord onePixelInTwips = nsPresContext::CSSPixelsToAppUnits(1);
     // insurance against infinite reflow, when reflowing less than a pixel
     // XXX Shouldn't we do something more friendly when invalid margins
     //     are set?
     if (maxSize.width < onePixelInTwips || maxSize.height < onePixelInTwips) {
-      aDesiredSize.Width() = 0;
-      aDesiredSize.Height() = 0;
+      aDesiredSize.ClearSize();
       NS_WARNING("Reflow aborted; no space for content");
       return;
     }
 
     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame,
                                      LogicalSize(frame->GetWritingMode(),
                                                  maxSize));
     kidReflowState.mFlags.mIsTopOfPage = true;
@@ -140,23 +139,27 @@ nsPageFrame::Reflow(nsPresContext*      
 
     // Place and size the child
     FinishReflowChild(frame, aPresContext, aDesiredSize, &kidReflowState, xc, yc, 0);
 
     NS_ASSERTION(!NS_FRAME_IS_FULLY_COMPLETE(aStatus) ||
                  !frame->GetNextInFlow(), "bad child flow list");
   }
   PR_PL(("PageFrame::Reflow %p ", this));
-  PR_PL(("[%d,%d][%d,%d]\n", aDesiredSize.Width(), aDesiredSize.Height(), aReflowState.AvailableWidth(), aReflowState.AvailableHeight()));
+  PR_PL(("[%d,%d][%d,%d]\n", aDesiredSize.Width(), aDesiredSize.Height(),
+         aReflowState.AvailableWidth(), aReflowState.AvailableHeight()));
 
   // Return our desired size
-  aDesiredSize.Width() = aReflowState.AvailableWidth();
-  if (aReflowState.AvailableHeight() != NS_UNCONSTRAINEDSIZE) {
-    aDesiredSize.Height() = aReflowState.AvailableHeight();
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize finalSize(wm);
+  finalSize.ISize(wm) = aReflowState.AvailableISize();
+  if (aReflowState.AvailableBSize() != NS_UNCONSTRAINEDSIZE) {
+    finalSize.BSize(wm) = aReflowState.AvailableBSize();
   }
+  aDesiredSize.SetSize(wm, finalSize);
 
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   FinishAndStoreOverflow(&aDesiredSize);
 
   PR_PL(("PageFrame::Reflow %p ", this));
   PR_PL(("[%d,%d]\n", aReflowState.AvailableWidth(), aReflowState.AvailableHeight()));
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
@@ -664,22 +667,24 @@ nsPageBreakFrame::Reflow(nsPresContext* 
                          const nsHTMLReflowState& aReflowState,
                          nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsPageBreakFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
 
   // Override reflow, since we don't want to deal with what our
   // computed values are.
-  aDesiredSize.Width() = GetIntrinsicWidth();
-  aDesiredSize.Height() = (aReflowState.AvailableHeight() == NS_UNCONSTRAINEDSIZE ?
-                         0 : aReflowState.AvailableHeight());
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize finalSize(wm, GetIntrinsicWidth(),
+                        aReflowState.AvailableBSize() == NS_UNCONSTRAINEDSIZE ?
+                          0 : aReflowState.AvailableBSize());
   // round the height down to the nearest pixel
-  aDesiredSize.Height() -=
-    aDesiredSize.Height() % nsPresContext::CSSPixelsToAppUnits(1);
+  finalSize.BSize(wm) -=
+    finalSize.BSize(wm) % nsPresContext::CSSPixelsToAppUnits(1);
+  aDesiredSize.SetSize(wm, finalSize);
 
   // Note: not using NS_FRAME_FIRST_REFLOW here, since it's not clear whether
   // DidReflow will always get called before the next Reflow() call.
   mHaveReflowed = true;
   aStatus = NS_FRAME_COMPLETE; 
 }
 
 nsIAtom*
--- a/layout/generic/nsPlaceholderFrame.cpp
+++ b/layout/generic/nsPlaceholderFrame.cpp
@@ -133,18 +133,17 @@ nsPlaceholderFrame::Reflow(nsPresContext
     } else {
       NS_ERROR("Out-of-flow frame got reflowed before its placeholder");
     }
   }
 #endif
 
   DO_GLOBAL_REFLOW_COUNT("nsPlaceholderFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
-  aDesiredSize.Width() = 0;
-  aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
 
   aStatus = NS_FRAME_COMPLETE;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 }
 
 void
 nsPlaceholderFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -2704,18 +2704,17 @@ static bool IsJustifiableCharacter(const
      ))
     return true;
   return false;
 }
 
 void
 nsTextFrame::ClearMetrics(nsHTMLReflowMetrics& aMetrics)
 {
-  aMetrics.Width() = 0;
-  aMetrics.Height() = 0;
+  aMetrics.ClearSize();
   aMetrics.SetBlockStartAscent(0);
   mAscent = 0;
 }
 
 static int32_t FindChar(const nsTextFragment* frag,
                         int32_t aOffset, int32_t aLength, char16_t ch)
 {
   int32_t i = 0;
@@ -8026,41 +8025,46 @@ nsTextFrame::ReflowText(nsLineLayout& aL
   // for good drop-cap effects
   if (GetStateBits() & TEXT_FIRST_LETTER) {
     textMetrics.mAscent = std::max(gfxFloat(0.0), -textMetrics.mBoundingBox.Y());
     textMetrics.mDescent = std::max(gfxFloat(0.0), textMetrics.mBoundingBox.YMost());
   }
 
   // Setup metrics for caller
   // Disallow negative widths
-  aMetrics.Width() = NSToCoordCeil(std::max(gfxFloat(0.0), textMetrics.mAdvanceWidth));
+  WritingMode wm = GetWritingMode();
+  LogicalSize finalSize(wm);
+  finalSize.ISize(wm) = NSToCoordCeil(std::max(gfxFloat(0.0),
+                                               textMetrics.mAdvanceWidth));
 
   if (transformedCharsFit == 0 && !usedHyphenation) {
     aMetrics.SetBlockStartAscent(0);
-    aMetrics.Height() = 0;
+    finalSize.BSize(wm) = 0;
   } else if (boundingBoxType != gfxFont::LOOSE_INK_EXTENTS) {
     // Use actual text metrics for floating first letter frame.
     aMetrics.SetBlockStartAscent(NSToCoordCeil(textMetrics.mAscent));
-    aMetrics.Height() = aMetrics.BlockStartAscent() +
+    finalSize.BSize(wm) = aMetrics.BlockStartAscent() +
       NSToCoordCeil(textMetrics.mDescent);
   } else {
     // Otherwise, ascent should contain the overline drawable area.
     // And also descent should contain the underline drawable area.
     // nsFontMetrics::GetMaxAscent/GetMaxDescent contains them.
     nsFontMetrics* fm = provider.GetFontMetrics();
     nscoord fontAscent = fm->MaxAscent();
     nscoord fontDescent = fm->MaxDescent();
     aMetrics.SetBlockStartAscent(std::max(NSToCoordCeil(textMetrics.mAscent), fontAscent));
     nscoord descent = std::max(NSToCoordCeil(textMetrics.mDescent), fontDescent);
-    aMetrics.Height() = aMetrics.BlockStartAscent() + descent;
-  }
+    finalSize.BSize(wm) = aMetrics.BlockStartAscent() + descent;
+  }
+  aMetrics.SetSize(wm, finalSize);
 
   NS_ASSERTION(aMetrics.BlockStartAscent() >= 0,
                "Negative ascent???");
-  NS_ASSERTION(aMetrics.Height() - aMetrics.BlockStartAscent() >= 0,
+  NS_ASSERTION(aMetrics.BSize(aMetrics.GetWritingMode()) -
+               aMetrics.BlockStartAscent() >= 0,
                "Negative descent???");
 
   mAscent = aMetrics.BlockStartAscent();
 
   // Handle text that runs outside its normal bounds.
   nsRect boundingBox = RoundOut(textMetrics.mBoundingBox) + nsPoint(0, mAscent);
   aMetrics.SetOverflowAreasToDesiredBounds();
   aMetrics.VisualOverflow().UnionRect(aMetrics.VisualOverflow(), boundingBox);
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -189,17 +189,18 @@ ViewportFrame::Reflow(nsPresContext*    
   // Set our size up front, since some parts of reflow depend on it
   // being already set.  Note that the computed height may be
   // unconstrained; that's ok.  Consumers should watch out for that.
   SetSize(nsSize(aReflowState.ComputedWidth(), aReflowState.ComputedHeight()));
  
   // Reflow the main content first so that the placeholders of the
   // fixed-position frames will be in the right places on an initial
   // reflow.
-  nscoord kidHeight = 0;
+  nscoord kidBSize = 0;
+  WritingMode wm = aReflowState.GetWritingMode();
 
   if (mFrames.NotEmpty()) {
     // Deal with a non-incremental reflow or an incremental reflow
     // targeted at our one-and-only principal child frame.
     if (aReflowState.ShouldReflowAllKids() ||
         aReflowState.mFlags.mVResize ||
         NS_SUBTREE_DIRTY(mFrames.FirstChild())) {
       // Reflow our one-and-only principal child frame
@@ -209,53 +210,54 @@ ViewportFrame::Reflow(nsPresContext*    
       LogicalSize         availableSpace = aReflowState.AvailableSize(wm);
       nsHTMLReflowState   kidReflowState(aPresContext, aReflowState,
                                          kidFrame, availableSpace);
 
       // Reflow the frame
       kidReflowState.SetComputedHeight(aReflowState.ComputedHeight());
       ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
                   0, 0, 0, aStatus);
-      kidHeight = kidDesiredSize.Height();
+      kidBSize = kidDesiredSize.BSize(wm);
 
       FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, nullptr, 0, 0, 0);
     } else {
-      kidHeight = mFrames.FirstChild()->GetSize().height;
+      kidBSize = LogicalSize(wm, mFrames.FirstChild()->GetSize()).BSize(wm);
     }
   }
 
   NS_ASSERTION(aReflowState.AvailableWidth() != NS_UNCONSTRAINEDSIZE,
                "shouldn't happen anymore");
 
   // Return the max size as our desired size
-  aDesiredSize.Width() = aReflowState.AvailableWidth();
-  // Being flowed initially at an unconstrained height means we should
-  // return our child's intrinsic size.
-  aDesiredSize.Height() = aReflowState.ComputedHeight() != NS_UNCONSTRAINEDSIZE
-                          ? aReflowState.ComputedHeight()
-                          : kidHeight;
+  LogicalSize maxSize(wm, aReflowState.AvailableISize(),
+                      // Being flowed initially at an unconstrained block size
+                      // means we should return our child's intrinsic size.
+                      aReflowState.ComputedBSize() != NS_UNCONSTRAINEDSIZE
+                        ? aReflowState.ComputedBSize()
+                        : kidBSize);
+  aDesiredSize.SetSize(wm, maxSize);
   aDesiredSize.SetOverflowAreasToDesiredBounds();
 
   if (mFrames.NotEmpty()) {
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, mFrames.FirstChild());
   }
 
   if (IsAbsoluteContainer()) {
     // Make a copy of the reflow state and change the computed width and height
     // to reflect the available space for the fixed items
     nsHTMLReflowState reflowState(aReflowState);
 
-    if (reflowState.AvailableHeight() == NS_UNCONSTRAINEDSIZE) {
+    if (reflowState.AvailableBSize() == NS_UNCONSTRAINEDSIZE) {
       // We have an intrinsic-height document with abs-pos/fixed-pos children.
       // Set the available height and mComputedHeight to our chosen height.
-      reflowState.AvailableHeight() = aDesiredSize.Height();
+      reflowState.AvailableBSize() = maxSize.BSize(wm);
       // Not having border/padding simplifies things
       NS_ASSERTION(reflowState.ComputedPhysicalBorderPadding() == nsMargin(0,0,0,0),
                    "Viewports can't have border/padding");
-      reflowState.SetComputedHeight(aDesiredSize.Height());
+      reflowState.SetComputedBSize(maxSize.BSize(wm));
     }
 
     nsRect rect = AdjustReflowStateAsContainingBlock(&reflowState);
 
     // Just reflow all the fixed-pos frames.
     GetAbsoluteContainingBlock()->Reflow(this, aPresContext, reflowState, aStatus,
                                          rect,
                                          false, true, true, // XXX could be optimized
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -964,32 +964,32 @@ nsMathMLContainerFrame::GetMinWidth(nsRe
   nscoord result;
   DISPLAY_MIN_WIDTH(this, result);
   nsHTMLReflowMetrics desiredSize(GetWritingMode());
   GetIntrinsicWidthMetrics(aRenderingContext, desiredSize);
 
   // Include the additional width added by FixInterFrameSpacing to ensure
   // consistent width calculations.
   AddInterFrameSpacingToSize(desiredSize, this);
-  result = desiredSize.Width();
+  result = desiredSize.ISize(GetWritingMode());
   return result;
 }
 
 /* virtual */ nscoord
 nsMathMLContainerFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
 {
   nscoord result;
   DISPLAY_PREF_WIDTH(this, result);
   nsHTMLReflowMetrics desiredSize(GetWritingMode());
   GetIntrinsicWidthMetrics(aRenderingContext, desiredSize);
 
   // Include the additional width added by FixInterFrameSpacing to ensure
   // consistent width calculations.
   AddInterFrameSpacingToSize(desiredSize, this);
-  result = desiredSize.Width();
+  result = desiredSize.ISize(GetWritingMode());
   return result;
 }
 
 /* virtual */ void
 nsMathMLContainerFrame::GetIntrinsicWidthMetrics(nsRenderingContext* aRenderingContext, nsHTMLReflowMetrics& aDesiredSize)
 {
   // Get child widths
   nsIFrame* childFrame = mFrames.FirstChild();
--- a/layout/mathml/nsMathMLSelectedFrame.cpp
+++ b/layout/mathml/nsMathMLSelectedFrame.cpp
@@ -101,17 +101,17 @@ nsMathMLSelectedFrame::BuildDisplayList(
 // Only reflow the selected child ...
 void
 nsMathMLSelectedFrame::Reflow(nsPresContext*          aPresContext,
                               nsHTMLReflowMetrics&     aDesiredSize,
                               const nsHTMLReflowState& aReflowState,
                               nsReflowStatus&          aStatus)
 {
   aStatus = NS_FRAME_COMPLETE;
-  aDesiredSize.Width() = aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
   aDesiredSize.SetBlockStartAscent(0);
   mBoundingMetrics = nsBoundingMetrics();
   nsIFrame* childFrame = GetSelectedFrame();
   if (childFrame) {
     WritingMode wm = childFrame->GetWritingMode();
     LogicalSize availSize = aReflowState.ComputedSize(wm);
     availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     nsHTMLReflowState childReflowState(aPresContext, aReflowState,
@@ -133,17 +133,17 @@ nsMathMLSelectedFrame::Place(nsRendering
                              nsHTMLReflowMetrics& aDesiredSize)
 {
   nsIFrame* childFrame = GetSelectedFrame();
 
   if (mInvalidMarkup) {
     return ReflowError(aRenderingContext, aDesiredSize);
   }
 
-  aDesiredSize.Width() = aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
   aDesiredSize.SetBlockStartAscent(0);
   mBoundingMetrics = nsBoundingMetrics();
   if (childFrame) {
     GetReflowAndBoundingMetricsFor(childFrame, aDesiredSize, mBoundingMetrics);
     if (aPlaceOrigin) {
       FinishReflowChild(childFrame, PresContext(), aDesiredSize, nullptr, 0, 0, 0);
     }
     mReference.x = 0;
--- a/layout/mathml/nsMathMLTokenFrame.cpp
+++ b/layout/mathml/nsMathMLTokenFrame.cpp
@@ -122,17 +122,17 @@ nsMathMLTokenFrame::InsertFrames(ChildLi
 
 void
 nsMathMLTokenFrame::Reflow(nsPresContext*          aPresContext,
                            nsHTMLReflowMetrics&     aDesiredSize,
                            const nsHTMLReflowState& aReflowState,
                            nsReflowStatus&          aStatus)
 {
   // initializations needed for empty markup like <mtag></mtag>
-  aDesiredSize.Width() = aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
   aDesiredSize.SetBlockStartAscent(0);
   aDesiredSize.mBoundingMetrics = nsBoundingMetrics();
 
   nsIFrame* childFrame = GetFirstPrincipalChild();
   while (childFrame) {
     // ask our children to compute their bounding metrics
     nsHTMLReflowMetrics childDesiredSize(aReflowState.GetWritingMode(),
                                          aDesiredSize.mFlags
--- a/layout/mathml/nsMathMLmfencedFrame.cpp
+++ b/layout/mathml/nsMathMLmfencedFrame.cpp
@@ -185,17 +185,17 @@ nsMathMLmfencedFrame::BuildDisplayList(n
 }
 
 void
 nsMathMLmfencedFrame::Reflow(nsPresContext*          aPresContext,
                              nsHTMLReflowMetrics&     aDesiredSize,
                              const nsHTMLReflowState& aReflowState,
                              nsReflowStatus&          aStatus)
 {
-  aDesiredSize.Width() = aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
   aDesiredSize.SetBlockStartAscent(0);
   aDesiredSize.mBoundingMetrics = nsBoundingMetrics();
 
   int32_t i;
   const nsStyleFont* font = StyleFont();
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
   aReflowState.rendContext->SetFont(fm);
--- a/layout/mathml/nsMathMLmrootFrame.cpp
+++ b/layout/mathml/nsMathMLmrootFrame.cpp
@@ -161,17 +161,17 @@ nsMathMLmrootFrame::GetRadicalXOffsets(n
 void
 nsMathMLmrootFrame::Reflow(nsPresContext*          aPresContext,
                            nsHTMLReflowMetrics&     aDesiredSize,
                            const nsHTMLReflowState& aReflowState,
                            nsReflowStatus&          aStatus)
 {
   nsReflowStatus childStatus;
 
-  aDesiredSize.Width() = aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
   aDesiredSize.SetBlockStartAscent(0);
 
   nsBoundingMetrics bmSqr, bmBase, bmIndex;
   nsRenderingContext& renderingContext = *aReflowState.rendContext;
 
   //////////////////
   // Reflow Children
 
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -5203,32 +5203,33 @@ SVGTextFrame::DoReflow()
     // an updated preferred width.
     kid->MarkIntrinsicWidthsDirty();
   }
 
   mState |= NS_STATE_SVG_TEXT_IN_REFLOW;
 
   //XXX GetPrefWidth will become GetInlineSize
   nscoord inlineSize = kid->GetPrefWidth(renderingContext);
+  WritingMode wm = kid->GetWritingMode();
   nsHTMLReflowState reflowState(presContext, kid,
                                 renderingContext,
-                                LogicalSize(kid->GetWritingMode(),
-                                            inlineSize, NS_UNCONSTRAINEDSIZE));
+                                LogicalSize(wm, inlineSize,
+                                            NS_UNCONSTRAINEDSIZE));
   nsHTMLReflowMetrics desiredSize(reflowState);
   nsReflowStatus status;
 
   NS_ASSERTION(reflowState.ComputedPhysicalBorderPadding() == nsMargin(0, 0, 0, 0) &&
                reflowState.ComputedPhysicalMargin() == nsMargin(0, 0, 0, 0),
                "style system should ensure that :-moz-svg-text "
                "does not get styled");
 
   kid->WillReflow(presContext);
   kid->Reflow(presContext, desiredSize, reflowState, status);
   kid->DidReflow(presContext, &reflowState, nsDidReflowStatus::FINISHED);
-  kid->SetSize(nsSize(desiredSize.Width(), desiredSize.Height()));
+  kid->SetSize(wm, desiredSize.Size(wm));
 
   mState &= ~NS_STATE_SVG_TEXT_IN_REFLOW;
 
   TextNodeCorrespondenceRecorder::RecordCorrespondence(this);
 }
 
 // Usable font size range in devpixels / user-units
 #define CLAMP_MIN_SIZE 8.0
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -139,18 +139,20 @@ nsSVGForeignObjectFrame::Reflow(nsPresCo
                "should only get reflow from being reflow root");
   NS_ASSERTION(aReflowState.ComputedWidth() == GetSize().width &&
                aReflowState.ComputedHeight() == GetSize().height,
                "reflow roots should be reflowed at existing size and "
                "svg.css should ensure we have no padding/border/margin");
 
   DoReflow();
 
-  aDesiredSize.Width() = aReflowState.ComputedWidth();
-  aDesiredSize.Height() = aReflowState.ComputedHeight();
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize finalSize(wm, aReflowState.ComputedISize(),
+                        aReflowState.ComputedBSize());
+  aDesiredSize.SetSize(wm, finalSize);
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   aStatus = NS_FRAME_COMPLETE;
 }
 
 void
 nsSVGForeignObjectFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                           const nsRect&           aDirtyRect,
                                           const nsDisplayListSet& aLists)
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -33,16 +33,17 @@
 #include "nsFrameSelection.h"
 #include "mozilla/LookAndFeel.h"
 
 using namespace mozilla;
 
 
 nsTableCellFrame::nsTableCellFrame(nsStyleContext* aContext) :
   nsContainerFrame(aContext)
+  , mDesiredSize(GetWritingMode())
 {
   mColIndex = 0;
   mPriorAvailWidth = 0;
 
   SetContentEmpty(false);
   SetHasPctOverHeight(false);
 }
 
@@ -616,19 +617,19 @@ void nsTableCellFrame::VerticallyAlignCh
   kidYTop = std::max(0, kidYTop);
 
   if (kidYTop != kidRect.y) {
     // Invalidate at the old position first
     firstKid->InvalidateFrameSubtree();
   }
 
   firstKid->SetPosition(nsPoint(kidRect.x, kidYTop));
-  nsHTMLReflowMetrics desiredSize(GetWritingMode()); // ???
-  desiredSize.Width() = mRect.width;
-  desiredSize.Height() = mRect.height;
+  WritingMode wm = GetWritingMode();
+  nsHTMLReflowMetrics desiredSize(wm);
+  desiredSize.SetSize(wm, GetLogicalSize(wm));
 
   nsRect overflow(nsPoint(0,0), GetSize());
   overflow.Inflate(GetBorderOverflow());
   desiredSize.mOverflowAreas.SetAllTo(overflow);
   ConsiderChildOverflow(desiredSize.mOverflowAreas, firstKid);
   FinishAndStoreOverflow(&desiredSize);
   if (kidYTop != kidRect.y) {
     // Make sure any child views are correctly positioned. We know the inner table
@@ -795,19 +796,20 @@ nsTableCellFrame::IntrinsicWidthOffsets(
 
 #ifdef DEBUG
 #define PROBABLY_TOO_LARGE 1000000
 static
 void DebugCheckChildSize(nsIFrame*            aChild,
                          nsHTMLReflowMetrics& aMet,
                          nsSize&              aAvailSize)
 {
-  if ((aMet.Width() < 0) || (aMet.Width() > PROBABLY_TOO_LARGE)) {
-    printf("WARNING: cell content %p has large width %d \n",
-           static_cast<void*>(aChild), int32_t(aMet.Width()));
+  WritingMode wm = aMet.GetWritingMode();
+  if ((aMet.ISize(wm) < 0) || (aMet.ISize(wm) > PROBABLY_TOO_LARGE)) {
+    printf("WARNING: cell content %p has large inline size %d \n",
+           static_cast<void*>(aChild), int32_t(aMet.ISize(wm)));
   }
 }
 #endif
 
 // the computed height for the cell, which descendants use for percent height calculations
 // it is the height (minus border, padding) of the cell's first in flow during its final
 // reflow without an unconstrained height.
 static nscoord
@@ -878,18 +880,19 @@ nsTableCellFrame::Reflow(nsPresContext* 
   if (NS_UNCONSTRAINEDSIZE != availSize.height)
     availSize.height -= topInset + bottomInset;
 
   // Try to reflow the child into the available space. It might not
   // fit or might need continuing.
   if (availSize.height < 0)
     availSize.height = 1;
 
-  nsHTMLReflowMetrics kidSize(aReflowState.GetWritingMode(), aDesiredSize.mFlags);
-  kidSize.Width() = kidSize.Height() = 0;
+  WritingMode wm = aReflowState.GetWritingMode();
+  nsHTMLReflowMetrics kidSize(wm, aDesiredSize.mFlags);
+  kidSize.ClearSize();
   SetPriorAvailWidth(aReflowState.AvailableWidth());
   nsIFrame* firstKid = mFrames.FirstChild();
   NS_ASSERTION(firstKid, "Frame construction error, a table cell always has an inner cell frame");
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
 
   if (aReflowState.mFlags.mSpecialHeightReflow) {
     const_cast<nsHTMLReflowState&>(aReflowState).SetComputedHeight(mRect.height - topInset - bottomInset);
     DISPLAY_REFLOW_CHANGE();
@@ -968,33 +971,35 @@ nsTableCellFrame::Reflow(nsPresContext* 
   // Place the child
   FinishReflowChild(firstKid, aPresContext, kidSize, &kidReflowState,
                     kidOrigin.x, kidOrigin.y, 0);
 
   nsTableFrame::InvalidateTableFrame(firstKid, origRect, origVisualOverflow,
                                      firstReflow);
 
   // first, compute the height which can be set w/o being restricted by aMaxSize.height
-  nscoord cellHeight = kidSize.Height();
+  LogicalSize cellSize(wm);
+  LogicalMargin logicalInsets(wm, nsMargin(topInset, rightInset,
+                                           bottomInset, leftInset));
+  cellSize.BSize(wm) = kidSize.BSize(wm);
 
-  if (NS_UNCONSTRAINEDSIZE != cellHeight) {
-    cellHeight += topInset + bottomInset;
+  if (NS_UNCONSTRAINEDSIZE != cellSize.BSize(wm)) {
+    cellSize.BSize(wm) += logicalInsets.BStartEnd(wm);
   }
 
   // next determine the cell's width
-  nscoord cellWidth = kidSize.Width();      // at this point, we've factored in the cell's style attributes
+  cellSize.ISize(wm) = kidSize.ISize(wm);      // at this point, we've factored in the cell's style attributes
 
   // factor in border and padding
-  if (NS_UNCONSTRAINEDSIZE != cellWidth) {
-    cellWidth += leftInset + rightInset;
+  if (NS_UNCONSTRAINEDSIZE != cellSize.ISize(wm)) {
+    cellSize.ISize(wm) += logicalInsets.IStartEnd(wm);
   }
 
   // set the cell's desired size and max element size
-  aDesiredSize.Width() = cellWidth;
-  aDesiredSize.Height() = cellHeight;
+  aDesiredSize.SetSize(wm, cellSize);
 
   // the overflow area will be computed when the child will be vertically aligned
 
   if (aReflowState.mFlags.mSpecialHeightReflow) {
     if (aDesiredSize.Height() > mRect.height) {
       // set a bit indicating that the pct height contents exceeded
       // the height that they could honor in the pass 2 reflow
       SetHasPctOverHeight(true);
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -182,17 +182,17 @@ public:
 
   /** return the available width given to this frame during its last reflow */
   inline nscoord GetPriorAvailWidth();
 
   /** set the available width given to this frame during its last reflow */
   inline void SetPriorAvailWidth(nscoord aPriorAvailWidth);
 
   /** return the desired size returned by this frame during its last reflow */
-  inline nsSize GetDesiredSize();
+  inline mozilla::LogicalSize GetDesiredSize();
 
   /** set the desired size returned by this frame during its last reflow */
   inline void SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize);
 
   bool GetContentEmpty();
   void SetContentEmpty(bool aContentEmpty);
 
   bool HasPctOverHeight();
@@ -233,32 +233,32 @@ protected:
    */
   virtual nsMargin GetBorderOverflow();
 
   friend class nsTableRowFrame;
 
   uint32_t     mColIndex;             // the starting column for this cell
 
   nscoord      mPriorAvailWidth;      // the avail width during the last reflow
-  nsSize       mDesiredSize;          // the last desired width & height
+  mozilla::LogicalSize mDesiredSize;  // the last desired inline and block size
 };
 
 inline nscoord nsTableCellFrame::GetPriorAvailWidth()
 { return mPriorAvailWidth;}
 
 inline void nsTableCellFrame::SetPriorAvailWidth(nscoord aPriorAvailWidth)
 { mPriorAvailWidth = aPriorAvailWidth;}
 
-inline nsSize nsTableCellFrame::GetDesiredSize()
+inline mozilla::LogicalSize nsTableCellFrame::GetDesiredSize()
 { return mDesiredSize; }
 
 inline void nsTableCellFrame::SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize)
 {
-  mDesiredSize.width = aDesiredSize.Width();
-  mDesiredSize.height = aDesiredSize.Height();
+  mozilla::WritingMode wm = aDesiredSize.GetWritingMode();
+  mDesiredSize = aDesiredSize.Size(wm).ConvertTo(GetWritingMode(), wm);
 }
 
 inline bool nsTableCellFrame::GetContentEmpty()
 {
   return (mState & NS_TABLE_CELL_CONTENT_EMPTY) ==
          NS_TABLE_CELL_CONTENT_EMPTY;
 }
 
--- a/layout/tables/nsTableColFrame.cpp
+++ b/layout/tables/nsTableColFrame.cpp
@@ -88,18 +88,17 @@ void nsTableColFrame::SetContinuousBCBor
 void
 nsTableColFrame::Reflow(nsPresContext*          aPresContext,
                                   nsHTMLReflowMetrics&     aDesiredSize,
                                   const nsHTMLReflowState& aReflowState,
                                   nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsTableColFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
-  aDesiredSize.Width() = 0;
-  aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
   const nsStyleVisibility* colVis = StyleVisibility();
   bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
   if (collapseCol) {
     nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
     tableFrame->SetNeedToCollapse(true);
   }
   aStatus = NS_FRAME_COMPLETE;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -374,18 +374,17 @@ nsTableColGroupFrame::Reflow(nsPresConte
     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
                                      LogicalSize(kidFrame->GetWritingMode()));
 
     nsReflowStatus status;
     ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, status);
     FinishReflowChild(kidFrame, aPresContext, kidSize, nullptr, 0, 0, 0);
   }
 
-  aDesiredSize.Width() = 0;
-  aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
   aStatus = NS_FRAME_COMPLETE;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 }
 
 nsTableColFrame * nsTableColGroupFrame::GetFirstColumn()
 {
   return GetNextColumn(nullptr);
 }
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -2801,17 +2801,17 @@ nsTableFrame::SetupHeaderFooterChild(con
   LogicalSize availSize = aReflowState.reflowState.AvailableSize(wm);
   availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
   nsHTMLReflowState kidReflowState(presContext, aReflowState.reflowState,
                                    aFrame, availSize,
                                    -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
   InitChildReflowState(kidReflowState);
   kidReflowState.mFlags.mIsTopOfPage = true;
   nsHTMLReflowMetrics desiredSize(aReflowState.reflowState);
-  desiredSize.Width() = desiredSize.Height() = 0;
+  desiredSize.ClearSize();
   nsReflowStatus status;
   ReflowChild(aFrame, presContext, desiredSize, kidReflowState,
               aReflowState.x, aReflowState.y, 0, status);
   // The child will be reflowed again "for real" so no need to place it now
 
   aFrame->SetRepeatable(IsRepeatable(desiredSize.Height(), pageHeight));
   *aDesiredHeight = desiredSize.Height();
   return NS_OK;
@@ -2834,17 +2834,17 @@ nsTableFrame::PlaceRepeatedFooter(nsTabl
   InitChildReflowState(footerReflowState);
   aReflowState.y += GetCellSpacingY(GetRowCount());
 
   nsRect origTfootRect = aTfoot->GetRect();
   nsRect origTfootVisualOverflow = aTfoot->GetVisualOverflowRect();
           
   nsReflowStatus footerStatus;
   nsHTMLReflowMetrics desiredSize(aReflowState.reflowState);
-  desiredSize.Width() = desiredSize.Height() = 0;
+  desiredSize.ClearSize();
   ReflowChild(aTfoot, presContext, desiredSize, footerReflowState,
               aReflowState.x, aReflowState.y, 0, footerStatus);
   PlaceChild(aReflowState, aTfoot, desiredSize, origTfootRect,
              origTfootVisualOverflow);
 }
                     
 // Reflow the children based on the avail size and reason in aReflowState
 // update aReflowMetrics a aStatus
@@ -2941,17 +2941,17 @@ nsTableFrame::ReflowChildren(nsTableRefl
           }
         }
       }
 
       nsRect oldKidRect = kidFrame->GetRect();
       nsRect oldKidVisualOverflow = kidFrame->GetVisualOverflowRect();
 
       nsHTMLReflowMetrics desiredSize(aReflowState.reflowState);
-      desiredSize.Width() = desiredSize.Height() = 0;
+      desiredSize.ClearSize();
 
       // Reflow the child into the available space
       nsHTMLReflowState kidReflowState(presContext, aReflowState.reflowState,
                                        kidFrame,
                                        LogicalSize(kidFrame->GetWritingMode(),
                                                    kidAvailSize),
                                        -1, -1,
                                        nsHTMLReflowState::CALLER_WILL_INIT);
@@ -3215,29 +3215,26 @@ nsTableFrame::CalcDesiredHeight(const ns
   aDesiredSize.Height() = desiredHeight;
 }
 
 static
 void ResizeCells(nsTableFrame& aTableFrame)
 {
   nsTableFrame::RowGroupArray rowGroups;
   aTableFrame.OrderRowGroups(rowGroups);
-  nsHTMLReflowMetrics tableDesiredSize(aTableFrame.GetWritingMode()); // ???
-  nsRect tableRect = aTableFrame.GetRect();
-  tableDesiredSize.Width() = tableRect.width;
-  tableDesiredSize.Height() = tableRect.height;
+  WritingMode wm = aTableFrame.GetWritingMode();
+  nsHTMLReflowMetrics tableDesiredSize(wm);
+  tableDesiredSize.SetSize(wm, aTableFrame.GetLogicalSize(wm));
   tableDesiredSize.SetOverflowAreasToDesiredBounds();
 
   for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
 
-    nsRect rowGroupRect = rgFrame->GetRect();
-    nsHTMLReflowMetrics groupDesiredSize(tableDesiredSize.GetWritingMode());
-    groupDesiredSize.Width() = rowGroupRect.width;
-    groupDesiredSize.Height() = rowGroupRect.height;
+    nsHTMLReflowMetrics groupDesiredSize(wm);
+    groupDesiredSize.SetSize(wm, rgFrame->GetLogicalSize(wm));
     groupDesiredSize.SetOverflowAreasToDesiredBounds();
 
     nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
     while (rowFrame) {
       rowFrame->DidResize();
       rgFrame->ConsiderChildOverflow(groupDesiredSize.mOverflowAreas, rowFrame);
       rowFrame = rowFrame->GetNextRow();
     }
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -875,17 +875,17 @@ nsTableOuterFrame::Reflow(nsPresContext*
                                     nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsTableOuterFrame");
   DISPLAY_REFLOW(aPresContext, this, aOuterRS, aDesiredSize, aStatus);
 
   uint8_t captionSide = GetCaptionSide();
 
   // Initialize out parameters
-  aDesiredSize.Width() = aDesiredSize.Height() = 0;
+  aDesiredSize.ClearSize();
   aStatus = NS_FRAME_COMPLETE;
 
   if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     // Set up our kids.  They're already present, on an overflow list, 
     // or there are none so we'll create them now
     MoveOverflowToChildList();
   }
 
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -309,20 +309,20 @@ nsTableRowFrame::GetFirstCell()
  */
 void
 nsTableRowFrame::DidResize()
 {
   // Resize and re-align the cell frames based on our row height
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
   nsTableIterator iter(*this);
   nsIFrame* childFrame = iter.First();
-  
-  nsHTMLReflowMetrics desiredSize(GetWritingMode()); // ???
-  desiredSize.Width() = mRect.width;
-  desiredSize.Height() = mRect.height;
+
+  WritingMode wm = GetWritingMode();
+  nsHTMLReflowMetrics desiredSize(wm);
+  SetSize(wm, GetLogicalSize(wm));
   desiredSize.SetOverflowAreasToDesiredBounds();
 
   while (childFrame) {
     nsTableCellFrame *cellFrame = do_QueryFrame(childFrame);
     if (cellFrame) {
       nscoord cellHeight = mRect.height + GetHeightOfRowsSpannedBelowFirst(*cellFrame, *tableFrame);
 
       // resize the cell's height
@@ -490,28 +490,29 @@ nsTableRowFrame::CalcHeight(const nsHTML
     SetPctHeight(position->mHeight.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) {
-      nsSize desSize = cellFrame->GetDesiredSize();
+      WritingMode wm = cellFrame->GetWritingMode();
+      LogicalSize desSize = cellFrame->GetDesiredSize();
       if ((NS_UNCONSTRAINEDSIZE == aReflowState.AvailableHeight()) && !GetPrevInFlow()) {
-        CalculateCellActualHeight(cellFrame, desSize.height);
+        CalculateCellActualHeight(cellFrame, desSize.BSize(wm));
       }
       // height may have changed, adjust descent to absorb any excess difference
       nscoord ascent;
        if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild())
-         ascent = desSize.height;
+         ascent = desSize.BSize(wm);
        else
          ascent = cellFrame->GetCellBaseline();
-      nscoord descent = desSize.height - ascent;
-      UpdateHeight(desSize.height, ascent, descent, tableFrame, cellFrame);
+       nscoord descent = desSize.BSize(wm) - ascent;
+       UpdateHeight(desSize.BSize(wm), ascent, descent, tableFrame, cellFrame);
     }
   }
   return GetHeight();
 }
 
 /**
  * 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').
@@ -871,19 +872,21 @@ nsTableRowFrame::ReflowChildren(nsPresCo
 
       nsHTMLReflowMetrics desiredSize(aReflowState);
 
       // If the avail width 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.
       // XXXldb Why is this condition distinct from doReflowChild above?
-      nsSize cellDesiredSize = cellFrame->GetDesiredSize();
+      WritingMode rowWM = aReflowState.GetWritingMode();
+      WritingMode cellWM = cellFrame->GetWritingMode();
+      LogicalSize cellDesiredSize = cellFrame->GetDesiredSize();
       if ((availCellWidth != cellFrame->GetPriorAvailWidth())       ||
-          (cellDesiredSize.width > cellFrame->GetPriorAvailWidth()) ||
+          (cellDesiredSize.ISize(cellWM) > cellFrame->GetPriorAvailWidth()) ||
           (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_HEIGHT) ||
           HasPctHeight()) {
         // Reflow the cell to fit the available width, height
         // XXX The old IR_ChildIsDirty code used availCellWidth here.
@@ -908,18 +911,17 @@ nsTableRowFrame::ReflowChildren(nsPresCo
           aStatus = NS_FRAME_NOT_COMPLETE;
         }
       }
       else {
         if (x != kidRect.x) {
           kidFrame->InvalidateFrameSubtree();
         }
         
-        desiredSize.Width() = cellDesiredSize.width;
-        desiredSize.Height() = cellDesiredSize.height;
+        desiredSize.SetSize(cellWM, 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...
@@ -930,33 +932,35 @@ nsTableRowFrame::ReflowChildren(nsPresCo
       if (NS_UNCONSTRAINEDSIZE == aReflowState.AvailableHeight()) {
         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());
         }
         // height may have changed, adjust descent to absorb any excess difference
         nscoord ascent;
-        if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild())
-          ascent = desiredSize.Height();
-        else
+        if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild()) {
+          ascent = desiredSize.BSize(rowWM);
+        } else {
           ascent = ((nsTableCellFrame *)kidFrame)->GetCellBaseline();
-        nscoord descent = desiredSize.Height() - ascent;
+        }
+        nscoord descent = desiredSize.BSize(rowWM) - ascent;
+        UpdateHeight(desiredSize.BSize(rowWM), ascent, descent, &aTableFrame, cellFrame);
         UpdateHeight(desiredSize.Height(), ascent, descent, &aTableFrame, cellFrame);
       }
       else {
         cellMaxHeight = std::max(cellMaxHeight, desiredSize.Height());
         int32_t rowSpan = aTableFrame.GetEffectiveRowSpan((nsTableCellFrame&)*kidFrame);
         if (1 == rowSpan) {
           SetContentHeight(cellMaxHeight);
         }
       }
 
       // Place the child
-      desiredSize.Width() = availCellWidth;
+      desiredSize.ISize(rowWM) = availCellWidth;
 
       FinishReflowChild(kidFrame, aPresContext, desiredSize, nullptr, x, 0, 0);
 
       nsTableFrame::InvalidateTableFrame(kidFrame, kidRect, kidVisualOverflow,
                                          firstReflow);
       
       x += desiredSize.Width();  
     }
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -372,18 +372,18 @@ nsTableRowGroupFrame::ReflowChildren(nsP
                           NS_FRAME_CONTAINS_RELATIVE_HEIGHT)))) {
       nsRect oldKidRect = kidFrame->GetRect();
       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.Width() = desiredSize.Height() = 0;
-  
+      desiredSize.ClearSize();
+
       // Reflow the child into the available space, giving it as much height 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);
       kidAvailSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
       nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
                                        kidFrame, kidAvailSize,
@@ -640,17 +640,18 @@ nsTableRowGroupFrame::CalculateRowHeight
               }
               if (rowInfo[rowIndex + spanX].isSpecial) {
                 numSpecialRowsSpanned++;
               }
             } 
             nscoord heightOfAreaSpanned = heightOfRowsSpanned + cellSpacingTotal;
             // get the height of the cell 
             nsSize cellFrameSize = cellFrame->GetSize();
-            nsSize cellDesSize = cellFrame->GetDesiredSize();
+            nsSize cellDesSize =
+              cellFrame->GetDesiredSize().GetPhysicalSize(cellFrame->GetWritingMode());
             rowFrame->CalculateCellActualHeight(cellFrame, cellDesSize.height);
             cellFrameSize.height = cellDesSize.height;
             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();
--- a/layout/xul/nsBoxFrame.cpp
+++ b/layout/xul/nsBoxFrame.cpp
@@ -648,72 +648,75 @@ nsBoxFrame::Reflow(nsPresContext*       
 #endif
 
   aStatus = NS_FRAME_COMPLETE;
 
   // create the layout state
   nsBoxLayoutState state(aPresContext, aReflowState.rendContext,
                          &aReflowState, aReflowState.mReflowDepth);
 
-  nsSize computedSize(aReflowState.ComputedWidth(),aReflowState.ComputedHeight());
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize computedSize(wm, aReflowState.ComputedISize(),
+                           aReflowState.ComputedBSize());
 
-  nsMargin m;
-  m = aReflowState.ComputedPhysicalBorderPadding();
+  LogicalMargin m = aReflowState.ComputedLogicalBorderPadding();
   // GetBorderAndPadding(m);
 
-  nsSize prefSize(0,0);
+  LogicalSize prefSize(wm);
 
   // if we are told to layout intrinsic then get our preferred size.
-  NS_ASSERTION(computedSize.width != NS_INTRINSICSIZE,
-               "computed width should always be computed");
-  if (computedSize.height == NS_INTRINSICSIZE) {
-    prefSize = GetPrefSize(state);
+  NS_ASSERTION(computedSize.ISize(wm) != NS_INTRINSICSIZE,
+               "computed inline size should always be computed");
+  if (computedSize.BSize(wm) == NS_INTRINSICSIZE) {
+    nsSize physicalPrefSize = GetPrefSize(state);
     nsSize minSize = GetMinSize(state);
     nsSize maxSize = GetMaxSize(state);
     // XXXbz isn't GetPrefSize supposed to bounds-check for us?
-    prefSize = BoundsCheck(minSize, prefSize, maxSize);
+    physicalPrefSize = BoundsCheck(minSize, physicalPrefSize, maxSize);
+    prefSize = LogicalSize(wm, physicalPrefSize);
   }
 
   // get our desiredSize
-  computedSize.width += m.left + m.right;
+  computedSize.ISize(wm) += m.IStart(wm) + m.IEnd(wm);
 
-  if (aReflowState.ComputedHeight() == NS_INTRINSICSIZE) {
-    computedSize.height = prefSize.height;
+  if (aReflowState.ComputedBSize() == NS_INTRINSICSIZE) {
+    computedSize.BSize(wm) = prefSize.BSize(wm);
     // prefSize is border-box but min/max constraints are content-box.
-    nscoord verticalBorderPadding =
-      aReflowState.ComputedPhysicalBorderPadding().TopBottom();
-    nscoord contentHeight = computedSize.height - verticalBorderPadding;
+    nscoord blockDirBorderPadding =
+      aReflowState.ComputedLogicalBorderPadding().BStartEnd(wm);
+    nscoord contentBSize = computedSize.BSize(wm) - blockDirBorderPadding;
     // Note: contentHeight might be negative, but that's OK because min-height
     // is never negative.
-    computedSize.height = aReflowState.ApplyMinMaxHeight(contentHeight) +
-                          verticalBorderPadding;
+    computedSize.BSize(wm) = aReflowState.ApplyMinMaxHeight(contentBSize) +
+                             blockDirBorderPadding;
   } else {
-    computedSize.height += m.top + m.bottom;
+    computedSize.BSize(wm) += m.BStart(wm) + m.BEnd(wm);
   }
 
-  nsRect r(mRect.x, mRect.y, computedSize.width, computedSize.height);
+  nsSize physicalSize = computedSize.GetPhysicalSize(wm);
+  nsRect r(mRect.x, mRect.y, physicalSize.width, physicalSize.height);
 
   SetBounds(state, r);
  
   // layout our children
   Layout(state);
   
   // ok our child could have gotten bigger. So lets get its bounds
   
   // get the ascent
-  nscoord ascent = mRect.height;
+  LogicalSize boxSize = GetLogicalSize(wm);
+  nscoord ascent = boxSize.BSize(wm);
 
   // getting the ascent could be a lot of work. Don't get it if
   // we are the root. The viewport doesn't care about it.
   if (!(mState & NS_STATE_IS_ROOT)) {
     ascent = GetBoxAscent(state);
   }
 
-  aDesiredSize.Width() = mRect.width;
-  aDesiredSize.Height() = mRect.height;
+  aDesiredSize.SetSize(wm, boxSize);
   aDesiredSize.SetBlockStartAscent(ascent);
 
   aDesiredSize.mOverflowAreas = GetOverflowAreas();
 
 #ifdef DO_NOISY_REFLOW
   {
     printf("%p ** nsBF(done) W:%d H:%d  ", this, aDesiredSize.Width(), aDesiredSize.Height());