Bug 789096 patch 9: use logical coordinates in nsHTMLReflowState available size. r=jfkthame
authorSimon Montagu <smontagu@smontagu.org>
Thu, 24 Jul 2014 01:28:46 -0700
changeset 217620 a4ba6995c87e7cf67a7d513ac7e23dcdab76b408
parent 217464 810551a5ee644c4bce6a775b925793fae16c21af
child 217621 634d33dc9d3ed1fbd09098b7d76d9a754cc80f69
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [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 9: use logical coordinates in nsHTMLReflowState available size. r=jfkthame
layout/base/RestyleManager.cpp
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsHTMLButtonControlFrame.cpp
layout/forms/nsMeterFrame.cpp
layout/forms/nsNumberControlFrame.cpp
layout/forms/nsProgressFrame.cpp
layout/forms/nsRangeFrame.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/nsAbsoluteContainingBlock.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockReflowContext.cpp
layout/generic/nsBlockReflowState.h
layout/generic/nsCanvasFrame.cpp
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsContainerFrame.cpp
layout/generic/nsFirstLetterFrame.cpp
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFontInflationData.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsHTMLCanvasFrame.cpp
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsHTMLReflowState.h
layout/generic/nsLineLayout.cpp
layout/generic/nsPageContentFrame.cpp
layout/generic/nsPageFrame.cpp
layout/generic/nsSimplePageSequenceFrame.cpp
layout/generic/nsVideoFrame.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/nsTableColGroupFrame.cpp
layout/tables/nsTableFrame.cpp
layout/tables/nsTableOuterFrame.cpp
layout/tables/nsTableOuterFrame.h
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowGroupFrame.cpp
layout/xul/nsBoxFrame.cpp
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -403,46 +403,49 @@ RestyleManager::RecomputePosition(nsIFra
   // doesn't need to change, we can simply update the frame position. Otherwise
   // we fall back to a reflow.
   nsRefPtr<nsRenderingContext> rc =
     aFrame->PresContext()->PresShell()->CreateReferenceRenderingContext();
 
   // Construct a bogus parent reflow state so that there's a usable
   // containing block reflow state.
   nsIFrame* parentFrame = aFrame->GetParent();
-  nsSize parentSize = parentFrame->GetSize();
+  WritingMode parentWM = parentFrame->GetWritingMode();
+  WritingMode frameWM = aFrame->GetWritingMode();
+  LogicalSize parentSize = parentFrame->GetLogicalSize();
 
   nsFrameState savedState = parentFrame->GetStateBits();
   nsHTMLReflowState parentReflowState(aFrame->PresContext(), parentFrame,
                                       rc, parentSize);
   parentFrame->RemoveStateBits(~nsFrameState(0));
   parentFrame->AddStateBits(savedState);
 
-  NS_WARN_IF_FALSE(parentSize.width != NS_INTRINSICSIZE &&
-                   parentSize.height != NS_INTRINSICSIZE,
+  NS_WARN_IF_FALSE(parentSize.ISize(parentWM) != NS_INTRINSICSIZE &&
+                   parentSize.BSize(parentWM) != NS_INTRINSICSIZE,
                    "parentSize should be valid");
-  parentReflowState.SetComputedWidth(std::max(parentSize.width, 0));
-  parentReflowState.SetComputedHeight(std::max(parentSize.height, 0));
+  parentReflowState.SetComputedISize(std::max(parentSize.ISize(parentWM), 0));
+  parentReflowState.SetComputedBSize(std::max(parentSize.BSize(parentWM), 0));
   parentReflowState.ComputedPhysicalMargin().SizeTo(0, 0, 0, 0);
 
   parentReflowState.ComputedPhysicalPadding() = parentFrame->GetUsedPadding();
   parentReflowState.ComputedPhysicalBorderPadding() =
     parentFrame->GetUsedBorderAndPadding();
-  nsSize availSize(parentSize.width, NS_INTRINSICSIZE);
+  LogicalSize availSize = parentSize.ConvertTo(frameWM, parentWM);
+  availSize.BSize(frameWM) = NS_INTRINSICSIZE;
 
   ViewportFrame* viewport = do_QueryFrame(parentFrame);
   nsSize cbSize = viewport ?
     viewport->AdjustReflowStateAsContainingBlock(&parentReflowState).Size()
     : aFrame->GetContainingBlock()->GetSize();
   const nsMargin& parentBorder =
     parentReflowState.mStyleBorder->GetComputedBorder();
   cbSize -= nsSize(parentBorder.LeftRight(), parentBorder.TopBottom());
   nsHTMLReflowState reflowState(aFrame->PresContext(), parentReflowState,
-                                aFrame, availSize, cbSize.width,
-                                cbSize.height);
+                                aFrame, availSize,
+                                cbSize.width, cbSize.height);
   nsSize computedSize(reflowState.ComputedWidth(), reflowState.ComputedHeight());
   computedSize.width += reflowState.ComputedPhysicalBorderPadding().LeftRight();
   if (computedSize.height != NS_INTRINSICSIZE) {
     computedSize.height += reflowState.ComputedPhysicalBorderPadding().TopBottom();
   }
   nsSize size = aFrame->GetSize();
   // The RecomputePosition hint is not used if any offset changed between auto
   // and non-auto. If computedSize.height == NS_INTRINSICSIZE then the new
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -8767,87 +8767,90 @@ PresShell::DoReflow(nsIFrame* target, bo
   mCurrentReflowRoot = target;
 #endif
 
   target->WillReflow(mPresContext);
 
   // If the target frame is the root of the frame hierarchy, then
   // use all the available space. If it's simply a `reflow root',
   // then use the target frame's size as the available space.
-  nsSize size;
+  WritingMode wm = target->GetWritingMode();
+  LogicalSize size(wm);
   if (target == rootFrame) {
-     size = mPresContext->GetVisibleArea().Size();
+    size = LogicalSize(wm, mPresContext->GetVisibleArea().Size());
   } else {
-     size = target->GetSize();
+    size = target->GetLogicalSize();
   }
 
   NS_ASSERTION(!target->GetNextInFlow() && !target->GetPrevInFlow(),
                "reflow roots should never split");
 
   // Don't pass size directly to the reflow state, since a
   // constrained height implies page/column breaking.
-  nsSize reflowSize(size.width, NS_UNCONSTRAINEDSIZE);
+  LogicalSize reflowSize(wm, size.ISize(wm), NS_UNCONSTRAINEDSIZE);
   nsHTMLReflowState reflowState(mPresContext, target, rcx, reflowSize,
                                 nsHTMLReflowState::CALLER_WILL_INIT);
 
   if (rootFrame == target) {
     reflowState.Init(mPresContext);
 
-    // When the root frame is being reflowed with unconstrained height
+    // When the root frame is being reflowed with unconstrained block-size
     // (which happens when we're called from
     // nsDocumentViewer::SizeToContent), we're effectively doing a
-    // vertical resize, since it changes the meaning of percentage
-    // heights even if no heights actually changed.  The same applies
-    // when we reflow again after that computation.  This is an unusual
-    // case, and isn't caught by nsHTMLReflowState::InitResizeFlags.
-    bool hasUnconstrainedHeight = size.height == NS_UNCONSTRAINEDSIZE;
-
-    if (hasUnconstrainedHeight || mLastRootReflowHadUnconstrainedHeight) {
+    // resize in the block direction, since it changes the meaning of
+    // percentage block-sizes even if no block-sizes actually changed.
+    // The same applies when we reflow again after that computation. This is
+    // an unusual case, and isn't caught by nsHTMLReflowState::InitResizeFlags.
+    bool hasUnconstrainedBSize = size.BSize(wm) == NS_UNCONSTRAINEDSIZE;
+
+    if (hasUnconstrainedBSize || mLastRootReflowHadUnconstrainedBSize) {
       reflowState.mFlags.mVResize = true;
     }
 
-    mLastRootReflowHadUnconstrainedHeight = hasUnconstrainedHeight;
+    mLastRootReflowHadUnconstrainedBSize = hasUnconstrainedBSize;
   } else {
     // Initialize reflow state with current used border and padding,
     // in case this was set specially by the parent frame when the reflow root
     // was reflowed by its parent.
     nsMargin currentBorder = target->GetUsedBorder();
     nsMargin currentPadding = target->GetUsedPadding();
     reflowState.Init(mPresContext, -1, -1, &currentBorder, &currentPadding);
   }
 
   // fix the computed height
   NS_ASSERTION(reflowState.ComputedPhysicalMargin() == nsMargin(0, 0, 0, 0),
                "reflow state should not set margin for reflow roots");
-  if (size.height != NS_UNCONSTRAINEDSIZE) {
-    nscoord computedHeight =
-      size.height - reflowState.ComputedPhysicalBorderPadding().TopBottom();
-    computedHeight = std::max(computedHeight, 0);
-    reflowState.SetComputedHeight(computedHeight);
-  }
-  NS_ASSERTION(reflowState.ComputedWidth() ==
-                 size.width -
-                   reflowState.ComputedPhysicalBorderPadding().LeftRight(),
-               "reflow state computed incorrect width");
+  if (size.BSize(wm) != NS_UNCONSTRAINEDSIZE) {
+    nscoord computedBSize =
+      size.BSize(wm) - reflowState.ComputedLogicalBorderPadding().BStartEnd(wm);
+    computedBSize = std::max(computedBSize, 0);
+    reflowState.SetComputedBSize(computedBSize);
+  }
+  NS_ASSERTION(reflowState.ComputedISize() ==
+               size.ISize(wm) -
+                   reflowState.ComputedLogicalBorderPadding().IStartEnd(wm),
+               "reflow state computed incorrect inline size");
 
   mPresContext->ReflowStarted(aInterruptible);
   mIsReflowing = true;
 
   nsReflowStatus status;
   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());
-  NS_ASSERTION((target == rootFrame && size.height == NS_UNCONSTRAINEDSIZE) ||
-               (desiredSize.Width() == size.width &&
-                desiredSize.Height() == size.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),
                "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");
@@ -8862,17 +8865,17 @@ PresShell::DoReflow(nsIFrame* target, bo
   // viewport bounds; the view manager "window dimensions" code depends on it.
   nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, target,
                                              target->GetView(),
                                              boundsRelativeToTarget);
   nsContainerFrame::SyncWindowProperties(mPresContext, target,
                                          target->GetView(), rcx);
 
   target->DidReflow(mPresContext, nullptr, nsDidReflowStatus::FINISHED);
-  if (target == rootFrame && size.height == NS_UNCONSTRAINEDSIZE) {
+  if (target == rootFrame && size.BSize(wm) == NS_UNCONSTRAINEDSIZE) {
     mPresContext->SetVisibleArea(boundsRelativeToTarget);
   }
 
 #ifdef DEBUG
   mCurrentReflowRoot = nullptr;
 #endif
 
   NS_ASSERTION(mPresContext->HasPendingInterrupt() ||
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -817,17 +817,17 @@ protected:
   // middle of frame construction and the like... it really shouldn't be
   // needed, one hopes, but it is for now.
   uint16_t                  mChangeNestCount;
 
   bool                      mDocumentLoading : 1;
   bool                      mIgnoreFrameDestruction : 1;
   bool                      mHaveShutDown : 1;
   bool                      mViewportOverridden : 1;
-  bool                      mLastRootReflowHadUnconstrainedHeight : 1;
+  bool                      mLastRootReflowHadUnconstrainedBSize : 1;
   bool                      mNoDelayedMouseEvents : 1;
   bool                      mNoDelayedKeyEvents : 1;
 
   // We've been disconnected from the document.  We will refuse to paint the
   // document until either our timer fires or all frames are constructed.
   bool                      mIsDocumentGone : 1;
 
   // Indicates that it is safe to unlock painting once all pending reflows
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -411,17 +411,19 @@ nsComboboxControlFrame::ReflowDropdown(n
   if (!aReflowState.ShouldReflowAllKids() &&
       !NS_SUBTREE_DIRTY(mDropdownFrame)) {
     return;
   }
 
   // XXXbz this will, for small-height dropdowns, have extra space on the right
   // edge for the scrollbar we don't show... but that's the best we can do here
   // for now.
-  nsSize availSize(aReflowState.AvailableWidth(), NS_UNCONSTRAINEDSIZE);
+  WritingMode wm = mDropdownFrame->GetWritingMode();
+  LogicalSize availSize = aReflowState.AvailableSize(wm);
+  availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
   nsHTMLReflowState kidReflowState(aPresContext, aReflowState, mDropdownFrame,
                                    availSize);
 
   // If the dropdown's intrinsic width is narrower than our specified width,
   // then expand it out.  We want our border-box width to end up the same as
   // the dropdown's so account for both sets of mComputedBorderPadding.
   nscoord forcedWidth = aReflowState.ComputedWidth() +
     aReflowState.ComputedPhysicalBorderPadding().LeftRight() -
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -362,41 +362,46 @@ nsFieldSetFrame::Reflow(nsPresContext*  
     reflowInner = inner && NS_SUBTREE_DIRTY(inner);
     reflowLegend = legend && NS_SUBTREE_DIRTY(legend);
   }
 
   // We don't allow fieldsets to break vertically. If we did, we'd
   // need logic here to push and pull overflow frames.
   // Since we're not applying our padding in this frame, we need to add it here
   // to compute the available width for our children.
-  nsSize availSize(aReflowState.ComputedWidth() + aReflowState.ComputedPhysicalPadding().LeftRight(),
-                   NS_UNCONSTRAINEDSIZE);
+  WritingMode innerWM = inner ? inner->GetWritingMode() : GetWritingMode();
+  WritingMode legendWM = legend ? legend->GetWritingMode() : GetWritingMode();
+  LogicalSize innerAvailSize = aReflowState.ComputedSizeWithPadding(innerWM);
+  LogicalSize legendAvailSize = aReflowState.ComputedSizeWithPadding(legendWM);
+  innerAvailSize.BSize(innerWM) = legendAvailSize.BSize(legendWM) =
+    NS_UNCONSTRAINEDSIZE;
   NS_ASSERTION(!inner ||
       nsLayoutUtils::IntrinsicForContainer(aReflowState.rendContext,
                                            inner,
                                            nsLayoutUtils::MIN_WIDTH) <=
-               availSize.width,
-               "Bogus availSize.width; should be bigger");
+               innerAvailSize.ISize(innerWM),
+               "Bogus availSize.ISize; should be bigger");
   NS_ASSERTION(!legend ||
       nsLayoutUtils::IntrinsicForContainer(aReflowState.rendContext,
                                            legend,
                                            nsLayoutUtils::MIN_WIDTH) <=
-               availSize.width,
-               "Bogus availSize.width; should be bigger");
+               legendAvailSize.ISize(legendWM),
+               "Bogus availSize.ISize; should be bigger");
 
   // get our border and padding
   nsMargin border = aReflowState.ComputedPhysicalBorderPadding() - aReflowState.ComputedPhysicalPadding();
 
   // Figure out how big the legend is if there is one. 
   // get the legend's margin
   nsMargin legendMargin(0,0,0,0);
   // reflow the legend only if needed
   Maybe<nsHTMLReflowState> legendReflowState;
   if (legend) {
-    legendReflowState.construct(aPresContext, aReflowState, legend, availSize);
+    legendReflowState.construct(aPresContext, aReflowState, legend,
+                                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());
@@ -432,17 +437,18 @@ nsFieldSetFrame::Reflow(nsPresContext*  
     // mLegendSpace and mLegendRect haven't changed, but we need
     // the used margin when placing the legend.
     legendMargin = legend->GetUsedMargin();
   }
 
   // reflow the content frame only if needed
   if (reflowInner) {
     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, inner,
-                                     availSize, -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
+                                     innerAvailSize, -1, -1,
+                                     nsHTMLReflowState::CALLER_WILL_INIT);
     // Override computed padding, in case it's percentage padding
     kidReflowState.Init(aPresContext, -1, -1, nullptr,
                         &aReflowState.ComputedPhysicalPadding());
     // Our child is "height:100%" but we actually want its height to be reduced
     // by the amount of content-height the legend is eating up, unless our
     // height is unconstrained (in which case the child's will be too).
     if (aReflowState.ComputedHeight() != NS_UNCONSTRAINEDSIZE) {
       kidReflowState.SetComputedHeight(
@@ -468,32 +474,35 @@ nsFieldSetFrame::Reflow(nsPresContext*  
     ReflowChild(inner, aPresContext, kidDesiredSize, kidReflowState,
                 pt.x, pt.y, 0, aStatus);
 
     FinishReflowChild(inner, aPresContext, kidDesiredSize,
                       &kidReflowState, pt.x, pt.y, 0);
     NS_FRAME_TRACE_REFLOW_OUT("FieldSet::Reflow", aStatus);
   }
 
-  nsRect contentRect;
+  LogicalRect contentRect(innerWM);
   if (inner) {
     // We don't support margins on inner, so our content rect is just the
     // inner's border-box.
-    contentRect = inner->GetRect();
+    contentRect = inner->GetLogicalRect(aReflowState.ComputedWidth());
   }
 
   // Our content rect must fill up the available width
-  if (availSize.width > contentRect.width) {
-    contentRect.width = availSize.width;
+  if (innerAvailSize.ISize(innerWM) > contentRect.ISize(innerWM)) {
+    contentRect.ISize(innerWM) = innerAvailSize.ISize(innerWM);
   }
 
+  //XXX temporary!
+  nsRect physicalContentRect =
+    contentRect.GetPhysicalRect(innerWM, aReflowState.ComputedWidth());
   if (legend) {
     // the legend is postioned horizontally within the inner's content rect
     // (so that padding on the fieldset affects the legend position).
-    nsRect innerContentRect = contentRect;
+    nsRect innerContentRect = physicalContentRect;
     innerContentRect.Deflate(aReflowState.ComputedPhysicalPadding());
     // if the inner content rect is larger than the legend, we can align the legend
     if (innerContentRect.width > mLegendRect.width) {
       int32_t align = static_cast<nsLegendFrame*>
         (legend->GetContentInsertionFrame())->GetAlign();
 
       switch (align) {
         case NS_STYLE_TEXT_ALIGN_RIGHT:
@@ -506,33 +515,34 @@ nsFieldSetFrame::Reflow(nsPresContext*  
         default:
           mLegendRect.x = innerContentRect.x;
           break;
       }
     } else {
       // otherwise make place for the legend
       mLegendRect.x = innerContentRect.x;
       innerContentRect.width = mLegendRect.width;
-      contentRect.width = mLegendRect.width + aReflowState.ComputedPhysicalPadding().LeftRight();
+      physicalContentRect.width = mLegendRect.width +
+        aReflowState.ComputedPhysicalPadding().LeftRight();
     }
 
     // place the legend
     nsRect actualLegendRect(mLegendRect);
     actualLegendRect.Deflate(legendMargin);
     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() = contentRect.width + border.LeftRight();
+  aDesiredSize.Width() = physicalContentRect.width + border.LeftRight();
   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/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -239,43 +239,45 @@ nsHTMLButtonControlFrame::ReflowButtonCo
                                                nsHTMLReflowMetrics& aButtonDesiredSize,
                                                const nsHTMLReflowState& aButtonReflowState,
                                                nsIFrame* aFirstKid)
 {
   // Buttons have some bonus renderer-determined border/padding,
   // which occupies part of the button's content-box area:
   const nsMargin focusPadding = mRenderer.GetAddedButtonBorderAndPadding();
 
-  nsSize availSize(aButtonReflowState.ComputedWidth(), NS_INTRINSICSIZE);
+  WritingMode wm = aFirstKid->GetWritingMode();
+  LogicalSize availSize = aButtonReflowState.ComputedSize(GetWritingMode());
+  availSize.BSize(wm) = NS_INTRINSICSIZE;
 
   // Indent the child inside us by the focus border. We must do this separate
   // from the regular border.
-  availSize.width -= focusPadding.LeftRight();
-  
+  availSize.ISize(wm) -= LogicalMargin(wm, focusPadding).IStartEnd(wm);
+
   // See whether out availSize's width is big enough.  If it's smaller than our
   // intrinsic min width, that means that the kid wouldn't really fit; for a
   // better look in such cases we adjust the available width and our left
   // offset to allow the kid to spill left into our padding.
   nscoord xoffset = focusPadding.left +
     aButtonReflowState.ComputedPhysicalBorderPadding().left;
   nscoord extrawidth = GetMinWidth(aButtonReflowState.rendContext) -
     aButtonReflowState.ComputedWidth();
   if (extrawidth > 0) {
     nscoord extraleft = extrawidth / 2;
     nscoord extraright = extrawidth - extraleft;
     NS_ASSERTION(extraright >=0, "How'd that happen?");
-    
+
     // Do not allow the extras to be bigger than the relevant padding
     extraleft = std::min(extraleft, aButtonReflowState.ComputedPhysicalPadding().left);
     extraright = std::min(extraright, aButtonReflowState.ComputedPhysicalPadding().right);
     xoffset -= extraleft;
-    availSize.width += extraleft + extraright;
+    availSize.SetWidth(wm, availSize.Width(wm) + extraleft + extraright);
   }
-  availSize.width = std::max(availSize.width,0);
-  
+  availSize.SetWidth(wm, std::max(availSize.Width(wm), 0));
+
   // Give child a clone of the button's reflow state, with height/width reduced
   // by focusPadding, so that descendants with height:100% don't protrude.
   nsHTMLReflowState adjustedButtonReflowState =
     CloneReflowStateWithReducedContentBox(aButtonReflowState, focusPadding);
 
   nsHTMLReflowState contentsReflowState(aPresContext,
                                         adjustedButtonReflowState,
                                         aFirstKid, availSize);
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -18,16 +18,17 @@
 #include "nsFontMetrics.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLMeterElement.h"
 #include "nsContentList.h"
 #include "nsStyleSet.h"
 #include "nsThemeConstants.h"
 #include <algorithm>
 
+using namespace mozilla;
 using mozilla::dom::Element;
 using mozilla::dom::HTMLMeterElement;
 
 nsIFrame*
 NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMeterFrame(aContext);
 }
@@ -129,19 +130,21 @@ nsMeterFrame::Reflow(nsPresContext*     
 
 void
 nsMeterFrame::ReflowBarFrame(nsIFrame*                aBarFrame,
                              nsPresContext*           aPresContext,
                              const nsHTMLReflowState& aReflowState,
                              nsReflowStatus&          aStatus)
 {
   bool vertical = StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
-  nsHTMLReflowState reflowState(aPresContext, aReflowState, aBarFrame,
-                                nsSize(aReflowState.ComputedWidth(),
-                                       NS_UNCONSTRAINEDSIZE));
+  WritingMode wm = aBarFrame->GetWritingMode();
+  LogicalSize availSize = aReflowState.ComputedSize(wm);
+  availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
+  nsHTMLReflowState reflowState(aPresContext, aReflowState,
+                                aBarFrame, availSize);
   nscoord size = vertical ? aReflowState.ComputedHeight()
                           : aReflowState.ComputedWidth();
   nscoord xoffset = aReflowState.ComputedPhysicalBorderPadding().left;
   nscoord yoffset = aReflowState.ComputedPhysicalBorderPadding().top;
 
   // NOTE: Introduce a new function getPosition in the content part ?
   HTMLMeterElement* meterElement = static_cast<HTMLMeterElement*>(mContent);
 
--- a/layout/forms/nsNumberControlFrame.cpp
+++ b/layout/forms/nsNumberControlFrame.cpp
@@ -132,20 +132,22 @@ nsNumberControlFrame::Reflow(nsPresConte
     if (contentBoxHeight == NS_INTRINSICSIZE) {
       contentBoxHeight = 0;
     }
   } else {
     NS_ASSERTION(outerWrapperFrame == mFrames.FirstChild(), "huh?");
 
     nsHTMLReflowMetrics wrappersDesiredSize(aReflowState);
 
+    WritingMode wm = outerWrapperFrame->GetWritingMode();
+    LogicalSize availSize = aReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
+
     nsHTMLReflowState wrapperReflowState(aPresContext, aReflowState,
-                                         outerWrapperFrame,
-                                         nsSize(contentBoxWidth,
-                                                NS_UNCONSTRAINEDSIZE));
+                                         outerWrapperFrame, availSize);
 
     // offsets of wrapper frame
     nscoord xoffset = aReflowState.ComputedPhysicalBorderPadding().left +
                         wrapperReflowState.ComputedPhysicalMargin().left;
     nscoord yoffset = aReflowState.ComputedPhysicalBorderPadding().top +
                         wrapperReflowState.ComputedPhysicalMargin().top;
 
     nsReflowStatus childStatus;
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -18,16 +18,17 @@
 #include "nsFontMetrics.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLProgressElement.h"
 #include "nsContentList.h"
 #include "nsStyleSet.h"
 #include "nsThemeConstants.h"
 #include <algorithm>
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 nsIFrame*
 NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsProgressFrame(aContext);
 }
 
@@ -134,19 +135,21 @@ nsProgressFrame::Reflow(nsPresContext*  
 
 void
 nsProgressFrame::ReflowBarFrame(nsIFrame*                aBarFrame,
                                 nsPresContext*           aPresContext,
                                 const nsHTMLReflowState& aReflowState,
                                 nsReflowStatus&          aStatus)
 {
   bool vertical = StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
-  nsHTMLReflowState reflowState(aPresContext, aReflowState, aBarFrame,
-                                nsSize(aReflowState.ComputedWidth(),
-                                       NS_UNCONSTRAINEDSIZE));
+  WritingMode wm = aBarFrame->GetWritingMode();
+  LogicalSize availSize = aReflowState.ComputedSize(wm);
+  availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
+  nsHTMLReflowState reflowState(aPresContext, aReflowState,
+                                aBarFrame, availSize);
   nscoord size = vertical ? aReflowState.ComputedHeight()
                           : aReflowState.ComputedWidth();
   nscoord xoffset = aReflowState.ComputedPhysicalBorderPadding().left;
   nscoord yoffset = aReflowState.ComputedPhysicalBorderPadding().top;
 
   double position = static_cast<HTMLProgressElement*>(mContent)->Position();
 
   // Force the bar's size to match the current progress.
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -338,19 +338,21 @@ nsRangeFrame::ReflowAnonymousContent(nsP
 
     // Position the track:
     // The idea here is that we allow content authors to style the width,
     // height, border and padding of the track, but we ignore margin and
     // positioning properties and do the positioning ourself to keep the center
     // of the track's border box on the center of the nsRangeFrame's content
     // box.
 
-    nsHTMLReflowState trackReflowState(aPresContext, aReflowState, trackFrame,
-                                       nsSize(aReflowState.ComputedWidth(),
-                                              NS_UNCONSTRAINEDSIZE));
+    WritingMode wm = trackFrame->GetWritingMode();
+    LogicalSize availSize = aReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
+    nsHTMLReflowState trackReflowState(aPresContext, aReflowState,
+                                       trackFrame, availSize);
 
     // Find the x/y position of the track frame such that it will be positioned
     // as described above. These coordinates are with respect to the
     // nsRangeFrame's border-box.
     nscoord trackX = rangeFrameContentBoxWidth / 2;
     nscoord trackY = rangeFrameContentBoxHeight / 2;
 
     // Account for the track's border and padding (we ignore its margin):
@@ -371,19 +373,21 @@ nsRangeFrame::ReflowAnonymousContent(nsP
                "We gave our child unconstrained height, so it should be complete");
     FinishReflowChild(trackFrame, aPresContext, trackDesiredSize,
                       &trackReflowState, trackX, trackY, 0);
   }
 
   nsIFrame* thumbFrame = mThumbDiv->GetPrimaryFrame();
 
   if (thumbFrame) { // display:none?
-    nsHTMLReflowState thumbReflowState(aPresContext, aReflowState, thumbFrame,
-                                       nsSize(aReflowState.ComputedWidth(),
-                                              NS_UNCONSTRAINEDSIZE));
+    WritingMode wm = thumbFrame->GetWritingMode();
+    LogicalSize availSize = aReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
+    nsHTMLReflowState thumbReflowState(aPresContext, aReflowState,
+                                       thumbFrame, availSize);
 
     // Where we position the thumb depends on its size, so we first reflow
     // the thumb at {0,0} to obtain its size, then position it afterwards.
 
     nsReflowStatus frameStatus;
     nsHTMLReflowMetrics thumbDesiredSize(aReflowState);
     ReflowChild(thumbFrame, aPresContext, thumbDesiredSize,
                 thumbReflowState, 0, 0, 0, frameStatus);
@@ -393,20 +397,21 @@ nsRangeFrame::ReflowAnonymousContent(nsP
                       &thumbReflowState, 0, 0, 0);
     DoUpdateThumbPosition(thumbFrame, nsSize(aDesiredSize.Width(),
                                              aDesiredSize.Height()));
   }
 
   nsIFrame* rangeProgressFrame = mProgressDiv->GetPrimaryFrame();
 
   if (rangeProgressFrame) { // display:none?
+    WritingMode wm = rangeProgressFrame->GetWritingMode();
+    LogicalSize availSize = aReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     nsHTMLReflowState progressReflowState(aPresContext, aReflowState,
-                                          rangeProgressFrame,
-                                          nsSize(aReflowState.ComputedWidth(),
-                                                 NS_UNCONSTRAINEDSIZE));
+                                          rangeProgressFrame, availSize);
 
     // We first reflow the range-progress frame at {0,0} to obtain its
     // unadjusted dimensions, then we adjust it to so that the appropriate edge
     // ends at the thumb.
 
     nsReflowStatus frameStatus;
     nsHTMLReflowMetrics progressDesiredSize(aReflowState);
     ReflowChild(rangeProgressFrame, aPresContext,
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -516,22 +516,23 @@ nsTextControlFrame::Reflow(nsPresContext
 void
 nsTextControlFrame::ReflowTextControlChild(nsIFrame*                aKid,
                                            nsPresContext*           aPresContext,
                                            const nsHTMLReflowState& aReflowState,
                                            nsReflowStatus&          aStatus,
                                            nsHTMLReflowMetrics& aParentDesiredSize)
 {
   // compute available size and frame offsets for child
-  nsSize availSize(aReflowState.ComputedWidth() +
-                   aReflowState.ComputedPhysicalPadding().LeftRight(),
-                   NS_UNCONSTRAINEDSIZE);
+  WritingMode wm = aKid->GetWritingMode();
+  LogicalSize availSize = aReflowState.ComputedSizeWithPadding(wm);
+  availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
 
   nsHTMLReflowState kidReflowState(aPresContext, aReflowState, 
-                                   aKid, availSize, -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
+                                   aKid, availSize, -1, -1,
+                                   nsHTMLReflowState::CALLER_WILL_INIT);
   // Override padding with our computed padding in case we got it from theming or percentage
   kidReflowState.Init(aPresContext, -1, -1, nullptr, &aReflowState.ComputedPhysicalPadding());
 
   // Set computed width and computed height for the child
   kidReflowState.SetComputedWidth(aReflowState.ComputedWidth());
   kidReflowState.SetComputedHeight(aReflowState.ComputedHeight());
 
   // Offset the frame by the size of the parent's border
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -29,16 +29,18 @@ static void PrettyUC(nscoord aSize, char
       strcpy(aBuf, "deadbeef");
     } else {
       sprintf(aBuf, "%d", aSize);
     }
   }
 }
 #endif
 
+using namespace mozilla;
+
 void
 nsAbsoluteContainingBlock::SetInitialChildList(nsIFrame*       aDelegatingFrame,
                                                ChildListID     aListID,
                                                nsFrameList&    aChildList)
 {
   NS_PRECONDITION(mChildListID == aListID, "unexpected child list name");
 #ifdef DEBUG
   nsFrame::VerifyDirtyBitSet(aChildList);
@@ -362,27 +364,30 @@ nsAbsoluteContainingBlock::ReflowAbsolut
     printf(" a=%s,%s ", width, height);
     PrettyUC(aReflowState.ComputedWidth(), width);
     PrettyUC(aReflowState.ComputedHeight(), height);
     printf("c=%s,%s \n", width, height);
   }
   AutoNoisyIndenter indent(nsBlockFrame::gNoisy);
 #endif // DEBUG
 
-  nscoord availWidth = aContainingBlock.width;
-  if (availWidth == -1) {
-    NS_ASSERTION(aReflowState.ComputedWidth() != NS_UNCONSTRAINEDSIZE,
-                 "Must have a useful width _somewhere_");
-    availWidth =
-      aReflowState.ComputedWidth() + aReflowState.ComputedPhysicalPadding().LeftRight();
+  WritingMode wm = aKidFrame->GetWritingMode();
+  nscoord availISize = LogicalSize(wm, aContainingBlock.Size()).ISize(wm);
+  if (availISize == -1) {
+    NS_ASSERTION(aReflowState.ComputedSize(wm).ISize(wm) !=
+                   NS_UNCONSTRAINEDSIZE,
+                 "Must have a useful inline-size _somewhere_");
+    availISize =
+      aReflowState.ComputedSizeWithPadding(wm).ISize(wm);
   }
 
   nsHTMLReflowMetrics kidDesiredSize(aReflowState);
   nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame,
-                                   nsSize(availWidth, NS_UNCONSTRAINEDSIZE),
+                                   LogicalSize(wm, availISize,
+                                               NS_UNCONSTRAINEDSIZE),
                                    aContainingBlock.width,
                                    aContainingBlock.height);
 
   // Send the WillReflow() notification and position the frame
   aKidFrame->WillReflow(aPresContext);
 
   // Get the border values
   const nsMargin& border = aReflowState.mStyleBorder->GetComputedBorder();
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -3029,20 +3029,19 @@ nsBlockFrame::ReflowBlockFrame(nsBlockRe
       // value. We'll use a reason of `resize' so that we don't fudge
       // any incremental reflow state.
 
       // The availSpace here is irrelevant to our needs - all we want
       // out if this setup is the margin-top value which doesn't depend
       // on the childs available space.
       // XXX building a complete nsHTMLReflowState just to get the margin-top
       // seems like a waste. And we do this for almost every block!
-      nsSize availSpace =
-        LogicalSize(aState.mReflowState.GetWritingMode(),
-                    aState.ContentISize(), NS_UNCONSTRAINEDSIZE).
-          GetPhysicalSize(aState.mReflowState.GetWritingMode());
+      WritingMode wm = frame->GetWritingMode();
+      LogicalSize availSpace = aState.ContentSize(wm);
+      availSpace.BSize(wm) = NS_UNCONSTRAINEDSIZE;
       nsHTMLReflowState reflowState(aState.mPresContext, aState.mReflowState,
                                     frame, availSpace);
 
       if (treatWithClearance) {
         aState.mBCoord += aState.mPrevBEndMargin.get();
         aState.mPrevBEndMargin.Zero();
       }
 
@@ -3174,18 +3173,19 @@ nsBlockFrame::ReflowBlockFrame(nsBlockRe
     availSpace.y -= bStartMargin;
     if (NS_UNCONSTRAINEDSIZE != availSpace.height) {
       availSpace.height += bStartMargin;
     }
 
     // Reflow the block into the available space
     // construct the html reflow state for the block. ReflowBlock
     // will initialize it
-    nsHTMLReflowState blockHtmlRS(aState.mPresContext, aState.mReflowState, frame,
-                                  availSpace.Size());
+    nsHTMLReflowState
+      blockHtmlRS(aState.mPresContext, aState.mReflowState, frame,
+                  LogicalSize(frame->GetWritingMode(), availSpace.Size()));
     blockHtmlRS.mFlags.mHasClearance = aLine->HasClearance();
 
     nsFloatManager::SavedState floatManagerState;
     if (mayNeedRetry) {
       blockHtmlRS.mDiscoveredClearance = &clearanceFrame;
       aState.mFloatManager->PushState(&floatManagerState);
     } else if (!applyBStartMargin) {
       blockHtmlRS.mDiscoveredClearance = aState.mReflowState.mDiscoveredClearance;
@@ -3214,30 +3214,30 @@ nsBlockFrame::ReflowBlockFrame(nsBlockRe
       NS_ASSERTION(originalPosition == frame->GetPosition(),
                    "we need to call PositionChildViews");
       return;
     }
 
 #if defined(REFLOW_STATUS_COVERAGE)
     RecordReflowStatus(true, frameReflowStatus);
 #endif
-    
+
     if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) {
       // None of the child block fits.
       *aKeepReflowGoing = false;
       if (ShouldAvoidBreakInside(aState.mReflowState)) {
         aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
       } else {
         PushLines(aState, aLine.prev());
         NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
       }
     }
     else {
       // Note: line-break-after a block is a nop
-      
+
       // Try to place the child block.
       // Don't force the block to fit if we have positive clearance, because
       // pushing it to the next page would give it more room.
       // Don't force the block to fit if it's impacted by a float. If it is,
       // then pushing it to the next page would give it more room. Note that
       // isImpacted doesn't include impact from the block's own floats.
       bool forceFit = aState.IsAdjacentWithTop() && clearance <= 0 &&
         !floatAvailableSpace.mHasFloats;
@@ -5764,18 +5764,20 @@ nsBlockFrame::ComputeFloatWidth(nsBlockR
                                 nsIFrame*           aFloat)
 {
   NS_PRECONDITION(aFloat->GetStateBits() & NS_FRAME_OUT_OF_FLOW,
                   "aFloat must be an out-of-flow frame");
   // Reflow the float.
   nsRect availSpace = AdjustFloatAvailableSpace(aState, aFloatAvailableSpace,
                                                 aFloat);
 
-  nsHTMLReflowState floatRS(aState.mPresContext, aState.mReflowState, aFloat, 
-                            availSpace.Size());
+  WritingMode wm = aFloat->GetWritingMode();
+  nsHTMLReflowState floatRS(aState.mPresContext, aState.mReflowState, aFloat,
+                            LogicalSize(wm, availSpace.Size()));
+
   return floatRS.ComputedWidth() + floatRS.ComputedPhysicalBorderPadding().LeftRight() +
     floatRS.ComputedPhysicalMargin().LeftRight();
 }
 
 void
 nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
                           const nsRect&       aAdjustedAvailableSpace,
                           nsIFrame*           aFloat,
@@ -5792,19 +5794,20 @@ nsBlockFrame::ReflowFloat(nsBlockReflowS
 #ifdef NOISY_FLOAT
   printf("Reflow Float %p in parent %p, availSpace(%d,%d,%d,%d)\n",
           aFloat, this, 
           aFloatAvailableSpace.x, aFloatAvailableSpace.y, 
           aFloatAvailableSpace.width, aFloatAvailableSpace.height
   );
 #endif
 
-  nsHTMLReflowState floatRS(aState.mPresContext, aState.mReflowState, aFloat,
-                            nsSize(aAdjustedAvailableSpace.width,
-                                   aAdjustedAvailableSpace.height));
+  nsHTMLReflowState
+    floatRS(aState.mPresContext, aState.mReflowState, aFloat,
+            LogicalSize(aFloat->GetWritingMode(),
+                        aAdjustedAvailableSpace.Size()));
 
   // Normally the mIsTopOfPage state is copied from the parent reflow
   // state.  However, when reflowing a float, if we've placed other
   // floats that force this float *down* or *narrower*, we should unset
   // the mIsTopOfPage state.
   // FIXME: This is somewhat redundant with the |isAdjacentWithTop|
   // variable below, which has the exact same effect.  Perhaps it should
   // be merged into that, except that the test for narrowing here is not
@@ -6792,20 +6795,21 @@ void
 nsBlockFrame::ReflowBullet(nsIFrame* aBulletFrame,
                            nsBlockReflowState& aState,
                            nsHTMLReflowMetrics& aMetrics,
                            nscoord aLineTop)
 {
   const nsHTMLReflowState &rs = aState.mReflowState;
 
   // Reflow the bullet now
-  nsSize availSize;
-  // Make up a width since it doesn't really matter (XXX).
-  availSize.width = aState.ContentISize();
-  availSize.height = NS_UNCONSTRAINEDSIZE;
+  WritingMode bulletWM = aBulletFrame->GetWritingMode();
+  LogicalSize availSize(bulletWM);
+  // Make up an inline-size since it doesn't really matter (XXX).
+  availSize.ISize(bulletWM) = aState.ContentISize();
+  availSize.BSize(bulletWM) = NS_UNCONSTRAINEDSIZE;
 
   // Get the reason right.
   // XXXwaterson Should this look just like the logic in
   // nsBlockReflowContext::ReflowBlock and nsLineLayout::ReflowFrame?
   nsHTMLReflowState reflowState(aState.mPresContext, rs,
                                 aBulletFrame, availSize);
   nsReflowStatus  status;
   aBulletFrame->WillReflow(aState.mPresContext);
@@ -6835,17 +6839,16 @@ nsBlockFrame::ReflowBullet(nsIFrame* aBu
   // IStart from floatAvailSpace gives us the content/float start edge
   // in the current writing mode. Then we subtract out the start
   // border/padding and the bullet's width and margin to offset the position.
   WritingMode wm = rs.GetWritingMode();
   nscoord containerWidth = floatAvailSpace.XMost();
   LogicalRect logicalFAS(wm, floatAvailSpace, containerWidth);
   // Get the bullet's margin, converted to our writing mode so that we can
   // combine it with other logical values here.
-  WritingMode bulletWM = reflowState.GetWritingMode();
   LogicalMargin bulletMargin =
     reflowState.ComputedLogicalMargin().ConvertTo(wm, bulletWM);
   nscoord iStart = logicalFAS.IStart(wm) -
                    rs.ComputedLogicalBorderPadding().IStart(wm) -
                    bulletMargin.IEnd(wm) -
                    aMetrics.ISize(wm);
 
   // Approximate the bullets position; vertical alignment will provide
@@ -7024,17 +7027,18 @@ nsBlockFrame::WidthToClearPastFloats(nsB
   nscoord availWidth = aState.mContentArea.Width(wm) - leftOffset - rightOffset;
 
   // We actually don't want the min width here; see bug 427782; we only
   // want to displace if the width won't compute to a value small enough
   // to fit.
   // All we really need here is the result of ComputeSize, and we
   // could *almost* get that from an nsCSSOffsetState, except for the
   // last argument.
-  nsSize availSpace(availWidth, NS_UNCONSTRAINEDSIZE);
+  LogicalSize availSpace(aFrame->GetWritingMode(),
+                         nsSize(availWidth, NS_UNCONSTRAINEDSIZE));
   nsHTMLReflowState reflowState(aState.mPresContext, aState.mReflowState,
                                 aFrame, availSpace);
   result.borderBoxWidth = reflowState.ComputedWidth() +
                           reflowState.ComputedPhysicalBorderPadding().LeftRight();
   // Use the margins from offsetState rather than reflowState so that
   // they aren't reduced by ignoring margins in overconstrained cases.
   result.marginLeft  = offsetState.ComputedPhysicalMargin().left;
   result.marginRight = offsetState.ComputedPhysicalMargin().right;
--- a/layout/generic/nsBlockReflowContext.cpp
+++ b/layout/generic/nsBlockReflowContext.cpp
@@ -139,23 +139,23 @@ nsBlockReflowContext::ComputeCollapsedBS
           // We may have to construct an extra reflow state here if
           // we drilled down through a block wrapper. At the moment
           // we can only drill down one level so we only have to support
           // one extra reflow state.
           const nsHTMLReflowState* outerReflowState = &aRS;
           if (frame != aRS.frame) {
             NS_ASSERTION(frame->GetParent() == aRS.frame,
                          "Can only drill through one level of block wrapper");
-            nsSize availSpace(aRS.ComputedWidth(), aRS.ComputedHeight());
+            LogicalSize availSpace = aRS.ComputedSize(frame->GetWritingMode());
             outerReflowState = new nsHTMLReflowState(prescontext,
                                                      aRS, frame, availSpace);
           }
           {
-            nsSize availSpace(outerReflowState->ComputedWidth(),
-                              outerReflowState->ComputedHeight());
+            LogicalSize availSpace =
+              outerReflowState->ComputedSize(kid->GetWritingMode());
             nsHTMLReflowState innerReflowState(prescontext,
                                                *outerReflowState, kid,
                                                availSpace);
             // Record that we're being optimistic by assuming the kid
             // has no clearance
             if (kid->StyleDisplay()->mBreakType != NS_STYLE_CLEAR_NONE) {
               *aMayNeedRetry = true;
             }
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -193,16 +193,20 @@ public:
     return mContentArea.BStart(mReflowState.GetWritingMode());
   }
   nscoord ContentBSize() const {
     return mContentArea.BSize(mReflowState.GetWritingMode());
   }
   nscoord ContentBEnd() const {
     return mContentArea.BEnd(mReflowState.GetWritingMode());
   }
+  mozilla::LogicalSize ContentSize(mozilla::WritingMode aWM) const {
+    mozilla::WritingMode wm = mReflowState.GetWritingMode();
+    return mContentArea.Size(wm).ConvertTo(aWM, wm);
+  }
   nscoord mContainerWidth;
 
   // Continuation out-of-flow float frames that need to move to our
   // next in flow are placed here during reflow.  It's a pointer to
   // a frame list stored in the block's property table.
   nsFrameList *mPushedFloats;
   // This method makes sure pushed floats are accessible to
   // StealFrame. Call it before adding any frames to mPushedFloats.
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -534,19 +534,19 @@ nsCanvasFrame::Reflow(nsPresContext*    
   nsHTMLReflowMetrics kidDesiredSize(aReflowState);
   if (mFrames.IsEmpty()) {
     // We have no child frame, so return an empty size
     aDesiredSize.Width() = aDesiredSize.Height() = 0;
   } else {
     nsIFrame* kidFrame = mFrames.FirstChild();
     bool kidDirty = (kidFrame->GetStateBits() & NS_FRAME_IS_DIRTY) != 0;
 
-    nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
-                                     nsSize(aReflowState.AvailableWidth(),
-                                            aReflowState.AvailableHeight()));
+    nsHTMLReflowState
+      kidReflowState(aPresContext, aReflowState, kidFrame,
+                     aReflowState.AvailableSize(kidFrame->GetWritingMode()));
 
     if (aReflowState.mFlags.mVResize &&
         (kidFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT)) {
       // Tell our kid it's being vertically resized too.  Bit of a
       // hack for framesets.
       kidReflowState.mFlags.mVResize = true;
     }
 
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -512,49 +512,51 @@ nsColumnSetFrame::ReflowChildren(nsHTMLR
         aStatus = mLastFrameStatus;
       }
       childContentBEnd = nsLayoutUtils::CalculateContentBEnd(wm, child);
 #ifdef DEBUG_roc
       printf("*** Skipping child #%d %p (incremental %d, resize height shrink %d): status = %d\n",
              columnCount, (void*)child, skipIncremental, skipResizeHeightShrink, aStatus);
 #endif
     } else {
-      nsSize availSize(aConfig.mColWidth, aConfig.mColMaxHeight);
-      
+      nsSize physicalSize(aConfig.mColWidth, aConfig.mColMaxHeight);
+
       if (aUnboundedLastColumn && columnCount == aConfig.mBalanceColCount - 1) {
-        availSize.height = GetAvailableContentHeight(aReflowState);
+        physicalSize.height = GetAvailableContentHeight(aReflowState);
       }
+      LogicalSize availSize(wm, physicalSize);
+      LogicalSize computedSize = aReflowState.ComputedSize(wm);
 
       if (reflowNext)
         child->AddStateBits(NS_FRAME_IS_DIRTY);
 
       nsHTMLReflowState kidReflowState(PresContext(), aReflowState, child,
-                                       availSize, availSize.width,
-                                       aReflowState.ComputedHeight());
+                                       availSize, availSize.ISize(wm),
+                                       computedSize.BSize(wm));
       kidReflowState.mFlags.mIsTopOfPage = true;
       kidReflowState.mFlags.mTableIsSplittable = false;
       kidReflowState.mFlags.mIsColumnBalancing = aConfig.mBalanceColCount < INT32_MAX;
 
       // We need to reflow any float placeholders, even if our column height
       // hasn't changed.
       kidReflowState.mFlags.mMustReflowPlaceholders = !colHeightChanged;
 
 #ifdef DEBUG_roc
       printf("*** Reflowing child #%d %p: availHeight=%d\n",
-             columnCount, (void*)child,availSize.height);
+             columnCount, (void*)child,availSize.BSize(wm));
 #endif
 
       // Note if the column's next in flow is not being changed by this incremental reflow.
       // This may allow the current column to avoid trying to pull lines from the next column.
       if (child->GetNextSibling() &&
           !(GetStateBits() & NS_FRAME_IS_DIRTY) &&
         !(child->GetNextSibling()->GetStateBits() & NS_FRAME_IS_DIRTY)) {
         kidReflowState.mFlags.mNextInFlowUntouched = true;
       }
-    
+
       nsHTMLReflowMetrics kidDesiredSize(wm, aDesiredSize.mFlags);
 
       // XXX it would be cool to consult the float manager for the
       // previous block to figure out the region of floats from the
       // previous column that extend into this column, and subtract
       // that region from the new float manager.  So you could stick a
       // really big float in the first column and text in following
       // columns would flow around it.
@@ -579,17 +581,17 @@ nsColumnSetFrame::ReflowChildren(nsHTMLR
       
       FinishReflowChild(child, PresContext(), kidDesiredSize,
                         &kidReflowState, childOrigin.x, childOrigin.y, 0);
 
       childContentBEnd = nsLayoutUtils::CalculateContentBEnd(wm, child);
       if (childContentBEnd > aConfig.mColMaxHeight) {
         allFit = false;
       }
-      if (childContentBEnd > availSize.height) {
+      if (childContentBEnd > availSize.BSize(wm)) {
         aColData.mMaxOverflowingHeight = std::max(childContentBEnd,
             aColData.mMaxOverflowingHeight);
       }
     }
 
     contentRect.UnionRect(contentRect, child->GetRect());
 
     ConsiderChildOverflow(overflowRects, child);
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -1108,17 +1108,19 @@ nsContainerFrame::ReflowOverflowContaine
       nsIFrame* prevInFlow = frame->GetPrevInFlow();
       NS_ASSERTION(prevInFlow,
                    "overflow container frame must have a prev-in-flow");
       NS_ASSERTION(frame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER,
                    "overflow container frame must have overflow container bit set");
       nsRect prevRect = prevInFlow->GetRect();
 
       // Initialize reflow params
-      nsSize availSpace(prevRect.width, aReflowState.AvailableHeight());
+      WritingMode wm = frame->GetWritingMode();
+      LogicalSize availSpace(wm, LogicalSize(wm, prevRect.Size()).ISize(wm),
+                             aReflowState.AvailableSize(wm).BSize(wm));
       nsHTMLReflowMetrics desiredSize(aReflowState);
       nsHTMLReflowState frameState(aPresContext, aReflowState,
                                    frame, availSpace);
       nsReflowStatus frameStatus;
 
       // Reflow
       ReflowChild(frame, aPresContext, desiredSize, frameState,
                   prevRect.x, 0, aFlags, frameStatus, &tracker);
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -164,38 +164,39 @@ nsFirstLetterFrame::Reflow(nsPresContext
   nsresult rv = NS_OK;
 
   // Grab overflow list
   DrainOverflowFrames(aPresContext);
 
   nsIFrame* kid = mFrames.FirstChild();
 
   // Setup reflow state for our child
-  nsSize availSize(aReflowState.AvailableWidth(), aReflowState.AvailableHeight());
-  const nsMargin& bp = aReflowState.ComputedPhysicalBorderPadding();
-  nscoord lr = bp.left + bp.right;
-  nscoord tb = bp.top + bp.bottom;
-  NS_ASSERTION(availSize.width != NS_UNCONSTRAINEDSIZE,
-               "should no longer use unconstrained widths");
-  availSize.width -= lr;
-  if (NS_UNCONSTRAINEDSIZE != availSize.height) {
-    availSize.height -= tb;
+  WritingMode wm = aReflowState.GetWritingMode();
+  LogicalSize availSize = aReflowState.AvailableSize();
+  const LogicalMargin& bp = aReflowState.ComputedLogicalBorderPadding();
+  NS_ASSERTION(availSize.ISize(wm) != NS_UNCONSTRAINEDSIZE,
+               "should no longer use unconstrained inline size");
+  availSize.ISize(wm) -= bp.IStartEnd(wm);
+  if (NS_UNCONSTRAINEDSIZE != availSize.BSize(wm)) {
+    availSize.BSize(wm) -= bp.BStartEnd(wm);
   }
 
   // Reflow the child
   if (!aReflowState.mLineLayout) {
     // When there is no lineLayout provided, we provide our own. The
     // only time that the first-letter-frame is not reflowing in a
     // line context is when its floating.
-    nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize);
+    WritingMode kidWritingMode = GetWritingMode(kid);
+    LogicalSize kidAvailSize = availSize.ConvertTo(kidWritingMode, wm);
+    nsHTMLReflowState rs(aPresContext, aReflowState, kid, kidAvailSize);
     nsLineLayout ll(aPresContext, nullptr, &aReflowState, nullptr);
 
-    ll.BeginLineReflow(bp.left, bp.top, availSize.width, NS_UNCONSTRAINEDSIZE,
-                       false, true,
-                       ll.LineContainerFrame()->GetWritingMode(kid),
+    ll.BeginLineReflow(bp.IStart(wm), bp.BStart(wm),
+                       availSize.ISize(wm), NS_UNCONSTRAINEDSIZE,
+                       false, true, kidWritingMode,
                        aReflowState.AvailableWidth());
     rs.mLineLayout = &ll;
     ll.SetInFirstLetter(true);
     ll.SetFirstLetterStyleOK(true);
 
     kid->WillReflow(aPresContext);
     kid->Reflow(aPresContext, aMetrics, rs, aReflowStatus);
 
@@ -208,30 +209,35 @@ nsFirstLetterFrame::Reflow(nsPresContext
   }
   else {
     // Pretend we are a span and reflow the child frame
     nsLineLayout* ll = aReflowState.mLineLayout;
     bool          pushedFrame;
 
     ll->SetInFirstLetter(
       mStyleContext->GetPseudo() == nsCSSPseudoElements::firstLetter);
-    ll->BeginSpan(this, &aReflowState, bp.left, availSize.width, &mBaseline);
+    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
-  kid->SetRect(nsRect(bp.left, bp.top, aMetrics.Width(), aMetrics.Height()));
+  LogicalSize convertedSize(wm, nsSize(aMetrics.Width(), aMetrics.Height()));
+  kid->SetRect(nsRect(bp.IStart(wm), bp.BStart(wm),
+                      convertedSize.ISize(wm), convertedSize.BSize(wm)));
   kid->FinishAndStoreOverflow(&aMetrics);
   kid->DidReflow(aPresContext, nullptr, nsDidReflowStatus::FINISHED);
 
-  aMetrics.Width() += lr;
-  aMetrics.Height() += tb;
-  aMetrics.SetBlockStartAscent(aMetrics.BlockStartAscent() + bp.top);
+  convertedSize.ISize(wm) += bp.IStartEnd(wm);
+  convertedSize.BSize(wm) += bp.BStartEnd(wm);
+  aMetrics.SetSize(wm, convertedSize);
+  aMetrics.SetBlockStartAscent(aMetrics.BlockStartAscent() +
+                               bp.BStart(wm));
 
   // Ensure that the overflow rect contains the child textframe's overflow rect.
   // Note that if this is floating, the overline/underline drawable area is in
   // the overflow rect of the child textframe.
   aMetrics.UnionOverflowAreasWithDesiredBounds();
   ConsiderChildOverflow(aMetrics.mOverflowAreas, kid);
 
   if (!NS_INLINE_IS_BREAK_BEFORE(aReflowStatus)) {
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -954,19 +954,19 @@ nsFlexContainerFrame::GenerateFlexItemFo
   nsPresContext* aPresContext,
   nsIFrame*      aChildFrame,
   const nsHTMLReflowState& aParentReflowState,
   const FlexboxAxisTracker& aAxisTracker)
 {
   // Create temporary reflow state just for sizing -- to get hypothetical
   // main-size and the computed values of min / max main-size property.
   // (This reflow state will _not_ be used for reflow.)
-  nsHTMLReflowState childRS(aPresContext, aParentReflowState, aChildFrame,
-                            nsSize(aParentReflowState.ComputedWidth(),
-                                   aParentReflowState.ComputedHeight()));
+  nsHTMLReflowState
+    childRS(aPresContext, aParentReflowState, aChildFrame,
+            aParentReflowState.ComputedSize(aChildFrame->GetWritingMode()));
 
   // FLEX GROW & SHRINK WEIGHTS
   // --------------------------
   const nsStylePosition* stylePos = aChildFrame->StylePosition();
   float flexGrow   = stylePos->mFlexGrow;
   float flexShrink = stylePos->mFlexShrink;
 
   // MAIN SIZES (flex base size, min/max size)
@@ -1375,21 +1375,22 @@ nsFlexContainerFrame::
 nscoord
 nsFlexContainerFrame::
   MeasureFlexItemContentHeight(nsPresContext* aPresContext,
                                FlexItem& aFlexItem,
                                bool aForceVerticalResizeForMeasuringReflow,
                                const nsHTMLReflowState& aParentReflowState)
 {
   // Set up a reflow state for measuring the flex item's auto-height:
+  WritingMode wm = aFlexItem.Frame()->GetWritingMode();
+  LogicalSize availSize = aParentReflowState.ComputedSize(wm);
+  availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
   nsHTMLReflowState
     childRSForMeasuringHeight(aPresContext, aParentReflowState,
-                              aFlexItem.Frame(),
-                              nsSize(aParentReflowState.ComputedWidth(),
-                                     NS_UNCONSTRAINEDSIZE),
+                              aFlexItem.Frame(), availSize,
                               -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
   childRSForMeasuringHeight.mFlags.mIsFlexContainerMeasuringHeight = true;
   childRSForMeasuringHeight.Init(aPresContext);
 
   if (aFlexItem.IsStretched()) {
     childRSForMeasuringHeight.SetComputedWidth(aFlexItem.GetCrossSize());
     childRSForMeasuringHeight.mFlags.mHResize = true;
   }
@@ -3493,20 +3494,21 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
   // ===================================================
   // Calculate the hypothetical cross size of each item:
   nscoord sumLineCrossSizes = 0;
   for (FlexLine* line = lines.getFirst(); line; line = line->getNext()) {
     for (FlexItem* item = line->GetFirstItem(); item; item = item->getNext()) {
       // (If the item's already been stretched, or it's a strut, then it
       // already knows its cross size.  Don't bother trying to recalculate it.)
       if (!item->IsStretched() && !item->IsStrut()) {
+        WritingMode wm = item->Frame()->GetWritingMode();
+        LogicalSize availSize = aReflowState.ComputedSize(wm);
+        availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
         nsHTMLReflowState childReflowState(aPresContext, aReflowState,
-                                           item->Frame(),
-                                           nsSize(aReflowState.ComputedWidth(),
-                                                  NS_UNCONSTRAINEDSIZE));
+                                           item->Frame(), availSize);
         // Override computed main-size
         if (IsAxisHorizontal(aAxisTracker.GetMainAxis())) {
           childReflowState.SetComputedWidth(item->GetMainSize());
         } else {
           childReflowState.SetComputedHeight(item->GetMainSize());
         }
         
         SizeItemInCrossAxis(aPresContext, aAxisTracker,
@@ -3613,20 +3615,21 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
                                item->GetMainPosition(),
                                item->GetCrossPosition(),
                                aContentBoxMainSize,
                                contentBoxCrossSize);
       // Adjust physicalPosn to be relative to the container's border-box
       // (i.e. its frame rect), instead of the container's content-box:
       physicalPosn += containerContentBoxOrigin;
 
+      WritingMode wm = item->Frame()->GetWritingMode();
+      LogicalSize availSize = aReflowState.ComputedSize(wm);
+      availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
       nsHTMLReflowState childReflowState(aPresContext, aReflowState,
-                                         item->Frame(),
-                                         nsSize(aReflowState.ComputedWidth(),
-                                                NS_UNCONSTRAINEDSIZE));
+                                         item->Frame(), availSize);
 
       // Keep track of whether we've overriden the child's computed height
       // and/or width, so we can set its resize flags accordingly.
       bool didOverrideComputedWidth = false;
       bool didOverrideComputedHeight = false;
 
       // Override computed main-size
       if (IsAxisHorizontal(aAxisTracker.GetMainAxis())) {
--- a/layout/generic/nsFontInflationData.cpp
+++ b/layout/generic/nsFontInflationData.cpp
@@ -150,18 +150,20 @@ ComputeDescendantWidth(const nsHTMLReflo
 
   uint32_t len = frames.Length();
   nsHTMLReflowState *reflowStates = static_cast<nsHTMLReflowState*>
                                 (moz_xmalloc(sizeof(nsHTMLReflowState) * len));
   nsPresContext *presContext = aDescendantFrame->PresContext();
   for (uint32_t i = 0; i < len; ++i) {
     const nsHTMLReflowState &parentReflowState =
       (i == 0) ? aAncestorReflowState : reflowStates[i - 1];
-    nsSize availSize(parentReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
     nsIFrame *frame = frames[len - i - 1];
+    WritingMode wm = frame->GetWritingMode();
+    LogicalSize availSize = parentReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     NS_ABORT_IF_FALSE(frame->GetParent()->FirstInFlow() ==
                         parentReflowState.frame->FirstInFlow(),
                       "bad logic in this function");
     new (reflowStates + i) nsHTMLReflowState(presContext, parentReflowState,
                                              frame, availSize);
   }
 
   NS_ABORT_IF_FALSE(reflowStates[len - 1].frame == aDescendantFrame,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -8139,19 +8139,21 @@ nsFrame::DoLayout(nsBoxLayoutState& aSta
   // Should we do this if IsCollapsed() is true?
   nsSize size(GetSize());
   desiredSize.Width() = size.width;
   desiredSize.Height() = size.height;
   desiredSize.UnionOverflowAreasWithDesiredBounds();
 
   if (HasAbsolutelyPositionedChildren()) {
     // Set up a |reflowState| to pass into ReflowAbsoluteFrames
+    WritingMode wm = GetWritingMode();
     nsHTMLReflowState reflowState(aState.PresContext(), this,
                                   aState.GetRenderingContext(),
-                                  nsSize(size.width, NS_UNCONSTRAINEDSIZE),
+                                  LogicalSize(wm, GetLogicalSize().ISize(wm),
+                                              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);
@@ -8239,20 +8241,21 @@ nsFrame::BoxReflow(nsBoxLayoutState&    
     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();
-    nsHTMLReflowState parentReflowState(aPresContext, parentFrame,
-                                        aRenderingContext,
-                                        parentSize,
-                                        nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
+    nsHTMLReflowState
+      parentReflowState(aPresContext, parentFrame, aRenderingContext,
+                        LogicalSize(parentFrame->GetWritingMode(),
+                                    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)
       parentReflowState.SetComputedHeight(std::max(parentSize.height, 0));
@@ -8277,19 +8280,21 @@ nsFrame::BoxReflow(nsBoxLayoutState&    
       // linked up correctly for text control frames, so do so here).
       parentRS = outerReflowState;
     } else {
       parentRS = &parentReflowState;
     }
 
     // XXX Is it OK that this reflow state has only one ancestor?
     // (It used to have a bogus parent, skipping all the boxes).
-    nsSize availSize(aWidth, NS_INTRINSICSIZE);
+    WritingMode wm = GetWritingMode();
+    LogicalSize logicalSize(wm, nsSize(aWidth, aHeight));
+    logicalSize.BSize(wm) = NS_INTRINSICSIZE;
     nsHTMLReflowState reflowState(aPresContext, *parentRS, this,
-                                  availSize, -1, -1,
+                                  logicalSize, -1, -1,
                                   nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
 
     // XXX_jwir3: This is somewhat fishy. If this is actually changing the value
     //            here (which it might be), then we should make sure that it's
     //            correct the first time around, rather than changing it later.
     reflowState.mCBReflowState = parentRS;
 
     reflowState.mReflowDepth = aState.GetReflowDepth();
@@ -8310,16 +8315,17 @@ nsFrame::BoxReflow(nsBoxLayoutState&    
     // various CSS effects such as shadow or outline.
     if (!IsFrameOfType(eBlockFrame)) {
       if (aHeight != NS_INTRINSICSIZE) {
         nscoord computedHeight =
           aHeight - reflowState.ComputedPhysicalBorderPadding().TopBottom();
         computedHeight = std::max(computedHeight, 0);
         reflowState.SetComputedHeight(computedHeight);
       } else {
+        nsSize availSize = logicalSize.GetPhysicalSize(wm);
         reflowState.SetComputedHeight(
           ComputeSize(aRenderingContext, availSize, availSize.width,
                       nsSize(reflowState.ComputedPhysicalMargin().LeftRight(),
                              reflowState.ComputedPhysicalMargin().TopBottom()),
                       nsSize(reflowState.ComputedPhysicalBorderPadding().LeftRight() -
                                reflowState.ComputedPhysicalPadding().LeftRight(),
                              reflowState.ComputedPhysicalBorderPadding().TopBottom() -
                                reflowState.ComputedPhysicalPadding().TopBottom()),
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -731,17 +731,18 @@ void
 nsHTMLFramesetFrame::ReflowPlaceChild(nsIFrame*                aChild,
                                       nsPresContext*           aPresContext,
                                       const nsHTMLReflowState& aReflowState,
                                       nsPoint&                 aOffset,
                                       nsSize&                  aSize,
                                       nsIntPoint*              aCellIndex)
 {
   // reflow the child
-  nsHTMLReflowState reflowState(aPresContext, aReflowState, aChild, aSize);
+  nsHTMLReflowState reflowState(aPresContext, aReflowState, aChild,
+                                LogicalSize(aChild->GetWritingMode(), aSize));
   reflowState.SetComputedWidth(std::max(0, aSize.width - reflowState.ComputedPhysicalBorderPadding().LeftRight()));
   reflowState.SetComputedHeight(std::max(0, aSize.height - reflowState.ComputedPhysicalBorderPadding().TopBottom()));
   nsHTMLReflowMetrics metrics(aReflowState);
   metrics.Width() = aSize.width;
   metrics.Height() = aSize.height;
   nsReflowStatus status;
 
   ReflowChild(aChild, aPresContext, metrics, reflowState, aOffset.x,
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -422,20 +422,22 @@ nsHTMLScrollFrame::ReflowScrolledFrame(S
     GetScrollbarMetrics(aState->mBoxState, mHelper.mVScrollbarBox,
                         nullptr, &vScrollbarPrefSize, true);
     availWidth = std::max(0, availWidth - vScrollbarPrefSize.width);
   }
 
   nsPresContext* presContext = PresContext();
 
   // Pass false for aInit so we can pass in the correct padding.
-  nsHTMLReflowState kidReflowState(presContext, aState->mReflowState,
-                                   mHelper.mScrolledFrame,
-                                   nsSize(availWidth, NS_UNCONSTRAINEDSIZE),
-                                   -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
+  nsHTMLReflowState
+    kidReflowState(presContext, aState->mReflowState,
+                   mHelper.mScrolledFrame,
+                   LogicalSize(mHelper.mScrolledFrame->GetWritingMode(),
+                               nsSize(availWidth, NS_UNCONSTRAINEDSIZE)),
+                   -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
   kidReflowState.Init(presContext, -1, -1, nullptr,
                       &padding);
   kidReflowState.mFlags.mAssumingHScrollbar = aAssumeHScroll;
   kidReflowState.mFlags.mAssumingVScrollbar = aAssumeVScroll;
   kidReflowState.SetComputedHeight(computedHeight);
   kidReflowState.ComputedMinHeight() = computedMinHeight;
   kidReflowState.ComputedMaxHeight() = computedMaxHeight;
 
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -202,18 +202,20 @@ nsHTMLCanvasFrame::Reflow(nsPresContext*
     aMetrics.Height() = std::max(0, aMetrics.Height());
   }
 
   aMetrics.SetOverflowAreasToDesiredBounds();
   FinishAndStoreOverflow(&aMetrics);
 
   // Reflow the single anon block child.
   nsReflowStatus childStatus;
-  nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
   nsIFrame* childFrame = mFrames.FirstChild();
+  WritingMode wm = childFrame->GetWritingMode();
+  LogicalSize availSize = aReflowState.ComputedSize(wm);
+  availSize.BSize(wm) = 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);
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -51,29 +51,29 @@ enum eNormalLineHeightControl {
 
 static eNormalLineHeightControl sNormalLineHeightControl = eUninitialized;
 
 // Initialize a <b>root</b> reflow state with a rendering context to
 // use for measuring things.
 nsHTMLReflowState::nsHTMLReflowState(nsPresContext*       aPresContext,
                                      nsIFrame*            aFrame,
                                      nsRenderingContext*  aRenderingContext,
-                                     const nsSize&        aAvailableSpace,
+                                     const LogicalSize&   aAvailableSpace,
                                      uint32_t             aFlags)
   : nsCSSOffsetState(aFrame, aRenderingContext)
   , mBlockDelta(0)
   , mReflowDepth(0)
 {
   NS_PRECONDITION(aRenderingContext, "no rendering context");
   MOZ_ASSERT(aPresContext, "no pres context");
   MOZ_ASSERT(aFrame, "no frame");
   MOZ_ASSERT(aPresContext == aFrame->PresContext(), "wrong pres context");
   parentReflowState = nullptr;
-  AvailableWidth() = aAvailableSpace.width;
-  AvailableHeight() = aAvailableSpace.height;
+  AvailableISize() = aAvailableSpace.ISize(mWritingMode);
+  AvailableBSize() = aAvailableSpace.BSize(mWritingMode);
   mFloatManager = nullptr;
   mLineLayout = nullptr;
   memset(&mFlags, 0, sizeof(mFlags));
   mDiscoveredClearance = nullptr;
   mPercentHeightObserver = nullptr;
 
   if (aFlags & DUMMY_PARENT_REFLOW_STATE) {
     mFlags.mDummyParentReflowState = true;
@@ -154,17 +154,17 @@ nsCSSOffsetState::nsCSSOffsetState(nsIFr
 }
 
 // Initialize a reflow state for a child frame's reflow. Some state
 // is copied from the parent reflow state; the remaining state is
 // computed.
 nsHTMLReflowState::nsHTMLReflowState(nsPresContext*           aPresContext,
                                      const nsHTMLReflowState& aParentReflowState,
                                      nsIFrame*                aFrame,
-                                     const nsSize&            aAvailableSpace,
+                                     const LogicalSize&       aAvailableSpace,
                                      nscoord                  aContainingBlockWidth,
                                      nscoord                  aContainingBlockHeight,
                                      uint32_t                 aFlags)
   : nsCSSOffsetState(aFrame, aParentReflowState.rendContext)
   , mBlockDelta(0)
   , mReflowDepth(aParentReflowState.mReflowDepth + 1)
   , mFlags(aParentReflowState.mFlags)
 {
@@ -182,18 +182,18 @@ nsHTMLReflowState::nsHTMLReflowState(nsP
 
   // If the parent is dirty, then the child is as well.
   // XXX Are the other cases where the parent reflows a child a second
   // time, as a resize?
   if (!mFlags.mSpecialHeightReflow)
     frame->AddStateBits(parentReflowState->frame->GetStateBits() &
                         NS_FRAME_IS_DIRTY);
 
-  AvailableWidth() = aAvailableSpace.width;
-  AvailableHeight() = aAvailableSpace.height;
+  AvailableISize() = aAvailableSpace.ISize(mWritingMode);
+  AvailableBSize() = aAvailableSpace.BSize(mWritingMode);
 
   mFloatManager = aParentReflowState.mFloatManager;
   if (frame->IsFrameOfType(nsIFrame::eLineParticipant))
     mLineLayout = aParentReflowState.mLineLayout;
   else
     mLineLayout = nullptr;
 
   // Note: mFlags was initialized as a copy of aParentReflowState.mFlags up in
--- a/layout/generic/nsHTMLReflowState.h
+++ b/layout/generic/nsHTMLReflowState.h
@@ -322,16 +322,87 @@ struct nsHTMLReflowState : public nsCSSO
     { return mWritingMode.IsVertical() ? mComputedMinHeight : mComputedMinWidth; }
   nscoord& ComputedMaxISize()
     { return mWritingMode.IsVertical() ? mComputedMaxHeight : mComputedMaxWidth; }
   nscoord& ComputedMinBSize()
     { return mWritingMode.IsVertical() ? mComputedMinWidth : mComputedMinHeight; }
   nscoord& ComputedMaxBSize()
     { return mWritingMode.IsVertical() ? mComputedMaxWidth : mComputedMaxHeight; }
 
+  mozilla::LogicalSize AvailableSize() const {
+    return mozilla::LogicalSize(mWritingMode,
+                                AvailableISize(), AvailableBSize());
+  }
+  mozilla::LogicalSize ComputedSize() const {
+    return mozilla::LogicalSize(mWritingMode,
+                                ComputedISize(), ComputedBSize());
+  }
+  mozilla::LogicalSize ComputedMinSize() const {
+    return mozilla::LogicalSize(mWritingMode,
+                                ComputedMinISize(), ComputedMinBSize());
+  }
+  mozilla::LogicalSize ComputedMaxSize() const {
+    return mozilla::LogicalSize(mWritingMode,
+                                ComputedMaxISize(), ComputedMaxBSize());
+  }
+
+  mozilla::LogicalSize AvailableSize(mozilla::WritingMode aWM) const
+  { return AvailableSize().ConvertTo(aWM, mWritingMode); }
+  mozilla::LogicalSize ComputedSize(mozilla::WritingMode aWM) const
+    { return ComputedSize().ConvertTo(aWM, mWritingMode); }
+  mozilla::LogicalSize ComputedMinSize(mozilla::WritingMode aWM) const
+    { return ComputedMinSize().ConvertTo(aWM, mWritingMode); }
+  mozilla::LogicalSize ComputedMaxSize(mozilla::WritingMode aWM) const
+    { return ComputedMaxSize().ConvertTo(aWM, mWritingMode); }
+
+  mozilla::LogicalSize ComputedSizeWithPadding() const {
+    mozilla::WritingMode wm = GetWritingMode();
+    return mozilla::LogicalSize(wm,
+                                ComputedISize() +
+                                ComputedLogicalPadding().IStartEnd(wm),
+                                ComputedBSize() +
+                                ComputedLogicalPadding().BStartEnd(wm));
+  }
+
+  mozilla::LogicalSize ComputedSizeWithPadding(mozilla::WritingMode aWM) const {
+    return ComputedSizeWithPadding().ConvertTo(aWM, GetWritingMode());
+  }
+
+  mozilla::LogicalSize ComputedSizeWithBorderPadding() const {
+    mozilla::WritingMode wm = GetWritingMode();
+    return mozilla::LogicalSize(wm,
+                                ComputedISize() +
+                                ComputedLogicalBorderPadding().IStartEnd(wm),
+                                ComputedBSize() +
+                                ComputedLogicalBorderPadding().BStartEnd(wm));
+  }
+
+  mozilla::LogicalSize
+  ComputedSizeWithBorderPadding(mozilla::WritingMode aWM) const {
+    return ComputedSizeWithBorderPadding().ConvertTo(aWM, GetWritingMode());
+  }
+
+  mozilla::LogicalSize
+  ComputedSizeWithMarginBorderPadding() const {
+    mozilla::WritingMode wm = GetWritingMode();
+    return mozilla::LogicalSize(wm,
+                                ComputedISize() +
+                                ComputedLogicalMargin().IStartEnd(wm) +
+                                ComputedLogicalBorderPadding().IStartEnd(wm),
+                                ComputedBSize() +
+                                ComputedLogicalMargin().BStartEnd(wm) +
+                                ComputedLogicalBorderPadding().BStartEnd(wm));
+  }
+
+  mozilla::LogicalSize
+  ComputedSizeWithMarginBorderPadding(mozilla::WritingMode aWM) const {
+    return ComputedSizeWithMarginBorderPadding().ConvertTo(aWM,
+                                                           GetWritingMode());
+  }
+
   // XXX this will need to change when we make mComputedOffsets logical;
   // we won't be able to return a reference for the physical offsets
   const nsMargin& ComputedPhysicalOffsets() const { return mComputedOffsets; }
   nsMargin& ComputedPhysicalOffsets() { return mComputedOffsets; }
 
   LogicalMargin ComputedLogicalOffsets() const
     { return LogicalMargin(mWritingMode, mComputedOffsets); }
 
@@ -468,21 +539,21 @@ public:
    * @param aPresContext Must be equal to aFrame->PresContext().
    * @param aFrame The frame for whose reflow state is being constructed.
    * @param aRenderingContext The rendering context to be used for measurements.
    * @param aAvailableSpace See comments for availableHeight and availableWidth
    *        members.
    * @param aFlags A set of flags used for additional boolean parameters (see
    *        below).
    */
-  nsHTMLReflowState(nsPresContext*           aPresContext,
-                    nsIFrame*                aFrame,
-                    nsRenderingContext*      aRenderingContext,
-                    const nsSize&            aAvailableSpace,
-                    uint32_t                 aFlags = 0);
+  nsHTMLReflowState(nsPresContext*              aPresContext,
+                    nsIFrame*                   aFrame,
+                    nsRenderingContext*         aRenderingContext,
+                    const mozilla::LogicalSize& aAvailableSpace,
+                    uint32_t                    aFlags = 0);
 
   /**
    * Initialize a reflow state for a child frame's reflow. Some parts of the
    * state are copied from the parent's reflow state. The remainder is computed.
    *
    * @param aPresContext Must be equal to aFrame->PresContext().
    * @param aParentReflowState A reference to an nsHTMLReflowState object that
    *        is to be the parent of this object.
@@ -493,40 +564,40 @@ public:
    *        by absolute positioning code to override default containing block
    *        width.
    * @param aContainingBlockHeight An optional height, in app units, that is
    *        used by absolute positioning code to override default containing
    *        block height.
    * @param aFlags A set of flags used for additional boolean parameters (see
    *        below).
    */
-  nsHTMLReflowState(nsPresContext*           aPresContext,
-                    const nsHTMLReflowState& aParentReflowState,
-                    nsIFrame*                aFrame,
-                    const nsSize&            aAvailableSpace,
-                    nscoord                  aContainingBlockWidth = -1,
-                    nscoord                  aContainingBlockHeight = -1,
-                    uint32_t                 aFlags = 0);
+  nsHTMLReflowState(nsPresContext*              aPresContext,
+                    const nsHTMLReflowState&    aParentReflowState,
+                    nsIFrame*                   aFrame,
+                    const mozilla::LogicalSize& aAvailableSpace,
+                    nscoord                     aContainingBlockWidth = -1,
+                    nscoord                     aContainingBlockHeight = -1,
+                    uint32_t                    aFlags = 0);
 
   // Values for |aFlags| passed to constructor
   enum {
     // Indicates that the parent of this reflow state is "fake" (see
     // mDummyParentReflowState in mFlags).
     DUMMY_PARENT_REFLOW_STATE = (1<<0),
 
     // Indicates that the calling function will initialize the reflow state, and
     // that the constructor should not call Init().
     CALLER_WILL_INIT = (1<<1)
   };
 
   // This method initializes various data members. It is automatically
   // called by the various constructors
   void Init(nsPresContext* aPresContext,
-            nscoord         aContainingBlockWidth = -1,
-            nscoord         aContainingBlockHeight = -1,
+            nscoord         aContainingBlockISize = -1,
+            nscoord         aContainingBlockBSize = -1,
             const nsMargin* aBorder = nullptr,
             const nsMargin* aPadding = nullptr);
   /**
    * Find the content width of the containing block of aReflowState
    */
   static nscoord
     GetContainingBlockContentWidth(const nsHTMLReflowState* aReflowState);
 
@@ -607,16 +678,32 @@ public:
   }
 
   // This method doesn't apply min/max computed widths to the value passed in.
   void SetComputedWidth(nscoord aComputedWidth);
 
   // This method doesn't apply min/max computed heights to the value passed in.
   void SetComputedHeight(nscoord aComputedHeight);
 
+  void SetComputedISize(nscoord aComputedISize) {
+    if (mWritingMode.IsVertical()) {
+      SetComputedHeight(aComputedISize);
+    } else {
+      SetComputedWidth(aComputedISize);
+    }
+  }
+
+  void SetComputedBSize(nscoord aComputedBSize) {
+    if (mWritingMode.IsVertical()) {
+      SetComputedWidth(aComputedBSize);
+    } else {
+      SetComputedHeight(aComputedBSize);
+    }
+  }
+
   void SetComputedHeightWithoutResettingResizeFlags(nscoord aComputedHeight) {
     // Viewport frames reset the computed height on a copy of their reflow
     // state when reflowing fixed-pos kids.  In that case we actually don't
     // want to mess with the resize flags, because comparing the frame's rect
     // to the munged computed width is pointless.
     ComputedHeight() = aComputedHeight;
   }
 
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -783,20 +783,18 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra
   nscoord availableSpaceOnLine = psd->mIEnd - psd->mICoord;
 
   // Setup reflow state for reflowing the frame
   Maybe<nsHTMLReflowState> reflowStateHolder;
   if (!isText) {
     // Compute the available size for the frame. This available width
     // includes room for the side margins.
     // For now, set the available block-size to unconstrained always.
-    nsSize availSize =
-      LogicalSize(mBlockReflowState->GetWritingMode(),
-                  mBlockReflowState->ComputedISize(), NS_UNCONSTRAINEDSIZE).
-        GetPhysicalSize(mBlockReflowState->GetWritingMode());
+    LogicalSize availSize = mBlockReflowState->ComputedSize(frameWM);
+    availSize.BSize(frameWM) = NS_UNCONSTRAINEDSIZE;
     reflowStateHolder.construct(mPresContext, *psd->mReflowState,
                                 aFrame, availSize);
     nsHTMLReflowState& reflowState = reflowStateHolder.ref();
     reflowState.mLineLayout = this;
     reflowState.mFlags.mIsTopOfPage = mIsTopOfPage;
     if (reflowState.ComputedWidth() == NS_UNCONSTRAINEDSIZE)
       reflowState.AvailableWidth() = availableSpaceOnLine;
     WritingMode stateWM = reflowState.GetWritingMode();
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -4,16 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "nsPageContentFrame.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsPresContext.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsSimplePageSequenceFrame.h"
 
+using mozilla::LogicalSize;
+using mozilla::WritingMode;
+
 nsPageContentFrame*
 NS_NewPageContentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsPageContentFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsPageContentFrame)
 
@@ -42,18 +45,21 @@ nsPageContentFrame::Reflow(nsPresContext
                   aReflowState.ComputedHeight());
   SetSize(maxSize);
  
   // A PageContentFrame must always have one child: the canvas frame.
   // Resize our frame allowing it only to be as big as we are
   // XXX Pay attention to the page's border and padding...
   if (mFrames.NotEmpty()) {
     nsIFrame* frame = mFrames.FirstChild();
-    nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize);
-    kidReflowState.SetComputedHeight(maxSize.height);
+    WritingMode wm = frame->GetWritingMode();
+    LogicalSize logicalSize(wm, maxSize);
+    nsHTMLReflowState kidReflowState(aPresContext, aReflowState,
+                                     frame, logicalSize);
+    kidReflowState.SetComputedBSize(logicalSize.BSize(wm));
 
     // Reflow the page content area
     ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
 
     // The document element's background should cover the entire canvas, so
     // take into account the combined area and any space taken up by
     // absolutely positioned elements
     nsMargin padding(0,0,0,0);
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -83,17 +83,19 @@ nsPageFrame::Reflow(nsPresContext*      
     //     are set?
     if (maxSize.width < onePixelInTwips || maxSize.height < onePixelInTwips) {
       aDesiredSize.Width() = 0;
       aDesiredSize.Height() = 0;
       NS_WARNING("Reflow aborted; no space for content");
       return;
     }
 
-    nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize);
+    nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame,
+                                     LogicalSize(frame->GetWritingMode(),
+                                                 maxSize));
     kidReflowState.mFlags.mIsTopOfPage = true;
     kidReflowState.mFlags.mTableIsSplittable = true;
 
     // Use the margins given in the @page rule.
     // If a margin is 'auto', use the margin from the print settings for that side.
     nsMargin pageContentMargin;
     const nsStyleSides& marginStyle = kidReflowState.mStyleMargin->mMargin;
     NS_FOR_CSS_SIDES(side) {
--- a/layout/generic/nsSimplePageSequenceFrame.cpp
+++ b/layout/generic/nsSimplePageSequenceFrame.cpp
@@ -203,17 +203,18 @@ nsSimplePageSequenceFrame::Reflow(nsPres
   nsHTMLReflowMetrics kidSize(aReflowState);
   for (nsIFrame* kidFrame = mFrames.FirstChild(); nullptr != kidFrame; ) {
     // Set the shared data into the page frame before reflow
     nsPageFrame * pf = static_cast<nsPageFrame*>(kidFrame);
     pf->SetSharedPageData(mPageData);
 
     // Reflow the page
     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
-                                     pageSize);
+                                     LogicalSize(kidFrame->GetWritingMode(),
+                                                 pageSize));
     nsReflowStatus  status;
 
     kidReflowState.SetComputedWidth(kidReflowState.AvailableWidth());
     //kidReflowState.SetComputedHeight(kidReflowState.AvailableHeight());
     PR_PL(("AV W: %d   H: %d\n", kidReflowState.AvailableWidth(), kidReflowState.AvailableHeight()));
 
     nsMargin pageCSSMargin = kidReflowState.ComputedPhysicalMargin();
     y += pageCSSMargin.top;
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -266,18 +266,18 @@ nsVideoFrame::Reflow(nsPresContext*     
   // which is the poster, and a box frame, which is the video controls.
   for (nsIFrame *child = mFrames.FirstChild();
        child;
        child = child->GetNextSibling()) {
     if (child->GetContent() == mPosterImage) {
       // Reflow the poster frame.
       nsImageFrame* imageFrame = static_cast<nsImageFrame*>(child);
       nsHTMLReflowMetrics kidDesiredSize(aReflowState);
-      nsSize availableSize = nsSize(aReflowState.AvailableWidth(),
-                                    aReflowState.AvailableHeight());
+      WritingMode wm = imageFrame->GetWritingMode();
+      LogicalSize availableSize = aReflowState.AvailableSize(wm);
       nsHTMLReflowState kidReflowState(aPresContext,
                                        aReflowState,
                                        imageFrame,
                                        availableSize,
                                        aMetrics.Width(),
                                        aMetrics.Height());
 
       uint32_t posterHeight, posterWidth;
@@ -321,18 +321,18 @@ nsVideoFrame::Reflow(nsPresContext*     
                                        aReflowState.ComputedHeight()));
       if (child->GetSize() != size) {
         nsRefPtr<nsRunnable> event = new DispatchResizeToControls(child->GetContent());
         nsContentUtils::AddScriptRunner(event);
       }
     } else if (child->GetContent() == mCaptionDiv) {
       // Reflow to caption div
       nsHTMLReflowMetrics kidDesiredSize(aReflowState);
-      nsSize availableSize = nsSize(aReflowState.AvailableWidth(),
-                                    aReflowState.AvailableHeight());
+      WritingMode wm = child->GetWritingMode();
+      LogicalSize availableSize = aReflowState.AvailableSize(wm);
       nsHTMLReflowState kidReflowState(aPresContext,
                                        aReflowState,
                                        child,
                                        availableSize,
                                        aMetrics.Width(),
                                        aMetrics.Height());
       nsSize size(aReflowState.ComputedWidth(), aReflowState.ComputedHeight());
       size.width -= kidReflowState.ComputedPhysicalBorderPadding().LeftRight();
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -200,18 +200,18 @@ ViewportFrame::Reflow(nsPresContext*    
     // 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
       nsIFrame*           kidFrame = mFrames.FirstChild();
       nsHTMLReflowMetrics kidDesiredSize(aReflowState);
-      nsSize              availableSpace(aReflowState.AvailableWidth(),
-                                         aReflowState.AvailableHeight());
+      WritingMode         wm = kidFrame->GetWritingMode();
+      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();
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -880,21 +880,23 @@ nsMathMLContainerFrame::Reflow(nsPresCon
   aDesiredSize.SetBlockStartAscent(0);
   aDesiredSize.mBoundingMetrics = nsBoundingMetrics();
 
   /////////////
   // Reflow children
   // Asking each child to cache its bounding metrics
 
   nsReflowStatus childStatus;
-  nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
   nsIFrame* childFrame = mFrames.FirstChild();
   while (childFrame) {
     nsHTMLReflowMetrics childDesiredSize(aReflowState, // ???
                                          aDesiredSize.mFlags);
+    WritingMode wm = childFrame->GetWritingMode();
+    LogicalSize availSize = aReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     nsHTMLReflowState childReflowState(aPresContext, aReflowState,
                                        childFrame, availSize);
     ReflowChild(childFrame, aPresContext, childDesiredSize,
                 childReflowState, childStatus);
     //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
     SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
                                     childDesiredSize.mBoundingMetrics);
     childFrame = childFrame->GetNextSibling();
--- a/layout/mathml/nsMathMLSelectedFrame.cpp
+++ b/layout/mathml/nsMathMLSelectedFrame.cpp
@@ -1,16 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #include "nsMathMLSelectedFrame.h"
 #include "nsDisplayList.h"
 
+using namespace mozilla;
+
 nsMathMLSelectedFrame::~nsMathMLSelectedFrame()
 {
 }
 
 void
 nsMathMLSelectedFrame::Init(nsIContent*       aContent,
                             nsContainerFrame* aParent,
                             nsIFrame*         aPrevInFlow)
@@ -104,17 +106,19 @@ nsMathMLSelectedFrame::Reflow(nsPresCont
                               nsReflowStatus&          aStatus)
 {
   aStatus = NS_FRAME_COMPLETE;
   aDesiredSize.Width() = aDesiredSize.Height() = 0;
   aDesiredSize.SetBlockStartAscent(0);
   mBoundingMetrics = nsBoundingMetrics();
   nsIFrame* childFrame = GetSelectedFrame();
   if (childFrame) {
-    nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
+    WritingMode wm = childFrame->GetWritingMode();
+    LogicalSize availSize = aReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     nsHTMLReflowState childReflowState(aPresContext, aReflowState,
                                        childFrame, availSize);
     ReflowChild(childFrame, aPresContext, aDesiredSize,
                 childReflowState, aStatus);
     SaveReflowAndBoundingMetricsFor(childFrame, aDesiredSize,
                                     aDesiredSize.mBoundingMetrics);
     mBoundingMetrics = aDesiredSize.mBoundingMetrics;
   }
--- a/layout/mathml/nsMathMLTokenFrame.cpp
+++ b/layout/mathml/nsMathMLTokenFrame.cpp
@@ -5,16 +5,18 @@
 
 #include "nsMathMLTokenFrame.h"
 #include "nsPresContext.h"
 #include "nsContentUtils.h"
 #include "nsTextFrame.h"
 #include "RestyleManager.h"
 #include <algorithm>
 
+using namespace mozilla;
+
 nsIFrame*
 NS_NewMathMLTokenFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLTokenFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLTokenFrame)
 
@@ -124,23 +126,25 @@ nsMathMLTokenFrame::Reflow(nsPresContext
                            const nsHTMLReflowState& aReflowState,
                            nsReflowStatus&          aStatus)
 {
   // initializations needed for empty markup like <mtag></mtag>
   aDesiredSize.Width() = aDesiredSize.Height() = 0;
   aDesiredSize.SetBlockStartAscent(0);
   aDesiredSize.mBoundingMetrics = nsBoundingMetrics();
 
-  nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
   nsIFrame* childFrame = GetFirstPrincipalChild();
   while (childFrame) {
     // ask our children to compute their bounding metrics
     nsHTMLReflowMetrics childDesiredSize(aReflowState.GetWritingMode(),
                                          aDesiredSize.mFlags
                                          | NS_REFLOW_CALC_BOUNDING_METRICS);
+    WritingMode wm = childFrame->GetWritingMode();
+    LogicalSize availSize = aReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     nsHTMLReflowState childReflowState(aPresContext, aReflowState,
                                        childFrame, availSize);
     ReflowChild(childFrame, aPresContext, childDesiredSize,
                 childReflowState, aStatus);
     //NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
     SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
                                     childDesiredSize.mBoundingMetrics);
 
--- a/layout/mathml/nsMathMLmfencedFrame.cpp
+++ b/layout/mathml/nsMathMLmfencedFrame.cpp
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #include "nsMathMLmfencedFrame.h"
 #include "nsRenderingContext.h"
 #include "nsMathMLChar.h"
 #include <algorithm>
 
+using namespace mozilla;
+
 //
 // <mfenced> -- surround content with a pair of fences
 //
 
 nsIFrame*
 NS_NewMathMLmfencedFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmfencedFrame(aContext);
@@ -211,41 +213,43 @@ nsMathMLmfencedFrame::Reflow(nsPresConte
   // because we want to stretch our fences, separators and stretchy frames using
   // the *same* initial aDesiredSize.mBoundingMetrics. If we were to use the base
   // method here, our stretchy frames will be stretched and placed, and we may
   // end up stretching our fences/separators with a different aDesiredSize.
   // XXX The above decision was revisited in bug 121748 and this code can be
   // refactored to use nsMathMLContainerFrame::Reflow() at some stage.
 
   nsReflowStatus childStatus;
-  nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
   nsIFrame* firstChild = GetFirstPrincipalChild();
   nsIFrame* childFrame = firstChild;
   nscoord ascent = 0, descent = 0;
   if (firstChild || mOpenChar || mCloseChar || mSeparatorsCount > 0) {
     // We use the ASCII metrics to get our minimum height. This way,
     // if we have borders or a background, they will fit better with
     // other elements on the line.
     ascent = fm->MaxAscent();
     descent = fm->MaxDescent();
   }
   while (childFrame) {
     nsHTMLReflowMetrics childDesiredSize(aReflowState,
                                          aDesiredSize.mFlags
                                          | NS_REFLOW_CALC_BOUNDING_METRICS);
+    WritingMode wm = childFrame->GetWritingMode();
+    LogicalSize availSize = aReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     nsHTMLReflowState childReflowState(aPresContext, aReflowState,
                                        childFrame, availSize);
     ReflowChild(childFrame, aPresContext, childDesiredSize,
                 childReflowState, childStatus);
     //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
     SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
                                     childDesiredSize.mBoundingMetrics);
 
-    mozilla::WritingMode wm = aReflowState.GetWritingMode();
-    nscoord childDescent = childDesiredSize.BSize(wm) -
+    mozilla::WritingMode outerWM = aReflowState.GetWritingMode();
+    nscoord childDescent = childDesiredSize.BSize(outerWM) -
                            childDesiredSize.BlockStartAscent();
     if (descent < childDescent)
       descent = childDescent;
     if (ascent < childDesiredSize.BlockStartAscent())
       ascent = childDesiredSize.BlockStartAscent();
 
     childFrame = childFrame->GetNextSibling();
   }
--- a/layout/mathml/nsMathMLmrootFrame.cpp
+++ b/layout/mathml/nsMathMLmrootFrame.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/. */
 
 #include "nsMathMLmrootFrame.h"
 #include "nsPresContext.h"
 #include "nsRenderingContext.h"
 #include <algorithm>
 
+using namespace mozilla;
+
 //
 // <mroot> -- form a radical - implementation
 //
 
 // additional style context to be used by our MathMLChar.
 #define NS_SQR_CHAR_STYLE_CONTEXT_INDEX   0
 
 static const char16_t kSqrChar = char16_t(0x221A);
@@ -157,17 +159,16 @@ nsMathMLmrootFrame::GetRadicalXOffsets(n
 }
 
 void
 nsMathMLmrootFrame::Reflow(nsPresContext*          aPresContext,
                            nsHTMLReflowMetrics&     aDesiredSize,
                            const nsHTMLReflowState& aReflowState,
                            nsReflowStatus&          aStatus)
 {
-  nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
   nsReflowStatus childStatus;
 
   aDesiredSize.Width() = aDesiredSize.Height() = 0;
   aDesiredSize.SetBlockStartAscent(0);
 
   nsBoundingMetrics bmSqr, bmBase, bmIndex;
   nsRenderingContext& renderingContext = *aReflowState.rendContext;
 
@@ -180,16 +181,19 @@ nsMathMLmrootFrame::Reflow(nsPresContext
   nsHTMLReflowMetrics baseSize(aReflowState);
   nsHTMLReflowMetrics indexSize(aReflowState);
   nsIFrame* childFrame = mFrames.FirstChild();
   while (childFrame) {
     // ask our children to compute their bounding metrics 
     nsHTMLReflowMetrics childDesiredSize(aReflowState,
                                          aDesiredSize.mFlags
                                          | NS_REFLOW_CALC_BOUNDING_METRICS);
+    WritingMode wm = childFrame->GetWritingMode();
+    LogicalSize availSize = aReflowState.ComputedSize(wm);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     nsHTMLReflowState childReflowState(aPresContext, aReflowState,
                                        childFrame, availSize);
     ReflowChild(childFrame, aPresContext,
                      childDesiredSize, childReflowState, childStatus);
     //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
     if (0 == count) {
       // base 
       baseFrame = childFrame;
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -5201,20 +5201,22 @@ SVGTextFrame::DoReflow()
   if (UpdateFontSizeScaleFactor()) {
     // If the font size scale factor changed, we need the block to report
     // an updated preferred width.
     kid->MarkIntrinsicWidthsDirty();
   }
 
   mState |= NS_STATE_SVG_TEXT_IN_REFLOW;
 
-  nscoord width = kid->GetPrefWidth(renderingContext);
+  //XXX GetPrefWidth will become GetInlineSize
+  nscoord inlineSize = kid->GetPrefWidth(renderingContext);
   nsHTMLReflowState reflowState(presContext, kid,
                                 renderingContext,
-                                nsSize(width, NS_UNCONSTRAINEDSIZE));
+                                LogicalSize(kid->GetWritingMode(),
+                                            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");
 
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -546,19 +546,21 @@ nsSVGForeignObjectFrame::DoReflow()
     return;
 
   // initiate a synchronous reflow here and now:  
   nsRefPtr<nsRenderingContext> renderingContext =
     presContext->PresShell()->CreateReferenceRenderingContext();
 
   mInReflow = true;
 
+  WritingMode wm = kid->GetWritingMode();
   nsHTMLReflowState reflowState(presContext, kid,
                                 renderingContext,
-                                nsSize(mRect.width, NS_UNCONSTRAINEDSIZE));
+                                LogicalSize(wm, GetLogicalSize(wm).ISize(wm),
+                                            NS_UNCONSTRAINEDSIZE));
   nsHTMLReflowMetrics desiredSize(reflowState);
   nsReflowStatus status;
 
   // We don't use mRect.height above because that tells the child to do
   // page/column breaking at that height.
   NS_ASSERTION(reflowState.ComputedPhysicalBorderPadding() == nsMargin(0, 0, 0, 0) &&
                reflowState.ComputedPhysicalMargin() == nsMargin(0, 0, 0, 0),
                "style system should ensure that :-moz-svg-foreign-content "
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -903,17 +903,18 @@ nsTableCellFrame::Reflow(nsPresContext* 
       DISPLAY_REFLOW_CHANGE();
     }
   }
   else {
     SetHasPctOverHeight(false);
   }
 
   nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstKid,
-                                   availSize);
+                                   LogicalSize(firstKid->GetWritingMode(),
+                                               availSize));
 
   // Don't be a percent height observer if we're in the middle of
   // special-height reflow, in case we get an accidental NotifyPercentHeight()
   // call (which we shouldn't honor during special-height reflow)
   if (!aReflowState.mFlags.mSpecialHeightReflow) {
     // mPercentHeightObserver is for children of cells in quirks mode,
     // but only those than are tables in standards mode.  NeedsToObserve
     // will determine how far this is propagated to descendants.
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -367,17 +367,17 @@ nsTableColGroupFrame::Reflow(nsPresConte
   // for every content child that (is a column thingy and does not already have a frame)
   // create a frame and adjust it's style
   
   for (nsIFrame *kidFrame = mFrames.FirstChild(); kidFrame;
        kidFrame = kidFrame->GetNextSibling()) {
     // Give the child frame a chance to reflow, even though we know it'll have 0 size
     nsHTMLReflowMetrics kidSize(aReflowState);
     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
-                                     nsSize(0,0));
+                                     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;
@@ -517,8 +517,9 @@ void nsTableColGroupFrame::Dump(int32_t 
     j++;
   }
   NS_ASSERTION((j - GetStartColumnIndex()) == GetColCount(),
                "number of cols out of sync");
   printf("\n%s**END COLGROUP DUMP** ", indent);
   delete [] indent;
 }
 #endif
+
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1922,19 +1922,21 @@ nsTableFrame::FixupPositionedTableParts(
     desiredSize.Width() = size.width;
     desiredSize.Height() = size.height;
     desiredSize.mOverflowAreas = positionedPart->GetOverflowAreasRelativeToSelf();
 
     // Construct a dummy reflow state and reflow status.
     // XXX(seth): Note that the dummy reflow state doesn't have a correct
     // chain of parent reflow states. It also doesn't necessarily have a
     // correct containing block.
+    WritingMode wm = positionedPart->GetWritingMode();
+    LogicalSize availSize(wm, size);
+    availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     nsHTMLReflowState reflowState(aPresContext, positionedPart,
-                                  aReflowState.rendContext,
-                                  nsSize(size.width, NS_UNCONSTRAINEDSIZE),
+                                  aReflowState.rendContext, availSize,
                                   nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
     nsReflowStatus reflowStatus = NS_FRAME_COMPLETE;
 
     // Reflow absolutely-positioned descendants of the positioned part.
     // FIXME: Unconditionally using NS_UNCONSTRAINEDSIZE for the height and
     // ignoring any change to the reflow status aren't correct. We'll never
     // paginate absolutely positioned frames.
     overflowTracker.AddFrame(positionedPart,
@@ -2789,20 +2791,22 @@ IsRepeatable(nscoord aFrameHeight, nscoo
 nsresult
 nsTableFrame::SetupHeaderFooterChild(const nsTableReflowState& aReflowState,
                                      nsTableRowGroupFrame* aFrame,
                                      nscoord* aDesiredHeight)
 {
   nsPresContext* presContext = PresContext();
   nscoord pageHeight = presContext->GetPageSize().height;
 
-  // Reflow the child with unconstrainted height
+  // Reflow the child with unconstrained height
+  WritingMode wm = aFrame->GetWritingMode();
+  LogicalSize availSize = aReflowState.reflowState.AvailableSize(wm);
+  availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
   nsHTMLReflowState kidReflowState(presContext, aReflowState.reflowState,
-                                   aFrame,
-                                   nsSize(aReflowState.availSize.width, NS_UNCONSTRAINEDSIZE),
+                                   aFrame, availSize,
                                    -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
   InitChildReflowState(kidReflowState);
   kidReflowState.mFlags.mIsTopOfPage = true;
   nsHTMLReflowMetrics desiredSize(aReflowState.reflowState);
   desiredSize.Width() = desiredSize.Height() = 0;
   nsReflowStatus status;
   ReflowChild(aFrame, presContext, desiredSize, kidReflowState,
               aReflowState.x, aReflowState.y, 0, status);
@@ -2814,22 +2818,22 @@ nsTableFrame::SetupHeaderFooterChild(con
 }
 
 void 
 nsTableFrame::PlaceRepeatedFooter(nsTableReflowState& aReflowState,
                                   nsTableRowGroupFrame *aTfoot,
                                   nscoord aFooterHeight)
 {
   nsPresContext* presContext = PresContext();
-  nsSize kidAvailSize(aReflowState.availSize);
-  kidAvailSize.height = aFooterHeight;
+  WritingMode wm = aTfoot->GetWritingMode();
+  LogicalSize kidAvailSize(wm, aReflowState.availSize);
+  kidAvailSize.BSize(wm) = aFooterHeight;
   nsHTMLReflowState footerReflowState(presContext,
                                       aReflowState.reflowState,
-                                      aTfoot,
-                                      kidAvailSize,
+                                      aTfoot, kidAvailSize,
                                       -1, -1,
                                       nsHTMLReflowState::CALLER_WILL_INIT);
   InitChildReflowState(footerReflowState);
   aReflowState.y += GetCellSpacingY(GetRowCount());
 
   nsRect origTfootRect = aTfoot->GetRect();
   nsRect origTfootVisualOverflow = aTfoot->GetVisualOverflowRect();
           
@@ -2941,17 +2945,19 @@ nsTableFrame::ReflowChildren(nsTableRefl
       nsRect oldKidRect = kidFrame->GetRect();
       nsRect oldKidVisualOverflow = kidFrame->GetVisualOverflowRect();
 
       nsHTMLReflowMetrics desiredSize(aReflowState.reflowState);
       desiredSize.Width() = desiredSize.Height() = 0;
 
       // Reflow the child into the available space
       nsHTMLReflowState kidReflowState(presContext, aReflowState.reflowState,
-                                       kidFrame, kidAvailSize,
+                                       kidFrame,
+                                       LogicalSize(kidFrame->GetWritingMode(),
+                                                   kidAvailSize),
                                        -1, -1,
                                        nsHTMLReflowState::CALLER_WILL_INIT);
       InitChildReflowState(kidReflowState);
 
       // If this isn't the first row group, and the previous row group has a
       // nonzero YMost, then we can't be at the top of the page.
       // We ignore a repeated head row group in this check to avoid causing
       // infinite loops in some circumstances - see bug 344883.
@@ -3133,18 +3139,19 @@ nsTableFrame::ReflowColGroups(nsRenderin
 {
   if (!GetPrevInFlow() && !HaveReflowedColGroups()) {
     nsHTMLReflowMetrics kidMet(GetWritingMode());
     nsPresContext *presContext = PresContext();
     for (nsIFrame* kidFrame = mColGroups.FirstChild(); kidFrame;
          kidFrame = kidFrame->GetNextSibling()) {
       if (NS_SUBTREE_DIRTY(kidFrame)) {
         // The column groups don't care about dimensions or reflow states.
-        nsHTMLReflowState kidReflowState(presContext, kidFrame,
-                                       aRenderingContext, nsSize(0,0));
+        nsHTMLReflowState
+          kidReflowState(presContext, kidFrame, aRenderingContext,
+                         LogicalSize(kidFrame->GetWritingMode()));
         nsReflowStatus cgStatus;
         ReflowChild(kidFrame, presContext, kidMet, kidReflowState, 0, 0, 0,
                     cgStatus);
         FinishReflowChild(kidFrame, presContext, kidMet, nullptr, 0, 0, 0);
       }
     }
     SetHaveReflowedColGroups(true);
   }
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -351,30 +351,31 @@ nsTableOuterFrame::InitChildReflowState(
 }
 
 // get the margin and padding data. nsHTMLReflowState doesn't handle the
 // case of auto margins
 void
 nsTableOuterFrame::GetChildMargin(nsPresContext*           aPresContext,
                                   const nsHTMLReflowState& aOuterRS,
                                   nsIFrame*                aChildFrame,
-                                  nscoord                  aAvailWidth,
-                                  nsMargin&                aMargin)
+                                  nscoord                  aAvailISize,
+                                  LogicalMargin&           aMargin)
 {
   // construct a reflow state to compute margin and padding. Auto margins
   // will not be computed at this time.
 
   // create and init the child reflow state
   // XXX We really shouldn't construct a reflow state to do this.
-  nsHTMLReflowState childRS(aPresContext, aOuterRS, aChildFrame,
-                            nsSize(aAvailWidth, aOuterRS.AvailableHeight()),
+  WritingMode wm = aChildFrame->GetWritingMode();
+  LogicalSize availSize(wm, aAvailISize, aOuterRS.AvailableSize(wm).BSize(wm));
+  nsHTMLReflowState childRS(aPresContext, aOuterRS, aChildFrame, availSize,
                             -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
   InitChildReflowState(*aPresContext, childRS);
 
-  aMargin = childRS.ComputedPhysicalMargin();
+  aMargin = childRS.ComputedLogicalMargin();
 }
 
 static nsSize
 GetContainingBlockSize(const nsHTMLReflowState& aOuterRS)
 {
   nsSize size(0,0);
   const nsHTMLReflowState* containRS =
     aOuterRS.mCBReflowState;
@@ -778,36 +779,40 @@ nsTableOuterFrame::GetInnerOrigin(uint32
   return NS_OK;
 }
 
 void
 nsTableOuterFrame::OuterBeginReflowChild(nsPresContext*           aPresContext,
                                          nsIFrame*                aChildFrame,
                                          const nsHTMLReflowState& aOuterRS,
                                          void*                    aChildRSSpace,
-                                         nscoord                  aAvailWidth)
-{ 
+                                         nscoord                  aAvailISize)
+{
   // work around pixel rounding errors, round down to ensure we don't exceed the avail height in
-  nscoord availHeight = aOuterRS.AvailableHeight();
-  if (NS_UNCONSTRAINEDSIZE != availHeight) {
+  WritingMode wm = aChildFrame->GetWritingMode();
+  LogicalSize outerSize = aOuterRS.AvailableSize(wm);
+  nscoord availBSize = outerSize.BSize(wm);
+  if (NS_UNCONSTRAINEDSIZE != availBSize) {
     if (mCaptionFrames.FirstChild() == aChildFrame) {
-      availHeight = NS_UNCONSTRAINEDSIZE;
+      availBSize = NS_UNCONSTRAINEDSIZE;
     } else {
-      nsMargin margin;
+      LogicalMargin margin(wm);
       GetChildMargin(aPresContext, aOuterRS, aChildFrame,
-                     aOuterRS.AvailableWidth(), margin);
-    
-      NS_ASSERTION(NS_UNCONSTRAINEDSIZE != margin.top, "No unconstrainedsize arithmetic, please");
-      availHeight -= margin.top;
- 
-      NS_ASSERTION(NS_UNCONSTRAINEDSIZE != margin.bottom, "No unconstrainedsize arithmetic, please");
-      availHeight -= margin.bottom;
+                     outerSize.ISize(wm), margin);
+
+      NS_ASSERTION(NS_UNCONSTRAINEDSIZE != margin.BStart(wm),
+                   "No unconstrainedsize arithmetic, please");
+      availBSize -= margin.BStart(wm);
+
+      NS_ASSERTION(NS_UNCONSTRAINEDSIZE != margin.BEnd(wm),
+                   "No unconstrainedsize arithmetic, please");
+      availBSize -= margin.BEnd(wm);
     }
   }
-  nsSize availSize(aAvailWidth, availHeight);
+  LogicalSize availSize(wm, aAvailISize, availBSize);
   // create and init the child reflow state, using placement new on
   // stack space allocated by the caller, so that the caller can destroy
   // it
   nsHTMLReflowState &childRS = * new (aChildRSSpace)
     nsHTMLReflowState(aPresContext, aOuterRS, aChildFrame, availSize,
                       -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
   InitChildReflowState(*aPresContext, childRS);
 
@@ -905,63 +910,68 @@ nsTableOuterFrame::Reflow(nsPresContext*
     origCaptionRect = mCaptionFrames.FirstChild()->GetRect();
     origCaptionVisualOverflow =
       mCaptionFrames.FirstChild()->GetVisualOverflowRect();
     captionFirstReflow =
       (mCaptionFrames.FirstChild()->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
   }
   
   // ComputeAutoSize has to match this logic.
+  WritingMode wm;
   if (captionSide == NO_SIDE) {
     // We don't have a caption.
+    wm = InnerTableFrame()->GetWritingMode();
     OuterBeginReflowChild(aPresContext, InnerTableFrame(), aOuterRS,
-                          innerRSSpace, aOuterRS.ComputedWidth());
+                          innerRSSpace, aOuterRS.ComputedSize(wm).ISize(wm));
   } else if (captionSide == NS_STYLE_CAPTION_SIDE_LEFT ||
              captionSide == NS_STYLE_CAPTION_SIDE_RIGHT) {
     // nsTableCaptionFrame::ComputeAutoSize takes care of making side
     // captions small.  Compute the caption's size first, and tell the
     // table to fit in what's left.
+    wm = mCaptionFrames.FirstChild()->GetWritingMode();
     OuterBeginReflowChild(aPresContext, mCaptionFrames.FirstChild(), aOuterRS,
-                          captionRSSpace, aOuterRS.ComputedWidth());
-    nscoord innerAvailWidth = aOuterRS.ComputedWidth() -
-      (captionRS->ComputedWidth() + captionRS->ComputedPhysicalMargin().LeftRight() +
-       captionRS->ComputedPhysicalBorderPadding().LeftRight());
+                          captionRSSpace, aOuterRS.ComputedSize(wm).ISize(wm));
+    nscoord innerAvailISize = aOuterRS.ComputedSize(wm).ISize(wm) -
+      captionRS->ComputedSizeWithMarginBorderPadding(wm).ISize(wm);
     OuterBeginReflowChild(aPresContext, InnerTableFrame(), aOuterRS,
-                          innerRSSpace, innerAvailWidth);
+                          innerRSSpace, innerAvailISize);
 
   } else if (captionSide == NS_STYLE_CAPTION_SIDE_TOP ||
              captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM) {
     // Compute the table's size first, and then prevent the caption from
     // being wider unless it has to be.
     //
     // Note that CSS 2.1 (but not 2.0) says:
     //   The width of the anonymous box is the border-edge width of the
     //   table box inside it
     // We don't actually make our anonymous box that width (if we did,
     // it would break 'auto' margins), but this effectively does that.
+    wm = InnerTableFrame()->GetWritingMode();
     OuterBeginReflowChild(aPresContext, InnerTableFrame(), aOuterRS,
-                          innerRSSpace, aOuterRS.ComputedWidth());
+                          innerRSSpace, aOuterRS.ComputedSize(wm).ISize(wm));
     // It's good that CSS 2.1 says not to include margins, since we
     // can't, since they already been converted so they exactly
     // fill the available width (ignoring the margin on one side if
     // neither are auto).  (We take advantage of that later when we call
     // GetCaptionOrigin, though.)
-    nscoord innerBorderWidth = innerRS->ComputedWidth() +
-                               innerRS->ComputedPhysicalBorderPadding().LeftRight();
+    nscoord innerBorderWidth =
+      innerRS->ComputedSizeWithBorderPadding(wm).ISize(wm);
     OuterBeginReflowChild(aPresContext, mCaptionFrames.FirstChild(), aOuterRS,
                           captionRSSpace, innerBorderWidth);
   } else {
     NS_ASSERTION(captionSide == NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE ||
                  captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE,
                  "unexpected caption-side");
     // Size the table and the caption independently.
+    wm = mCaptionFrames.FirstChild()->GetWritingMode();
     OuterBeginReflowChild(aPresContext, mCaptionFrames.FirstChild(), aOuterRS,
-                          captionRSSpace, aOuterRS.ComputedWidth());
+                          captionRSSpace, aOuterRS.ComputedSize(wm).ISize(wm));
+    wm = InnerTableFrame()->GetWritingMode();
     OuterBeginReflowChild(aPresContext, InnerTableFrame(), aOuterRS,
-                          innerRSSpace, aOuterRS.ComputedWidth());
+                          innerRSSpace, aOuterRS.ComputedSize(wm).ISize(wm));
   }
 
   // First reflow the caption.
   nsHTMLReflowMetrics captionMet(captionRS->GetWritingMode());
   nsSize captionSize;
   nsMargin captionMargin;
   if (mCaptionFrames.NotEmpty()) {
     nsReflowStatus capStatus; // don't let the caption cause incomplete
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -245,17 +245,17 @@ protected:
                             nsMargin&        aInnerMargin,
                             nsPoint&         aOrigin);
   
   // reflow the child (caption or innertable frame)
   void OuterBeginReflowChild(nsPresContext*           aPresContext,
                              nsIFrame*                aChildFrame,
                              const nsHTMLReflowState& aOuterRS,
                              void*                    aChildRSSpace,
-                             nscoord                  aAvailWidth);
+                             nscoord                  aAvailISize);
 
   void OuterDoReflowChild(nsPresContext*           aPresContext,
                           nsIFrame*                aChildFrame,
                           const nsHTMLReflowState& aChildRS,
                           nsHTMLReflowMetrics&     aMetrics,
                           nsReflowStatus&          aStatus);
 
   // Set the reflow metrics
@@ -265,17 +265,17 @@ protected:
                            const nsMargin&      aCaptionMargin);
 
   // Get the margin.  aMarginNoAuto is aMargin, but with auto 
   // margins set to 0
   void GetChildMargin(nsPresContext*           aPresContext,
                       const nsHTMLReflowState& aOuterRS,
                       nsIFrame*                aChildFrame,
                       nscoord                  aAvailableWidth,
-                      nsMargin&                aMargin);
+                      mozilla::LogicalMargin&  aMargin);
 
   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags &
                                            (~eCanContainOverflowContainers));
   }
 
   nsTableFrame* InnerTableFrame() const {
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -23,17 +23,17 @@
 
 using namespace mozilla;
 
 struct nsTableCellReflowState : public nsHTMLReflowState
 {
   nsTableCellReflowState(nsPresContext*           aPresContext,
                          const nsHTMLReflowState& aParentReflowState,
                          nsIFrame*                aFrame,
-                         const nsSize&            aAvailableSpace,
+                         const LogicalSize&       aAvailableSpace,
                          uint32_t                 aFlags = 0)
     : nsHTMLReflowState(aPresContext, aParentReflowState, aFrame,
                         aAvailableSpace, -1, -1, aFlags)
   {
   }
 
   void FixUp(const nsSize& aAvailSpace);
 };
@@ -804,19 +804,20 @@ nsTableRowFrame::ReflowChildren(nsPresCo
   // Reflow each of our existing cell frames
   for (nsIFrame* kidFrame = iter.First(); kidFrame; kidFrame = iter.Next()) {
     nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
     if (!cellFrame) {
       // XXXldb nsCSSFrameConstructor needs to enforce this!
       NS_NOTREACHED("yikes, a non-row child");
 
       // it's an unknown frame type, give it a generic reflow and ignore the results
-      nsTableCellReflowState kidReflowState(aPresContext, aReflowState,
-                                            kidFrame, nsSize(0,0),
-                                            nsHTMLReflowState::CALLER_WILL_INIT);
+      nsTableCellReflowState
+        kidReflowState(aPresContext, aReflowState, kidFrame,
+                       LogicalSize(kidFrame->GetWritingMode(), 0, 0),
+                       nsHTMLReflowState::CALLER_WILL_INIT);
       InitChildReflowState(*aPresContext, nsSize(0,0), false, kidReflowState);
       nsHTMLReflowMetrics desiredSize(aReflowState);
       nsReflowStatus  status;
       ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, status);
       kidFrame->DidReflow(aPresContext, nullptr, nsDidReflowStatus::FINISHED);
 
       continue;
     }
@@ -884,19 +885,21 @@ nsTableRowFrame::ReflowChildren(nsPresCo
           // 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.
         nsSize  kidAvailSize(availCellWidth, aReflowState.AvailableHeight());
 
         // Reflow the child
-        nsTableCellReflowState kidReflowState(aPresContext, aReflowState, 
-                                              kidFrame, kidAvailSize,
-                                              nsHTMLReflowState::CALLER_WILL_INIT);
+        nsTableCellReflowState
+          kidReflowState(aPresContext, aReflowState, kidFrame,
+                         LogicalSize(kidFrame->GetWritingMode(),
+                                     kidAvailSize),
+                         nsHTMLReflowState::CALLER_WILL_INIT);
         InitChildReflowState(*aPresContext, kidAvailSize, borderCollapse,
                              kidReflowState);
 
         nsReflowStatus status;
         ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
                     x, 0, 0, status);
 
         // allow the table to determine if/how the table needs to be rebalanced
@@ -1075,19 +1078,21 @@ nsTableRowFrame::ReflowCellFrame(nsPresC
 {
   // Reflow the cell frame with the specified height. Use the existing width
   nsRect cellRect = aCellFrame->GetRect();
   nsRect cellVisualOverflow = aCellFrame->GetVisualOverflowRect();
   
   nsSize availSize(cellRect.width, aAvailableHeight);
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
   bool borderCollapse = tableFrame->IsBorderCollapse();
-  nsTableCellReflowState cellReflowState(aPresContext, aReflowState,
-                                         aCellFrame, availSize,
-                                         nsHTMLReflowState::CALLER_WILL_INIT);
+  nsTableCellReflowState
+    cellReflowState(aPresContext, aReflowState, aCellFrame,
+                    LogicalSize(aCellFrame->GetWritingMode(),
+                                availSize),
+                    nsHTMLReflowState::CALLER_WILL_INIT);
   InitChildReflowState(*aPresContext, availSize, borderCollapse, cellReflowState);
   cellReflowState.mFlags.mIsTopOfPage = aIsTopOfPage;
 
   nsHTMLReflowMetrics desiredSize(aReflowState);
 
   ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
               0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
   bool fullyComplete = NS_FRAME_IS_COMPLETE(aStatus) && !NS_FRAME_IS_TRUNCATED(aStatus);
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -377,17 +377,19 @@ nsTableRowGroupFrame::ReflowChildren(nsP
       // incremental reflow codepath.
       nsHTMLReflowMetrics desiredSize(aReflowState.reflowState,
                                       aDesiredSize.mFlags);
       desiredSize.Width() = desiredSize.Height() = 0;
   
       // 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...
-      nsSize kidAvailSize(aReflowState.availSize.width, NS_UNCONSTRAINEDSIZE);
+      WritingMode wm = kidFrame->GetWritingMode();
+      LogicalSize kidAvailSize(wm, aReflowState.availSize);
+      kidAvailSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
       nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
                                        kidFrame, kidAvailSize,
                                        -1, -1,
                                        nsHTMLReflowState::CALLER_WILL_INIT);
       InitChildReflowState(*aPresContext, borderCollapse, kidReflowState);
 
       // This can indicate that columns were resized.
       if (aReflowState.reflowState.mFlags.mHResize)
@@ -940,18 +942,19 @@ nsTableRowGroupFrame::SplitSpanningCells
 
         nsRect rowRect = row->GetRect();
         nsSize rowAvailSize(aReflowState.AvailableWidth(),
                             std::max(aReflowState.AvailableHeight() - rowRect.y,
                                    0));
         // don't let the available height exceed what
         // CalculateRowHeights set for it
         rowAvailSize.height = std::min(rowAvailSize.height, rowRect.height);
-        nsHTMLReflowState rowReflowState(&aPresContext, aReflowState,
-                                         row, rowAvailSize,
+        nsHTMLReflowState rowReflowState(&aPresContext, aReflowState, row,
+                                         LogicalSize(row->GetWritingMode(),
+                                                     rowAvailSize),
                                          -1, -1,
                                          nsHTMLReflowState::CALLER_WILL_INIT);
         InitChildReflowState(aPresContext, borderCollapse, rowReflowState);
         rowReflowState.mFlags.mIsTopOfPage = isTopOfPage; // set top of page
 
         nscoord cellHeight = row->ReflowCellFrame(&aPresContext, rowReflowState,
                                                   isTopOfPage, cell,
                                                   cellAvailHeight, status);
@@ -1075,18 +1078,19 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
       // Reflow the row in the availabe space and have it split if it is the 1st
       // row (on the page) or there is at least 5% of the current page available 
       // XXX this 5% should be made a preference 
       if (!prevRowFrame || (availHeight - aDesiredSize.Height() > pageHeight / 20)) { 
         nsSize availSize(availWidth, std::max(availHeight - rowRect.y, 0));
         // don't let the available height exceed what CalculateRowHeights set for it
         availSize.height = std::min(availSize.height, rowRect.height);
 
-        nsHTMLReflowState rowReflowState(aPresContext, aReflowState,
-                                         rowFrame, availSize,
+        nsHTMLReflowState rowReflowState(aPresContext, aReflowState, rowFrame,
+                                         LogicalSize(rowFrame->GetWritingMode(),
+                                                     availSize),
                                          -1, -1,
                                          nsHTMLReflowState::CALLER_WILL_INIT);
                                          
         InitChildReflowState(*aPresContext, borderCollapse, rowReflowState);
         rowReflowState.mFlags.mIsTopOfPage = isTopOfPage; // set top of page
         nsHTMLReflowMetrics rowMetrics(aReflowState);
 
         // Get the old size before we reflow.
--- a/layout/xul/nsBoxFrame.cpp
+++ b/layout/xul/nsBoxFrame.cpp
@@ -900,19 +900,21 @@ nsBoxFrame::DoLayout(nsBoxLayoutState& a
     CoordNeedsRecalc(mAscent);
     rv = mLayoutManager->Layout(this, aState);
   }
 
   aState.SetLayoutFlags(oldFlags);
 
   if (HasAbsolutelyPositionedChildren()) {
     // Set up a |reflowState| to pass into ReflowAbsoluteFrames
+    WritingMode wm = GetWritingMode();
     nsHTMLReflowState reflowState(aState.PresContext(), this,
                                   aState.GetRenderingContext(),
-                                  nsSize(mRect.width, NS_UNCONSTRAINEDSIZE));
+                                  LogicalSize(wm, GetLogicalSize().ISize(wm),
+                                              NS_UNCONSTRAINEDSIZE));
 
     // Set up a |desiredSize| to pass into ReflowAbsoluteFrames
     nsHTMLReflowMetrics desiredSize(reflowState);
     desiredSize.Width() = mRect.width;
     desiredSize.Height() = mRect.height;
 
     // get the ascent (cribbed from ::Reflow)
     nscoord ascent = mRect.height;