Bug 1114239 patch 3: Backout bug 1062963 patch 3, r=jfkthame, a=lmandel
authorSimon Montagu <smontagu@smontagu.org>
Thu, 19 Mar 2015 01:48:49 +0200
changeset 250430 470cd8c739c5
parent 250429 8fca3694654a
child 250431 f0a0d5d2d525
push id4586
push usersmontagu@mozilla.com
push date2015-03-18 23:49 +0000
treeherdermozilla-beta@470cd8c739c5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame, lmandel
bugs1114239, 1062963
milestone37.0
Bug 1114239 patch 3: Backout bug 1062963 patch 3, r=jfkthame, a=lmandel
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsBlockReflowContext.cpp
layout/generic/nsBlockReflowState.cpp
layout/generic/nsBlockReflowState.h
layout/generic/nsContainerFrame.cpp
layout/generic/nsFloatManager.cpp
layout/generic/nsFloatManager.h
layout/generic/nsLineLayout.cpp
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1917,19 +1917,18 @@ nsBlockFrame::PropagateFloatDamage(nsBlo
     // with aLine's floats
     nscoord lineYA = aLine->BStart() + aDeltaY;
     nscoord lineYB = lineYA + aLine->BSize();
     // Scrollable overflow should be sufficient for things that affect
     // layout.
     nsRect overflow = aLine->GetOverflowArea(eScrollableOverflow);
     nscoord lineYCombinedA = overflow.y + aDeltaY;
     nscoord lineYCombinedB = lineYCombinedA + overflow.height;
-    WritingMode wm = aState.mReflowState.GetWritingMode();
-    if (floatManager->IntersectsDamage(wm, lineYA, lineYB) ||
-        floatManager->IntersectsDamage(wm, lineYCombinedA, lineYCombinedB)) {
+    if (floatManager->IntersectsDamage(lineYA, lineYB) ||
+        floatManager->IntersectsDamage(lineYCombinedA, lineYCombinedB)) {
       aLine->MarkDirty();
       return;
     }
   }
 
   // Check if the line is moving relative to the float manager
   if (aDeltaY + aState.mReflowState.mBlockDelta != 0) {
     if (aLine->IsBlock()) {
@@ -3282,18 +3281,17 @@ nsBlockFrame::ReflowBlockFrame(nsBlockRe
     // 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,
                   LogicalSize(frame->GetWritingMode(), availSpace.Size()));
     blockHtmlRS.mFlags.mHasClearance = aLine->HasClearance();
 
-    nsFloatManager::SavedState
-      floatManagerState(aState.mReflowState.GetWritingMode());
+    nsFloatManager::SavedState floatManagerState;
     if (mayNeedRetry) {
       blockHtmlRS.mDiscoveredClearance = &clearanceFrame;
       aState.mFloatManager->PushState(&floatManagerState);
     } else if (!applyBStartMargin) {
       blockHtmlRS.mDiscoveredClearance = aState.mReflowState.mDiscoveredClearance;
     }
 
     nsReflowStatus frameReflowStatus = NS_FRAME_COMPLETE;
@@ -3548,18 +3546,17 @@ nsBlockFrame::ReflowInlineFrames(nsBlock
   do {
     nscoord availableSpaceHeight = 0;
     do {
       bool allowPullUp = true;
       nsIFrame* forceBreakInFrame = nullptr;
       int32_t forceBreakOffset = -1;
       gfxBreakPriority forceBreakPriority = gfxBreakPriority::eNoBreak;
       do {
-        nsFloatManager::SavedState
-          floatManagerState(aState.mReflowState.GetWritingMode());
+        nsFloatManager::SavedState floatManagerState;
         aState.mReflowState.mFloatManager->PushState(&floatManagerState);
 
         // Once upon a time we allocated the first 30 nsLineLayout objects
         // on the stack, and then we switched to the heap.  At that time
         // these objects were large (1100 bytes on a 32 bit system).
         // Then the nsLineLayout object was shrunk to 156 bytes by
         // removing some internal buffers.  Given that it is so much
         // smaller, the complexity of 2 different ways of allocating
@@ -6100,63 +6097,60 @@ nsBlockFrame::ReflowPushedFloats(nsBlock
   // If there are continued floats, then we may need to continue BR clearance
   if (0 != aState.ClearFloats(0, NS_STYLE_CLEAR_BOTH)) {
     aState.mFloatBreakType = static_cast<nsBlockFrame*>(GetPrevInFlow())
                                ->FindTrailingClear();
   }
 }
 
 void
-nsBlockFrame::RecoverFloats(nsFloatManager& aFloatManager, WritingMode aWM,
-                            nscoord aContainerWidth)
+nsBlockFrame::RecoverFloats(nsFloatManager& aFloatManager)
 {
   // Recover our own floats
   nsIFrame* stop = nullptr; // Stop before we reach pushed floats that
                            // belong to our next-in-flow
   for (nsIFrame* f = mFloats.FirstChild(); f && f != stop; f = f->GetNextSibling()) {
-    LogicalRect region = nsFloatManager::GetRegionFor(aWM, f, aContainerWidth);
-    aFloatManager.AddFloat(f, region, aWM, aContainerWidth);
+    nsRect region = nsFloatManager::GetRegionFor(f);
+    aFloatManager.AddFloat(f, region);
     if (!stop && f->GetNextInFlow())
       stop = f->GetNextInFlow();
   }
 
   // Recurse into our overflow container children
   for (nsIFrame* oc = GetFirstChild(kOverflowContainersList);
        oc; oc = oc->GetNextSibling()) {
-    RecoverFloatsFor(oc, aFloatManager, aWM, aContainerWidth);
+    RecoverFloatsFor(oc, aFloatManager);
   }
 
   // Recurse into our normal children
   for (nsBlockFrame::line_iterator line = begin_lines(); line != end_lines(); ++line) {
     if (line->IsBlock()) {
-      RecoverFloatsFor(line->mFirstChild, aFloatManager, aWM, aContainerWidth);
+      RecoverFloatsFor(line->mFirstChild, aFloatManager);
     }
   }
 }
 
 void
 nsBlockFrame::RecoverFloatsFor(nsIFrame*       aFrame,
-                               nsFloatManager& aFloatManager,
-                               WritingMode     aWM,
-                               nscoord         aContainerWidth)
+                               nsFloatManager& aFloatManager)
 {
   NS_PRECONDITION(aFrame, "null frame");
   // Only blocks have floats
   nsBlockFrame* block = nsLayoutUtils::GetAsBlock(aFrame);
   // Don't recover any state inside a block that has its own space manager
   // (we don't currently have any blocks like this, though, thanks to our
   // use of extra frames for 'overflow')
   if (block && !nsBlockFrame::BlockNeedsFloatManager(block)) {
     // If the element is relatively positioned, then adjust x and y
     // accordingly so that we consider relatively positioned frames
     // at their original position.
-    LogicalPoint pos = block->GetLogicalNormalPosition(aWM, aContainerWidth);
-    WritingMode oldWM = aFloatManager.Translate(aWM, pos, aContainerWidth);
-    block->RecoverFloats(aFloatManager, aWM, aContainerWidth);
-    aFloatManager.Untranslate(oldWM, pos, aContainerWidth);
+    nsPoint pos = block->GetNormalPosition();
+    aFloatManager.Translate(pos.x, pos.y);
+    block->RecoverFloats(aFloatManager);
+    aFloatManager.Translate(-pos.x, -pos.y);
   }
 }
 
 //////////////////////////////////////////////////////////////////////
 // Painting, event handling
 
 #ifdef DEBUG
 static void ComputeVisualOverflowArea(nsLineList& aLines,
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -477,20 +477,18 @@ public:
 
   virtual bool UpdateOverflow() MOZ_OVERRIDE;
 
   /** Load all of aFrame's floats into the float manager iff aFrame is not a
    *  block formatting context. Handles all necessary float manager translations;
    *  assumes float manager is in aFrame's parent's coord system.
    *  Safe to call on non-blocks (does nothing).
    */
-  static void RecoverFloatsFor(nsIFrame*            aFrame,
-                               nsFloatManager&      aFloatManager,
-                               mozilla::WritingMode aWM,
-                               nscoord              aContainerWidth);
+  static void RecoverFloatsFor(nsIFrame*       aFrame,
+                               nsFloatManager& aFloatManager);
 
   /**
    * Determine if we have any pushed floats from a previous continuation.
    *
    * @returns true, if any of the floats at the beginning of our mFloats list
    *          have the NS_FRAME_IS_PUSHED_FLOAT bit set; false otherwise.
    */
   bool HasPushedFloatsFromPrevContinuation() const {
@@ -544,19 +542,17 @@ protected:
   /** grab pushed floats from this block's prevInFlow, and splice
     * them into this block's mFloats list.
     */
   void DrainPushedFloats(nsBlockReflowState& aState);
 
   /** Load all our floats into the float manager (without reflowing them).
    *  Assumes float manager is in our own coordinate system.
    */
-  void RecoverFloats(nsFloatManager&      aFloatManager,
-                     mozilla::WritingMode aWM,
-                     nscoord              aContainerWidth);
+  void RecoverFloats(nsFloatManager& aFloatManager);
 
   /** Reflow pushed floats
    */
   void ReflowPushedFloats(nsBlockReflowState& aState,
                           nsOverflowAreas&    aOverflowAreas,
                           nsReflowStatus&     aStatus);
 
   /** Find any trailing BR clear from the last line of the block (or its PIFs)
--- a/layout/generic/nsBlockReflowContext.cpp
+++ b/layout/generic/nsBlockReflowContext.cpp
@@ -247,53 +247,55 @@ nsBlockReflowContext::ReflowBlock(const 
 
     // Adjust the available block size if it's constrained so that the
     // child frame doesn't think it can reflow into its margin area.
     if (NS_UNCONSTRAINEDSIZE != aFrameRS.AvailableBSize()) {
       aFrameRS.AvailableBSize() -= mBStartMargin.get() + aClearance;
     }
   }
 
-  LogicalPoint tPt(mWritingMode);
+  nscoord tI = 0, tB = 0;
   // The values of x and y do not matter for floats, so don't bother
   // calculating them. Floats are guaranteed to have their own float
   // manager, so tI and tB don't matter.  mICoord and mBCoord don't
   // matter becacuse they are only used in PlaceBlock, which is not used
   // for floats.
   if (aLine) {
     // Compute inline/block coordinate where reflow will begin. Use the
     // rules from 10.3.3 to determine what to apply. At this point in the
     // reflow auto inline-start/end margins will have a zero value.
 
     WritingMode frameWM = aFrameRS.GetWritingMode();
-    mICoord = tPt.I(mWritingMode) =
+    mICoord = tI =
       mSpace.IStart(mWritingMode) +
       aFrameRS.ComputedLogicalMargin().ConvertTo(mWritingMode,
                                                  frameWM).IStart(mWritingMode);
-    mBCoord = tPt.B(mWritingMode) = mSpace.BStart(mWritingMode) +
-                                    mBStartMargin.get() + aClearance;
+    mBCoord = tB = mSpace.BStart(mWritingMode) +
+                   mBStartMargin.get() + aClearance;
+
+    //XXX temporary until nsFloatManager is logicalized
+    tI = aSpace.x + aFrameRS.ComputedPhysicalMargin().left;
+    tB = aSpace.y + mBStartMargin.get() + aClearance;
 
     if ((mFrame->GetStateBits() & NS_BLOCK_FLOAT_MGR) == 0)
       aFrameRS.mBlockDelta =
         mOuterReflowState.mBlockDelta + mBCoord - aLine->BStart();
   }
 
   // Let frame know that we are reflowing it
   mFrame->WillReflow(mPresContext);
 
 #ifdef DEBUG
   mMetrics.ISize(mWritingMode) = nscoord(0xdeadbeef);
   mMetrics.BSize(mWritingMode) = nscoord(0xdeadbeef);
 #endif
 
-  WritingMode oldWM =
-    mOuterReflowState.mFloatManager->Translate(mWritingMode, tPt,
-                                               mContainerWidth);
+  mOuterReflowState.mFloatManager->Translate(tI, tB);
   mFrame->Reflow(mPresContext, mMetrics, aFrameRS, aFrameReflowStatus);
-  mOuterReflowState.mFloatManager->Untranslate(oldWM, tPt, mContainerWidth);
+  mOuterReflowState.mFloatManager->Translate(-tI, -tB);
 
 #ifdef DEBUG
   if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) {
     if (CRAZY_SIZE(mMetrics.ISize(mWritingMode)) ||
         CRAZY_SIZE(mMetrics.BSize(mWritingMode))) {
       printf("nsBlockReflowContext: ");
       nsFrame::ListTag(stdout, mFrame);
       printf(" metrics=%d,%d!\n",
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -33,18 +33,16 @@ nsBlockReflowState::nsBlockReflowState(c
                                        nsBlockFrame* aFrame,
                                        bool aBStartMarginRoot,
                                        bool aBEndMarginRoot,
                                        bool aBlockNeedsFloatManager,
                                        nscoord aConsumedBSize)
   : mBlock(aFrame),
     mPresContext(aPresContext),
     mReflowState(aReflowState),
-    mFloatManagerOrigin(aReflowState.GetWritingMode()),
-    mFloatManagerStateBefore(aReflowState.GetWritingMode()),
     mContentArea(aReflowState.GetWritingMode()),
     mPushedFloats(nullptr),
     mOverflowTracker(nullptr),
     mBorderPadding(mReflowState.ComputedLogicalBorderPadding()),
     mPrevBEndMargin(),
     mLineNumber(0),
     mFlags(0),
     mFloatBreakType(NS_STYLE_CLEAR_NONE),
@@ -93,17 +91,17 @@ nsBlockReflowState::nsBlockReflowState(c
   }
   
   mFloatManager = aReflowState.mFloatManager;
 
   NS_ASSERTION(mFloatManager,
                "FloatManager should be set in nsBlockReflowState" );
   if (mFloatManager) {
     // Save the coordinate system origin for later.
-    mFloatManager->GetTranslation(mFloatManagerWM, mFloatManagerOrigin);
+    mFloatManager->GetTranslation(mFloatManagerX, mFloatManagerY);
     mFloatManager->PushState(&mFloatManagerStateBefore); // never popped
   }
 
   mReflowStatus = NS_FRAME_COMPLETE;
 
   mNextInFlow = static_cast<nsBlockFrame*>(mBlock->GetNextInFlow());
 
   NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aReflowState.ComputedISize(),
@@ -298,37 +296,31 @@ nsBlockReflowState::ComputeBlockAvailSpa
 #endif
 }
 
 nsFlowAreaRect
 nsBlockReflowState::GetFloatAvailableSpaceWithState(
                       nscoord aBCoord,
                       nsFloatManager::SavedState *aState) const
 {
-  WritingMode wm = mReflowState.GetWritingMode();
 #ifdef DEBUG
   // Verify that the caller setup the coordinate system properly
-  WritingMode wWM;
-  LogicalPoint wPt(wWM);
-  mFloatManager->GetTranslation(wWM, wPt);
-
-  if (wWM == mFloatManagerWM) {
-    NS_ASSERTION(wPt == mFloatManagerOrigin, "bad coord system");
-  } else {
-    //XXX if the writing modes are different we can't easily assert that
-    //    the origin is the same.
-  }
+  nscoord wx, wy;
+  mFloatManager->GetTranslation(wx, wy);
+  NS_ASSERTION((wx == mFloatManagerX) && (wy == mFloatManagerY),
+               "bad coord system");
 #endif
 
-  nscoord blockSize = (mContentArea.BSize(wm) == nscoord_MAX)
-    ? nscoord_MAX : std::max(mContentArea.BEnd(wm) - aBCoord, 0);
+  nsRect contentArea =
+    mContentArea.GetPhysicalRect(mReflowState.GetWritingMode(), mContainerWidth);
+  nscoord height = (contentArea.height == nscoord_MAX)
+                     ? nscoord_MAX : std::max(contentArea.YMost() - aBCoord, 0);
   nsFlowAreaRect result =
-    mFloatManager->GetFlowArea(wm, aBCoord, nsFloatManager::BAND_FROM_POINT,
-                               blockSize, mContentArea, aState,
-                               mContainerWidth);
+    mFloatManager->GetFlowArea(aBCoord, nsFloatManager::BAND_FROM_POINT,
+                               height, contentArea, aState);
   // Keep the width >= 0 for compatibility with nsSpaceManager.
   if (result.mRect.width < 0)
     result.mRect.width = 0;
 
 #ifdef DEBUG
   if (nsBlockFrame::gNoisyReflow) {
     nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
     printf("GetAvailableSpace: band=%d,%d,%d,%d hasfloats=%d\n",
@@ -339,32 +331,28 @@ nsBlockReflowState::GetFloatAvailableSpa
   return result;
 }
 
 nsFlowAreaRect
 nsBlockReflowState::GetFloatAvailableSpaceForBSize(
                       nscoord aBCoord, nscoord aBSize,
                       nsFloatManager::SavedState *aState) const
 {
-  WritingMode wm = mReflowState.GetWritingMode();
 #ifdef DEBUG
   // Verify that the caller setup the coordinate system properly
-  WritingMode wWM;
-  LogicalPoint wPt(wWM);
-  mFloatManager->GetTranslation(wWM, wPt);
-  if (wWM == mFloatManagerWM) {
-    NS_ASSERTION(wPt == mFloatManagerOrigin, "bad coord system");
-  } else {
-    //XXX if the writing modes are different we can't easily assert that
-    //    the origin is the same.
-  }
+  nscoord wx, wy;
+  mFloatManager->GetTranslation(wx, wy);
+  NS_ASSERTION((wx == mFloatManagerX) && (wy == mFloatManagerY),
+               "bad coord system");
 #endif
+  nsRect contentArea =
+    mContentArea.GetPhysicalRect(mReflowState.GetWritingMode(), mContainerWidth);
   nsFlowAreaRect result =
-    mFloatManager->GetFlowArea(wm, aBCoord, nsFloatManager::WIDTH_WITHIN_HEIGHT,
-                               aBSize, mContentArea, aState, mContainerWidth);
+    mFloatManager->GetFlowArea(aBCoord, nsFloatManager::WIDTH_WITHIN_HEIGHT,
+                               aBSize, contentArea, aState);
   // Keep the width >= 0 for compatibility with nsSpaceManager.
   if (result.mRect.width < 0)
     result.mRect.width = 0;
 
 #ifdef DEBUG
   if (nsBlockFrame::gNoisyReflow) {
     nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
     printf("GetAvailableSpaceForHeight: space=%d,%d,%d,%d hasfloats=%d\n",
@@ -456,61 +444,47 @@ nsBlockReflowState::AppendPushedFloatCha
  * parent.  The recovery of state is one of the things that makes
  * incremental reflow O(N^2) and this state should really be kept
  * around, attached to the frame tree.
  */
 void
 nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
                                   nscoord aDeltaBCoord)
 {
-  WritingMode wm = mReflowState.GetWritingMode();
-  // "Translate" the float manager with an offset of (0, 0) in order to
-  // set the origin to our writing mode
-  LogicalPoint oPt(wm);
-  WritingMode oldWM = mFloatManager->Translate(wm, oPt, mContainerWidth);
   if (aLine->HasFloats()) {
     // Place the floats into the space-manager again. Also slide
     // them, just like the regular frames on the line.
     nsFloatCache* fc = aLine->GetFirstFloat();
     while (fc) {
       nsIFrame* floatFrame = fc->mFloat;
       if (aDeltaBCoord != 0) {
         floatFrame->MovePositionBy(nsPoint(0, aDeltaBCoord));
         nsContainerFrame::PositionFrameView(floatFrame);
         nsContainerFrame::PositionChildViews(floatFrame);
       }
 #ifdef DEBUG
       if (nsBlockFrame::gNoisyReflow || nsBlockFrame::gNoisyFloatManager) {
-        WritingMode tWM;
-        LogicalPoint tPt(tWM);
-        mFloatManager->GetTranslation(tWM, tPt);
+        nscoord tx, ty;
+        mFloatManager->GetTranslation(tx, ty);
         nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
         printf("RecoverFloats: txy=%d,%d (%d,%d) ",
-               tPt.I(tWM), tPt.B(tWM),
-               mFloatManagerOrigin.I(mFloatManagerWM),
-               mFloatManagerOrigin.B(mFloatManagerWM));
+               tx, ty, mFloatManagerX, mFloatManagerY);
         nsFrame::ListTag(stdout, floatFrame);
-        LogicalRect region = nsFloatManager::GetRegionFor(wm, floatFrame,
-                                                          mContainerWidth);
+        nsRect region = nsFloatManager::GetRegionFor(floatFrame);
         printf(" aDeltaBCoord=%d region={%d,%d,%d,%d}\n",
-               aDeltaBCoord, region.IStart(wm), region.BStart(wm),
-               region.ISize(wm), region.BSize(wm));
+               aDeltaBCoord, region.x, region.y, region.width, region.height);
       }
 #endif
       mFloatManager->AddFloat(floatFrame,
-                              nsFloatManager::GetRegionFor(wm, floatFrame,
-                                                           mContainerWidth),
-                              wm, mContainerWidth);
+                              nsFloatManager::GetRegionFor(floatFrame));
       fc = fc->Next();
     }
   } else if (aLine->IsBlock()) {
-    nsBlockFrame::RecoverFloatsFor(aLine->mFirstChild, *mFloatManager, wm,
-                                   mContainerWidth);
+    nsBlockFrame::RecoverFloatsFor(aLine->mFirstChild, *mFloatManager);
   }
-  mFloatManager->Untranslate(oldWM, oPt, mContainerWidth);
 }
 
 /**
  * Everything done in this function is done O(N) times for each pass of
  * reflow so it is O(N*M) where M is the number of incremental reflow
  * passes.  That's bad.  Don't do stuff here.
  *
  * When this function is called, |aLine| has just been slid by |aDeltaBCoord|
@@ -586,20 +560,21 @@ nsBlockReflowState::AddFloat(nsLineLayou
     mBlock->mFloats.AppendFrame(mBlock, aFloat);
   }
 
   // Because we are in the middle of reflowing a placeholder frame
   // within a line (and possibly nested in an inline frame or two
   // that's a child of our block) we need to restore the space
   // manager's translation to the space that the block resides in
   // before placing the float.
-  WritingMode oldWM;
-  LogicalPoint oPt(oldWM);
-  mFloatManager->GetTranslation(oldWM, oPt);
-  mFloatManager->SetTranslation(mFloatManagerWM, mFloatManagerOrigin);
+  nscoord ox, oy;
+  mFloatManager->GetTranslation(ox, oy);
+  nscoord dx = ox - mFloatManagerX;
+  nscoord dy = oy - mFloatManagerY;
+  mFloatManager->Translate(-dx, -dy);
 
   bool placed;
 
   // Now place the float immediately if possible. Otherwise stash it
   // away in mPendingFloats and place it later.
   // If one or more floats has already been pushed to the next line,
   // don't let this one go on the current line, since that would violate
   // float ordering.
@@ -627,17 +602,17 @@ nsBlockReflowState::AddFloat(nsLineLayou
     // deal with this in PlaceBelowCurrentLineFloats
     placed = true;
     // This float will be placed after the line is done (it is a
     // below-current-line float).
     mBelowCurrentLineFloats.Append(mFloatCacheFreeList.Alloc(aFloat));
   }
 
   // Restore coordinate system
-  mFloatManager->SetTranslation(oldWM, oPt);
+  mFloatManager->Translate(dx, dy);
 
   return placed;
 }
 
 bool
 nsBlockReflowState::CanPlaceFloat(nscoord aFloatWidth,
                                   const nsFlowAreaRect& aFloatAvailableSpace)
 {
@@ -669,41 +644,34 @@ FloatMarginWidth(const nsHTMLReflowState
     nsIFrame::ComputeSizeFlags::eShrinkWrap).Width(fosWM) +
   aFloatOffsetState.ComputedPhysicalMargin().LeftRight() +
   aFloatOffsetState.ComputedPhysicalBorderPadding().LeftRight();
 }
 
 bool
 nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
 {
-  WritingMode wm = mReflowState.GetWritingMode();
   // Save away the Y coordinate before placing the float. We will
   // restore mBCoord at the end after placing the float. This is
   // necessary because any adjustments to mBCoord during the float
   // placement are for the float only, not for any non-floating
   // content.
   AutoRestore<nscoord> restoreBCoord(mBCoord);
   // FIXME: Should give AutoRestore a getter for the value to avoid this.
   const nscoord saveBCoord = mBCoord;
 
   // Grab the float's display information
   const nsStyleDisplay* floatDisplay = aFloat->StyleDisplay();
 
   // The float's old region, so we can propagate damage.
-  LogicalRect oldRegion = nsFloatManager::GetRegionFor(wm, aFloat,
-                                                       mContainerWidth);
+  nsRect oldRegion = nsFloatManager::GetRegionFor(aFloat);
 
   // Enforce CSS2 9.5.1 rule [2], i.e., make sure that a float isn't
   // ``above'' another float that preceded it in the flow.
-  // "Translate" the float manager with an offset of (0, 0) in order to
-  // set the origin to our writing mode
-  LogicalPoint oPt(wm);
-  WritingMode oldWM = mFloatManager->Translate(wm, oPt, mContainerWidth);
-  mBCoord = std::max(mFloatManager->GetLowestFloatTop(wm, mContainerWidth),
-                     mBCoord);
+  mBCoord = std::max(mFloatManager->GetLowestFloatTop(), mBCoord);
 
   // See if the float should clear any preceding floats...
   // XXX We need to mark this float somehow so that it gets reflowed
   // when floats are inserted before it.
   if (NS_STYLE_CLEAR_NONE != floatDisplay->mBreakType) {
     // XXXldb Does this handle vertical margins correctly?
     mBCoord = ClearFloats(mBCoord, floatDisplay->mBreakType);
   }
@@ -922,74 +890,65 @@ nsBlockReflowState::FlowAndPlaceFloat(ns
   }
 
   // Update the float combined area state
   // XXX Floats should really just get invalidated here if necessary
   mFloatOverflowAreas.UnionWith(aFloat->GetOverflowAreas() + origin);
 
   // Place the float in the float manager
   // calculate region
-  LogicalRect region =
-    nsFloatManager::CalculateRegionFor(wm, aFloat,
-                                       LogicalMargin(wm, floatMargin),
-                                       mContainerWidth);
+  nsRect region = nsFloatManager::CalculateRegionFor(aFloat, floatMargin);
   // if the float split, then take up all of the vertical height
   if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus) &&
       (NS_UNCONSTRAINEDSIZE != ContentBSize())) {
-    region.BSize(wm) = std::max(region.BSize(wm), ContentBSize() - floatY);
+    region.height = std::max(region.height, ContentBSize() - floatY);
   }
-  DebugOnly<nsresult> rv = mFloatManager->AddFloat(aFloat, region, wm,
-                                                   mContainerWidth);
+  DebugOnly<nsresult> rv =
+    mFloatManager->AddFloat(aFloat, region);
   NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "bad float placement");
   // store region
-  nsFloatManager::StoreRegionFor(wm, aFloat, region, mContainerWidth);
+  nsFloatManager::StoreRegionFor(aFloat, region);
 
   // If the float's dimensions have changed, note the damage in the
   // float manager.
   if (!region.IsEqualEdges(oldRegion)) {
     // XXXwaterson conservative: we could probably get away with noting
     // less damage; e.g., if only height has changed, then only note the
     // area into which the float has grown or from which the float has
     // shrunk.
-    nscoord blockStart = std::min(region.BStart(wm), oldRegion.BStart(wm));
-    nscoord blockEnd = std::max(region.BEnd(wm), oldRegion.BEnd(wm));
-    mFloatManager->IncludeInDamage(wm, blockStart, blockEnd);
+    nscoord top = std::min(region.y, oldRegion.y);
+    nscoord bottom = std::max(region.YMost(), oldRegion.YMost());
+    mFloatManager->IncludeInDamage(top, bottom);
   }
 
   if (!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus)) {
     mBlock->SplitFloat(*this, aFloat, reflowStatus);
   } else {
     MOZ_ASSERT(!aFloat->GetNextInFlow());
   }
 
 #ifdef NOISY_FLOATMANAGER
-  WritingMode tWM;
-  LogicalPoint tPt(wm);
-  mFloatManager->GetTranslation(tWM, tPt);
+  nscoord tx, ty;
+  mFloatManager->GetTranslation(tx, ty);
   nsFrame::ListTag(stdout, mBlock);
   printf(": FlowAndPlaceFloat: AddFloat: txy=%d,%d (%d,%d) {%d,%d,%d,%d}\n",
-         tPt.I(tWM), tPt.B(tWM),
-         mFloatManagerOrigin.I(mFloatManagerWM),
-         mFloatManagerOrigin.B(mFloatManagerWM),
-         region.IStart(wm), region.BStart(wm),
-         region.ISize(wm), region.BSize(wm));
+         tx, ty, mFloatManagerX, mFloatManagerY,
+         region.x, region.y, region.width, region.height);
 #endif
 
 #ifdef DEBUG
   if (nsBlockFrame::gNoisyReflow) {
     nsRect r = aFloat->GetRect();
     nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
     printf("placed float: ");
     nsFrame::ListTag(stdout, aFloat);
     printf(" %d,%d,%d,%d\n", r.x, r.y, r.width, r.height);
   }
 #endif
 
-  mFloatManager->Untranslate(oldWM, oPt, mContainerWidth);
-
   return true;
 }
 
 void
 nsBlockReflowState::PushFloatPastBreak(nsIFrame *aFloat)
 {
   // This ensures that we:
   //  * don't try to place later but smaller floats (which CSS says
@@ -1063,18 +1022,17 @@ nsBlockReflowState::ClearFloats(nscoord 
   if (!mFloatManager->HasAnyFloats()) {
     return aBCoord;
   }
 
   nscoord newBCoord = aBCoord;
   WritingMode wm = mReflowState.GetWritingMode();
 
   if (aBreakType != NS_STYLE_CLEAR_NONE) {
-    newBCoord = mFloatManager->ClearFloats(wm, newBCoord, aBreakType,
-                                           mContainerWidth, aFlags);
+    newBCoord = mFloatManager->ClearFloats(newBCoord, aBreakType, aFlags);
   }
 
   if (aReplacedBlock) {
     for (;;) {
       nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(newBCoord);
       if (!floatAvailableSpace.mHasFloats) {
         // If there aren't any floats here, then we always fit.
         // We check this before calling WidthToClearPastFloats, which is
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -154,18 +154,17 @@ public:
 
   nsFloatManager* mFloatManager;
 
   // The coordinates within the float manager where the block is being
   // placed <b>after</b> taking into account the blocks border and
   // padding. This, therefore, represents the inner "content area" (in
   // spacemanager coordinates) where child frames will be placed,
   // including child blocks and floats.
-  mozilla::WritingMode mFloatManagerWM;
-  mozilla::LogicalPoint mFloatManagerOrigin;
+  nscoord mFloatManagerX, mFloatManagerY;
 
   // XXX get rid of this
   nsReflowStatus mReflowStatus;
 
   // The float manager state as it was before the contents of this
   // block.  This is needed for positioning bullets, since we only want
   // to move the bullet to flow around floats that were before this
   // block, not floats inside of it.
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -1195,21 +1195,18 @@ nsContainerFrame::ReflowOverflowContaine
       }
       NS_MergeReflowStatusInto(&aStatus, frameStatus);
       // At this point it would be nice to assert !frame->GetOverflowRect().IsEmpty(),
       // but we have some unsplittable frames that, when taller than
       // availableHeight will push zero-height content into a next-in-flow.
     }
     else {
       tracker.Skip(frame, aStatus);
-      if (aReflowState.mFloatManager) {
-        nsBlockFrame::RecoverFloatsFor(frame, *aReflowState.mFloatManager,
-                                       aReflowState.GetWritingMode(),
-                                       aReflowState.ComputedWidth());
-      }
+      if (aReflowState.mFloatManager)
+        nsBlockFrame::RecoverFloatsFor(frame, *aReflowState.mFloatManager);
     }
     ConsiderChildOverflow(aOverflowRects, frame);
   }
 }
 
 void
 nsContainerFrame::DisplayOverflowContainers(nsDisplayListBuilder*   aBuilder,
                                             const nsRect&           aDirtyRect,
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -32,20 +32,18 @@ static void
 PSArenaFreeCB(size_t aSize, void* aPtr, void* aClosure)
 {
   static_cast<nsIPresShell*>(aClosure)->FreeMisc(aSize, aPtr);
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // nsFloatManager
 
-nsFloatManager::nsFloatManager(nsIPresShell* aPresShell,
-                               mozilla::WritingMode aWM)
-  : mWritingMode(aWM),
-    mOrigin(aWM),
+nsFloatManager::nsFloatManager(nsIPresShell* aPresShell)
+  : mX(0), mY(0),
     mFloatDamage(PSArenaAllocCB, PSArenaFreeCB, aPresShell),
     mPushedLeftFloatPastBreak(false),
     mPushedRightFloatPastBreak(false),
     mSplitLeftFloatAcrossBreak(false),
     mSplitRightFloatAcrossBreak(false)
 {
   MOZ_COUNT_CTOR(nsFloatManager);
 }
@@ -107,251 +105,224 @@ void nsFloatManager::Shutdown()
       nsMemory::Free(floatManager);
   }
 
   // Disable further caching.
   sCachedFloatManagerCount = -1;
 }
 
 nsFlowAreaRect
-nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBOffset,
-                            BandInfoType aInfoType, nscoord aBSize,
-                            LogicalRect aContentArea, SavedState* aState,
-                            nscoord aContainerWidth) const
+nsFloatManager::GetFlowArea(nscoord aYOffset, BandInfoType aInfoType,
+                            nscoord aHeight, nsRect aContentArea,
+                            SavedState* aState) const
 {
-  NS_ASSERTION(aBSize >= 0, "unexpected max block size");
-  NS_ASSERTION(aContentArea.ISize(aWM) >= 0,
-               "unexpected content area inline size");
+  NS_ASSERTION(aHeight >= 0, "unexpected max height");
+  NS_ASSERTION(aContentArea.width >= 0, "unexpected content area width");
 
-  LogicalPoint origin = mOrigin.ConvertTo(aWM, mWritingMode, aContainerWidth);
-  nscoord blockStart = aBOffset + origin.B(aWM);
-  if (blockStart < nscoord_MIN) {
+  nscoord top = aYOffset + mY;
+  if (top < nscoord_MIN) {
     NS_WARNING("bad value");
-    blockStart = nscoord_MIN;
+    top = nscoord_MIN;
   }
 
   // Determine the last float that we should consider.
   uint32_t floatCount;
   if (aState) {
     // Use the provided state.
     floatCount = aState->mFloatInfoCount;
     NS_ABORT_IF_FALSE(floatCount <= mFloats.Length(), "bad state");
   } else {
     // Use our current state.
     floatCount = mFloats.Length();
   }
 
   // If there are no floats at all, or we're below the last one, return
   // quickly.
   if (floatCount == 0 ||
-      (mFloats[floatCount-1].mLeftBEnd <= blockStart &&
-       mFloats[floatCount-1].mRightBEnd <= blockStart)) {
-    //XXX temporary!
-    LogicalRect rect(aWM, aContentArea.IStart(aWM), aBOffset,
-                     aContentArea.ISize(aWM), aBSize);
-    nsRect phys = rect.GetPhysicalRect(aWM, aContainerWidth);
-    return nsFlowAreaRect(phys.x, phys.y, phys.width, phys.height, false);
+      (mFloats[floatCount-1].mLeftYMost <= top &&
+       mFloats[floatCount-1].mRightYMost <= top)) {
+    return nsFlowAreaRect(aContentArea.x, aYOffset, aContentArea.width,
+                          aHeight, false);
   }
 
-  nscoord blockEnd;
-  if (aBSize == nscoord_MAX) {
+  nscoord bottom;
+  if (aHeight == nscoord_MAX) {
     // This warning (and the two below) are possible to hit on pages
     // with really large objects.
     NS_WARN_IF_FALSE(aInfoType == BAND_FROM_POINT,
                      "bad height");
-    blockEnd = nscoord_MAX;
+    bottom = nscoord_MAX;
   } else {
-    blockEnd = blockStart + aBSize;
-    if (blockEnd < blockStart || blockEnd > nscoord_MAX) {
+    bottom = top + aHeight;
+    if (bottom < top || bottom > nscoord_MAX) {
       NS_WARNING("bad value");
-      blockEnd = nscoord_MAX;
+      bottom = nscoord_MAX;
     }
   }
-  nscoord inlineStart = origin.I(aWM) + aContentArea.IStart(aWM);
-  nscoord inlineEnd = origin.I(aWM) + aContentArea.IEnd(aWM);
-  if (inlineEnd < inlineStart) {
+  nscoord left = mX + aContentArea.x;
+  nscoord right = mX + aContentArea.XMost();
+  if (right < left) {
     NS_WARNING("bad value");
-    inlineEnd = inlineStart;
+    right = left;
   }
 
   // Walk backwards through the floats until we either hit the front of
-  // the list or we're above |blockStart|.
+  // the list or we're above |top|.
   bool haveFloats = false;
   for (uint32_t i = floatCount; i > 0; --i) {
     const FloatInfo &fi = mFloats[i-1];
-    if (fi.mLeftBEnd <= blockStart && fi.mRightBEnd <= blockStart) {
+    if (fi.mLeftYMost <= top && fi.mRightYMost <= top) {
       // There aren't any more floats that could intersect this band.
       break;
     }
     if (fi.mRect.IsEmpty()) {
       // For compatibility, ignore floats with empty rects, even though it
       // disagrees with the spec.  (We might want to fix this in the
       // future, though.)
       continue;
     }
-
-    LogicalRect rect = fi.mRect.ConvertTo(aWM, fi.mWritingMode,
-                                          aContainerWidth);
-    nscoord floatBStart = rect.BStart(aWM);
-    nscoord floatBEnd = rect.BEnd(aWM);
-    if (blockStart < floatBStart && aInfoType == BAND_FROM_POINT) {
+    nscoord floatTop = fi.mRect.y, floatBottom = fi.mRect.YMost();
+    if (top < floatTop && aInfoType == BAND_FROM_POINT) {
       // This float is below our band.  Shrink our band's height if needed.
-      if (floatBStart < blockEnd) {
-        blockEnd = floatBStart;
+      if (floatTop < bottom) {
+        bottom = floatTop;
       }
     }
-    // If blockStart == blockEnd (which happens only with WIDTH_WITHIN_HEIGHT),
+    // If top == bottom (which happens only with WIDTH_WITHIN_HEIGHT),
     // we include floats that begin at our 0-height vertical area.  We
     // need to to this to satisfy the invariant that a
     // WIDTH_WITHIN_HEIGHT call is at least as narrow on both sides as a
-    // BAND_WITHIN_POINT call beginning at its blockStart.
-    else if (blockStart < floatBEnd &&
-             (floatBStart < blockEnd ||
-              (floatBStart == blockEnd && blockStart == blockEnd))) {
+    // BAND_WITHIN_POINT call beginning at its top.
+    else if (top < floatBottom &&
+             (floatTop < bottom || (floatTop == bottom && top == bottom))) {
       // This float is in our band.
 
       // Shrink our band's height if needed.
-      if (floatBEnd < blockEnd && aInfoType == BAND_FROM_POINT) {
-        blockEnd = floatBEnd;
+      if (floatBottom < bottom && aInfoType == BAND_FROM_POINT) {
+        bottom = floatBottom;
       }
 
       // Shrink our band's width if needed.
-      if ((fi.mFrame->StyleDisplay()->mFloats == NS_STYLE_FLOAT_LEFT) ==
-          aWM.IsBidiLTR()) {
-        // A left float in an ltr block or a right float in an rtl block
-        nscoord inlineEndEdge = rect.IEnd(aWM);
-        if (inlineEndEdge > inlineStart) {
-          inlineStart = inlineEndEdge;
+      if (fi.mFrame->StyleDisplay()->mFloats == NS_STYLE_FLOAT_LEFT) {
+        // A left float.
+        nscoord rightEdge = fi.mRect.XMost();
+        if (rightEdge > left) {
+          left = rightEdge;
           // Only set haveFloats to true if the float is inside our
           // containing block.  This matches the spec for what some
           // callers want and disagrees for other callers, so we should
           // probably provide better information at some point.
           haveFloats = true;
         }
       } else {
-        // A left float in an rtl block or a right float in an ltr block
-        nscoord inlineStartEdge = rect.IStart(aWM);
-        if (inlineStartEdge < inlineEnd) {
-          inlineEnd = inlineStartEdge;
+        // A right float.
+        nscoord leftEdge = fi.mRect.x;
+        if (leftEdge < right) {
+          right = leftEdge;
           // See above.
           haveFloats = true;
         }
       }
     }
   }
 
-  nscoord height = (blockEnd == nscoord_MAX) ?
-                    nscoord_MAX : (blockEnd - blockStart);
-  //XXX temporary!
-  LogicalRect rect(aWM,
-                   inlineStart - origin.I(aWM), blockStart - origin.B(aWM),
-                   inlineEnd - inlineStart, height);
-  nsRect phys = rect.GetPhysicalRect(aWM, aContainerWidth);
-  return nsFlowAreaRect(phys.x, phys.y, phys.width, phys.height, haveFloats);
+  nscoord height = (bottom == nscoord_MAX) ? nscoord_MAX : (bottom - top);
+  return nsFlowAreaRect(left - mX, top - mY, right - left, height, haveFloats);
 }
 
 nsresult
-nsFloatManager::AddFloat(nsIFrame* aFloatFrame, const LogicalRect& aMarginRect,
-                         WritingMode aWM, nscoord aContainerWidth)
+nsFloatManager::AddFloat(nsIFrame* aFloatFrame, const nsRect& aMarginRect)
 {
-  NS_ASSERTION(aMarginRect.ISize(aWM) >= 0, "negative inline size!");
-  NS_ASSERTION(aMarginRect.BSize(aWM) >= 0, "negative block size!");
+  NS_ASSERTION(aMarginRect.width >= 0, "negative width!");
+  NS_ASSERTION(aMarginRect.height >= 0, "negative height!");
 
-  FloatInfo info(aFloatFrame, aWM, aMarginRect + mOrigin);
+  FloatInfo info(aFloatFrame, aMarginRect + nsPoint(mX, mY));
 
-  // Set mLeftBEnd and mRightBEnd.
+  // Set mLeftYMost and mRightYMost.
   if (HasAnyFloats()) {
     FloatInfo &tail = mFloats[mFloats.Length() - 1];
-    info.mLeftBEnd = tail.mLeftBEnd;
-    info.mRightBEnd = tail.mRightBEnd;
+    info.mLeftYMost = tail.mLeftYMost;
+    info.mRightYMost = tail.mRightYMost;
   } else {
-    info.mLeftBEnd = nscoord_MIN;
-    info.mRightBEnd = nscoord_MIN;
+    info.mLeftYMost = nscoord_MIN;
+    info.mRightYMost = nscoord_MIN;
   }
   uint8_t floatStyle = aFloatFrame->StyleDisplay()->mFloats;
   NS_ASSERTION(floatStyle == NS_STYLE_FLOAT_LEFT ||
                floatStyle == NS_STYLE_FLOAT_RIGHT, "unexpected float");
-  nscoord& sideBEnd =
-    ((floatStyle == NS_STYLE_FLOAT_LEFT) == aWM.IsBidiLTR()) ? info.mLeftBEnd
-                                                             : info.mRightBEnd;
-  nscoord thisBEnd = info.mRect.BEnd(aWM);
-  if (thisBEnd > sideBEnd)
-    sideBEnd = thisBEnd;
+  nscoord& sideYMost = (floatStyle == NS_STYLE_FLOAT_LEFT) ? info.mLeftYMost
+                                                           : info.mRightYMost;
+  nscoord thisYMost = info.mRect.YMost();
+  if (thisYMost > sideYMost)
+    sideYMost = thisYMost;
 
   if (!mFloats.AppendElement(info))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
-LogicalRect
-nsFloatManager::CalculateRegionFor(WritingMode          aWM,
-                                   nsIFrame*            aFloat,
-                                   const LogicalMargin& aMargin,
-                                   nscoord              aContainerWidth)
+nsRect
+nsFloatManager::CalculateRegionFor(nsIFrame*       aFloat,
+                                   const nsMargin& aMargin)
 {
   // We consider relatively positioned frames at their original position.
-  LogicalRect region(aWM, nsRect(aFloat->GetNormalPosition(),
-                                 aFloat->GetSize()),
-                     aContainerWidth);
+  nsRect region(aFloat->GetNormalPosition(), aFloat->GetSize());
 
   // Float region includes its margin
-  region.Inflate(aWM, aMargin);
+  region.Inflate(aMargin);
 
   // Don't store rectangles with negative margin-box width or height in
   // the float manager; it can't deal with them.
-  if (region.ISize(aWM) < 0) {
+  if (region.width < 0) {
     // Preserve the right margin-edge for left floats and the left
     // margin-edge for right floats
     const nsStyleDisplay* display = aFloat->StyleDisplay();
-    if ((NS_STYLE_FLOAT_LEFT == display->mFloats) == aWM.IsBidiLTR()) {
-      region.IStart(aWM) = region.IEnd(aWM);
+    if (NS_STYLE_FLOAT_LEFT == display->mFloats) {
+      region.x = region.XMost();
     }
-    region.ISize(aWM) = 0;
+    region.width = 0;
   }
-  if (region.BSize(aWM) < 0) {
-    region.BSize(aWM) = 0;
+  if (region.height < 0) {
+    region.height = 0;
   }
   return region;
 }
 
 NS_DECLARE_FRAME_PROPERTY(FloatRegionProperty, nsIFrame::DestroyMargin)
 
-LogicalRect
-nsFloatManager::GetRegionFor(WritingMode aWM, nsIFrame* aFloat,
-                             nscoord aContainerWidth)
+nsRect
+nsFloatManager::GetRegionFor(nsIFrame* aFloat)
 {
-  LogicalRect region = aFloat->GetLogicalRect(aWM, aContainerWidth);
+  nsRect region = aFloat->GetRect();
   void* storedRegion = aFloat->Properties().Get(FloatRegionProperty());
   if (storedRegion) {
     nsMargin margin = *static_cast<nsMargin*>(storedRegion);
-    region.Inflate(aWM, LogicalMargin(aWM, margin));
+    region.Inflate(margin);
   }
   return region;
 }
 
 void
-nsFloatManager::StoreRegionFor(WritingMode aWM, nsIFrame* aFloat,
-                               const LogicalRect& aRegion,
-                               nscoord aContainerWidth)
+nsFloatManager::StoreRegionFor(nsIFrame* aFloat,
+                               nsRect&   aRegion)
 {
-  nsRect region = aRegion.GetPhysicalRect(aWM, aContainerWidth);
   nsRect rect = aFloat->GetRect();
   FrameProperties props = aFloat->Properties();
-  if (region.IsEqualEdges(rect)) {
+  if (aRegion.IsEqualEdges(rect)) {
     props.Delete(FloatRegionProperty());
   }
   else {
     nsMargin* storedMargin = static_cast<nsMargin*>
       (props.Get(FloatRegionProperty()));
     if (!storedMargin) {
       storedMargin = new nsMargin();
       props.Set(FloatRegionProperty(), storedMargin);
     }
-    *storedMargin = region - rect;
+    *storedMargin = aRegion - rect;
   }
 }
 
 nsresult
 nsFloatManager::RemoveTrailingRegions(nsIFrame* aFrameList)
 {
   if (!aFrameList) {
     return NS_OK;
@@ -402,57 +373,52 @@ nsFloatManager::PushState(SavedState* aS
   // It should also be noted that the state for mFloatDamage is
   // intentionally not saved or restored in PushState() and PopState(),
   // since that could lead to bugs where damage is missed/dropped when
   // we move from position A to B (during the intermediate incremental
   // reflow mentioned above) and then from B to C during the subsequent
   // reflow. In the typical case A and C will be the same, but not always.
   // Allowing mFloatDamage to accumulate the damage incurred during both
   // reflows ensures that nothing gets missed.
-  aState->mWritingMode = mWritingMode;
-  aState->mOrigin = mOrigin;
+  aState->mX = mX;
+  aState->mY = mY;
   aState->mPushedLeftFloatPastBreak = mPushedLeftFloatPastBreak;
   aState->mPushedRightFloatPastBreak = mPushedRightFloatPastBreak;
   aState->mSplitLeftFloatAcrossBreak = mSplitLeftFloatAcrossBreak;
   aState->mSplitRightFloatAcrossBreak = mSplitRightFloatAcrossBreak;
   aState->mFloatInfoCount = mFloats.Length();
 }
 
 void
 nsFloatManager::PopState(SavedState* aState)
 {
   NS_PRECONDITION(aState, "No state to restore?");
 
-  mWritingMode = aState->mWritingMode;
-  mOrigin = aState->mOrigin;
+  mX = aState->mX;
+  mY = aState->mY;
   mPushedLeftFloatPastBreak = aState->mPushedLeftFloatPastBreak;
   mPushedRightFloatPastBreak = aState->mPushedRightFloatPastBreak;
   mSplitLeftFloatAcrossBreak = aState->mSplitLeftFloatAcrossBreak;
   mSplitRightFloatAcrossBreak = aState->mSplitRightFloatAcrossBreak;
 
   NS_ASSERTION(aState->mFloatInfoCount <= mFloats.Length(),
                "somebody misused PushState/PopState");
   mFloats.TruncateLength(aState->mFloatInfoCount);
 }
 
 nscoord
-nsFloatManager::GetLowestFloatTop(WritingMode aWM,
-                                  nscoord aContainerWidth) const
+nsFloatManager::GetLowestFloatTop() const
 {
   if (mPushedLeftFloatPastBreak || mPushedRightFloatPastBreak) {
     return nscoord_MAX;
   }
   if (!HasAnyFloats()) {
     return nscoord_MIN;
   }
-  FloatInfo fi = mFloats[mFloats.Length() - 1];
-  LogicalRect rect = fi.mRect.ConvertTo(aWM, fi.mWritingMode, aContainerWidth);
-  LogicalPoint origin = mOrigin.ConvertTo(aWM, mWritingMode, aContainerWidth);
-
-  return rect.BStart(aWM) - origin.B(aWM);
+  return mFloats[mFloats.Length() - 1].mRect.y - mY;
 }
 
 #ifdef DEBUG_FRAME_DUMP
 void
 DebugListFloatManager(const nsFloatManager *aFloatManager)
 {
   aFloatManager->List(stdout);
 }
@@ -462,93 +428,84 @@ nsFloatManager::List(FILE* out) const
 {
   if (!HasAnyFloats())
     return NS_OK;
 
   for (uint32_t i = 0; i < mFloats.Length(); ++i) {
     const FloatInfo &fi = mFloats[i];
     fprintf_stderr(out, "Float %u: frame=%p rect={%d,%d,%d,%d} ymost={l:%d, r:%d}\n",
                    i, static_cast<void*>(fi.mFrame),
-                   fi.mRect.IStart(fi.mWritingMode),
-                   fi.mRect.BStart(fi.mWritingMode),
-                   fi.mRect.ISize(fi.mWritingMode),
-                   fi.mRect.BSize(fi.mWritingMode),
-                   fi.mLeftBEnd, fi.mRightBEnd);
+                   fi.mRect.x, fi.mRect.y, fi.mRect.width, fi.mRect.height,
+                   fi.mLeftYMost, fi.mRightYMost);
   }
   return NS_OK;
 }
 #endif
 
 nscoord
-nsFloatManager::ClearFloats(WritingMode aWM, nscoord aBCoord,
-                            uint8_t aBreakType, nscoord aContainerWidth,
+nsFloatManager::ClearFloats(nscoord aY, uint8_t aBreakType,
                             uint32_t aFlags) const
 {
   if (!(aFlags & DONT_CLEAR_PUSHED_FLOATS) && ClearContinues(aBreakType)) {
     return nscoord_MAX;
   }
   if (!HasAnyFloats()) {
-    return aBCoord;
+    return aY;
   }
 
-  LogicalPoint origin = mOrigin.ConvertTo(aWM, mWritingMode, aContainerWidth);
-  nscoord blockEnd = aBCoord + origin.B(aWM);
+  nscoord bottom = aY + mY;
 
   const FloatInfo &tail = mFloats[mFloats.Length() - 1];
   switch (aBreakType) {
     case NS_STYLE_CLEAR_BOTH:
-      blockEnd = std::max(blockEnd, tail.mLeftBEnd);
-      blockEnd = std::max(blockEnd, tail.mRightBEnd);
+      bottom = std::max(bottom, tail.mLeftYMost);
+      bottom = std::max(bottom, tail.mRightYMost);
       break;
     case NS_STYLE_CLEAR_LEFT:
-      blockEnd = std::max(blockEnd, aWM.IsBidiLTR() ? tail.mLeftBEnd
-                                                    : tail.mRightBEnd);
+      bottom = std::max(bottom, tail.mLeftYMost);
       break;
     case NS_STYLE_CLEAR_RIGHT:
-      blockEnd = std::max(blockEnd, aWM.IsBidiLTR() ? tail.mRightBEnd
-                                                    : tail.mLeftBEnd);
+      bottom = std::max(bottom, tail.mRightYMost);
       break;
     default:
       // Do nothing
       break;
   }
 
-  blockEnd -= origin.B(aWM);
+  bottom -= mY;
 
-  return blockEnd;
+  return bottom;
 }
 
 bool
 nsFloatManager::ClearContinues(uint8_t aBreakType) const
 {
   return ((mPushedLeftFloatPastBreak || mSplitLeftFloatAcrossBreak) &&
           (aBreakType == NS_STYLE_CLEAR_BOTH ||
            aBreakType == NS_STYLE_CLEAR_LEFT)) ||
          ((mPushedRightFloatPastBreak || mSplitRightFloatAcrossBreak) &&
           (aBreakType == NS_STYLE_CLEAR_BOTH ||
            aBreakType == NS_STYLE_CLEAR_RIGHT));
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // FloatInfo
 
-nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, WritingMode aWM,
-                                     const LogicalRect& aRect)
-  : mFrame(aFrame), mRect(aRect), mWritingMode(aWM)
+nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, const nsRect& aRect)
+  : mFrame(aFrame), mRect(aRect)
 {
   MOZ_COUNT_CTOR(nsFloatManager::FloatInfo);
 }
 
 #ifdef NS_BUILD_REFCNT_LOGGING
 nsFloatManager::FloatInfo::FloatInfo(const FloatInfo& aOther)
   : mFrame(aOther.mFrame),
     mRect(aOther.mRect),
-    mWritingMode(aOther.mWritingMode),
-    mLeftBEnd(aOther.mLeftBEnd),
-    mRightBEnd(aOther.mRightBEnd)
+    mLeftYMost(aOther.mLeftYMost),
+    mRightYMost(aOther.mRightYMost)
 {
   MOZ_COUNT_CTOR(nsFloatManager::FloatInfo);
 }
 
 nsFloatManager::FloatInfo::~FloatInfo()
 {
   MOZ_COUNT_DTOR(nsFloatManager::FloatInfo);
 }
@@ -579,18 +536,17 @@ nsAutoFloatManager::~nsAutoFloatManager(
 }
 
 nsresult
 nsAutoFloatManager::CreateFloatManager(nsPresContext *aPresContext)
 {
   // Create a new float manager and install it in the reflow
   // state. `Remember' the old float manager so we can restore it
   // later.
-  mNew = new nsFloatManager(aPresContext->PresShell(),
-                            mReflowState.GetWritingMode());
+  mNew = new nsFloatManager(aPresContext->PresShell());
   if (! mNew)
     return NS_ERROR_OUT_OF_MEMORY;
 
 #ifdef NOISY_FLOATMANAGER
   printf("constructed new float manager %p (replacing %p)\n",
          mNew, mReflowState.mFloatManager);
 #endif
 
--- a/layout/generic/nsFloatManager.h
+++ b/layout/generic/nsFloatManager.h
@@ -8,207 +8,155 @@
 
 #ifndef nsFloatManager_h_
 #define nsFloatManager_h_
 
 #include "mozilla/Attributes.h"
 
 #include "nsIntervalSet.h"
 #include "nsCoord.h"
-#include "WritingModes.h"
+#include "nsRect.h"
 #include "nsTArray.h"
 #include "nsFrameList.h" // for DEBUG_FRAME_DUMP
 
 class nsIPresShell;
 class nsIFrame;
 struct nsHTMLReflowState;
 class nsPresContext;
 
 /**
  * The available space for content not occupied by floats is divided
- * into a sequence of rectangles in the block direction.  However, we
- * need to know not only the rectangle, but also whether it was reduced
- * (from the content rectangle) by floats that actually intruded into
- * the content rectangle.
+ * into a (vertical) sequence of rectangles.  However, we need to know
+ * not only the rectangle, but also whether it was reduced (from the
+ * content rectangle) by floats that actually intruded into the content
+ * rectangle.
  */
 struct nsFlowAreaRect {
   nsRect mRect;
   bool mHasFloats;
 
-  nsFlowAreaRect(nscoord aICoord, nscoord aBCoord,
-                 nscoord aISize, nscoord aBSize,
+  nsFlowAreaRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
                  bool aHasFloats)
-    : mRect(aICoord, aBCoord, aISize, aBSize), mHasFloats(aHasFloats) {}
+    : mRect(aX, aY, aWidth, aHeight), mHasFloats(aHasFloats) {}
 };
 
 #define NS_FLOAT_MANAGER_CACHE_SIZE 4
 
 class nsFloatManager {
 public:
-  explicit nsFloatManager(nsIPresShell* aPresShell, mozilla::WritingMode aWM);
+  explicit nsFloatManager(nsIPresShell* aPresShell);
   ~nsFloatManager();
 
   void* operator new(size_t aSize) CPP_THROW_NEW;
   void operator delete(void* aPtr, size_t aSize);
 
   static void Shutdown();
 
   /**
    * Get float region stored on the frame. (Defaults to mRect if it's
    * not there.) The float region is the area impacted by this float;
    * the coordinates are relative to the containing block frame.
    */
-  static mozilla::LogicalRect GetRegionFor(mozilla::WritingMode aWM,
-                                           nsIFrame* aFloatFrame,
-                                           nscoord aContainerWidth);
+  static nsRect GetRegionFor(nsIFrame* aFloatFrame);
   /**
    * Calculate the float region for this frame using aMargin and the
    * frame's mRect. The region includes the margins around the float,
    * but doesn't include the relative offsets.
    * Note that if the frame is or has a continuation, aMargin's top
    * and/or bottom must be zeroed by the caller.
    */
-  static mozilla::LogicalRect CalculateRegionFor(
-                                mozilla::WritingMode aWM,
-                                nsIFrame* aFloatFrame,
-                                const mozilla::LogicalMargin& aMargin,
-                                nscoord aContainerWidth);
+  static nsRect CalculateRegionFor(nsIFrame* aFloatFrame,
+                                   const nsMargin& aMargin);
   /**
    * Store the float region on the frame. The region is stored
    * as a delta against the mRect, so repositioning the frame will
    * also reposition the float region.
    */
-  static void StoreRegionFor(mozilla::WritingMode aWM,
-                             nsIFrame* aFloat,
-                             const mozilla::LogicalRect& aRegion,
-                             nscoord aContainerWidth);
+  static void StoreRegionFor(nsIFrame* aFloat, nsRect& aRegion);
 
   // Structure that stores the current state of a frame manager for
   // Save/Restore purposes.
+  struct SavedState;
+  friend struct SavedState;
   struct SavedState {
-    explicit SavedState(mozilla::WritingMode aWM)
-      : mWritingMode(aWM)
-      , mOrigin(aWM)
-    {}
   private:
     uint32_t mFloatInfoCount;
-    mozilla::WritingMode mWritingMode;
-    mozilla::LogicalPoint mOrigin;
+    nscoord mX, mY;
     bool mPushedLeftFloatPastBreak;
     bool mPushedRightFloatPastBreak;
     bool mSplitLeftFloatAcrossBreak;
     bool mSplitRightFloatAcrossBreak;
 
     friend class nsFloatManager;
   };
 
   /**
-   * Translate the current origin by the specified (dICoord, dBCoord). This
+   * Translate the current origin by the specified (dx, dy). This
    * creates a new local coordinate space relative to the current
    * coordinate space.
-   * @returns previous writing mode
    */
-  mozilla::WritingMode Translate(mozilla::WritingMode aWM,
-                                 mozilla::LogicalPoint aDOrigin,
-                                 nscoord aContainerWidth)
-  {
-    mozilla::WritingMode oldWM = mWritingMode;
-    mOrigin = mOrigin.ConvertTo(aWM, oldWM, aContainerWidth);
-    mWritingMode = aWM;
-    mOrigin += aDOrigin;
-    return oldWM;
-  }
-
-  /*
-   * Set the translation origin to a specified value instead of
-   * translating by a delta.
-   */
-  void SetTranslation(mozilla::WritingMode aWM,
-                      mozilla::LogicalPoint aOrigin)
-  {
-    mWritingMode = aWM;
-    mOrigin = aOrigin;
-  }
-
-  void Untranslate(mozilla::WritingMode aWM,
-                   mozilla::LogicalPoint aDOrigin,
-                   nscoord aContainerWidth)
-  {
-    mOrigin -= aDOrigin;
-    mOrigin = mOrigin.ConvertTo(aWM, mWritingMode, aContainerWidth);
-    mWritingMode = aWM;
-  }
+  void Translate(nscoord aDx, nscoord aDy) { mX += aDx; mY += aDy; }
 
   /**
    * Returns the current translation from local coordinate space to
    * world coordinate space. This represents the accumulated calls to
    * Translate().
    */
-  void GetTranslation(mozilla::WritingMode& aWM,
-                      mozilla::LogicalPoint& aOrigin) const
-  {
-    aWM = mWritingMode;
-    aOrigin = mOrigin;
-  }
+  void GetTranslation(nscoord& aX, nscoord& aY) const { aX = mX; aY = mY; }
 
   /**
    * Get information about the area available to content that flows
    * around floats.  Two different types of space can be requested:
-   *   BAND_FROM_POINT: returns the band containing block-dir coordinate
-   *     |aBCoord| (though actually with the top truncated to begin at
-   *     aBCoord), but up to at most |aBSize| (which may be nscoord_MAX).
-   *     This will return the tallest rectangle whose block start is
-   *     |aBCoord| and in which there are no changes in what floats are
-   *     on the sides of that rectangle, but will limit the block size
-   *     of the rectangle to |aBSize|.  The inline start and end edges
-   *     of the rectangle give the area available for line boxes in that
-   *     space. The inline size of this resulting rectangle will not be
-   *     negative.
-   *   WIDTH_WITHIN_HEIGHT: This returns a rectangle whose block start
-   *     is aBCoord and whose block size is exactly aBSize.  Its inline
-   *     start and end edges give the corresponding edges of the space
-   *     that can be used for line boxes *throughout* that space.  (It
-   *     is possible that more inline space could be used in part of the
-   *     space if a float begins or ends in it.)  The inline size of the
-   *     resulting rectangle can be negative.
+   *   BAND_FROM_POINT: returns the band containing vertical coordinate
+   *     |aY| (though actually with the top truncated to begin at aY),
+   *     but up to at most |aHeight| (which may be nscoord_MAX).
+   *     This will return the tallest rectangle whose top is |aY| and in
+   *     which there are no changes in what floats are on the sides of
+   *     that rectangle, but will limit the height of the rectangle to
+   *     |aHeight|.  The left and right edges of the rectangle give the
+   *     area available for line boxes in that space.  The width of this
+   *     resulting rectangle will not be negative.
+   *   WIDTH_WITHIN_HEIGHT: This returns a rectangle whose top is aY and
+   *     whose height is exactly aHeight.  Its left and right edges give
+   *     the left and right edges of the space that can be used for line
+   *     boxes *throughout* that space.  (It is possible that more
+   *     horizontal space could be used in part of the space if a float
+   *     begins or ends in it.)  The width of the resulting rectangle
+   *     can be negative.
    *
-   * @param aBCoord [in] block-dir coordinate for block start of
-   *           available space desired
-   * @param aBSize [in] see above
+   * @param aY [in] vertical coordinate for top of available space
+   *           desired
+   * @param aHeight [in] see above
    * @param aContentArea [in] an nsRect representing the content area
    * @param aState [in] If null, use the current state, otherwise, do
    *                    computation based only on floats present in the given
    *                    saved state.
    * @return An nsFlowAreaRect whose:
    *           mRect is the resulting rectangle for line boxes.  It will not
-   *             extend beyond aContentArea's inline bounds, but may be
+   *             extend beyond aContentArea's horizontal bounds, but may be
    *             narrower when floats are present.
    *          mBandHasFloats is whether there are floats at the sides of the
    *            return value including those that do not reduce the line box
-   *            inline size at all (because they are entirely in the margins)
+   *            width at all (because they are entirely in the margins)
    *
-   * aBCoord and aAvailSpace are positioned relative to the current translation
+   * aY and aAvailSpace are positioned relative to the current translation
    */
   enum BandInfoType { BAND_FROM_POINT, WIDTH_WITHIN_HEIGHT };
-  nsFlowAreaRect GetFlowArea(mozilla::WritingMode aWM,
-                             nscoord aBCoord, BandInfoType aInfoType,
-                             nscoord aBSize, mozilla::LogicalRect aContentArea,
-                             SavedState* aState, nscoord mContainerWidth) const;
+  nsFlowAreaRect GetFlowArea(nscoord aY, BandInfoType aInfoType,
+                             nscoord aHeight, nsRect aContentArea,
+                             SavedState* aState) const;
 
   /**
-   * Add a float that comes after all floats previously added.  Its
-   * block start must be even with or below the top of all previous
-   * floats.
+   * Add a float that comes after all floats previously added.  Its top
+   * must be even with or below the top of all previous floats.
    *
    * aMarginRect is relative to the current translation.  The caller
    * must ensure aMarginRect.height >= 0 and aMarginRect.width >= 0.
    */
-  nsresult AddFloat(nsIFrame* aFloatFrame,
-                    const mozilla::LogicalRect& aMarginRect,
-                    mozilla::WritingMode aWM, nscoord aContainerWidth);
+  nsresult AddFloat(nsIFrame* aFloatFrame, const nsRect& aMarginRect);
 
   /**
    * Notify that we tried to place a float that could not fit at all and
    * had to be pushed to the next page/column?  (If so, we can't place
    * any more floats in this page/column because of the rule that the
    * top of a float cannot be above the top of an earlier float.  It
    * also means that any clear needs to continue to the next column.)
    */
@@ -247,28 +195,24 @@ public:
    * Methods for dealing with the propagation of float damage during
    * reflow.
    */
   bool HasFloatDamage() const
   {
     return !mFloatDamage.IsEmpty();
   }
 
-  void IncludeInDamage(mozilla::WritingMode aWM,
-                       nscoord aIntervalBegin, nscoord aIntervalEnd)
+  void IncludeInDamage(nscoord aIntervalBegin, nscoord aIntervalEnd)
   {
-    mFloatDamage.IncludeInterval(aIntervalBegin + mOrigin.B(aWM),
-                                 aIntervalEnd + mOrigin.B(aWM));
+    mFloatDamage.IncludeInterval(aIntervalBegin + mY, aIntervalEnd + mY);
   }
 
-  bool IntersectsDamage(mozilla::WritingMode aWM,
-                        nscoord aIntervalBegin, nscoord aIntervalEnd) const
+  bool IntersectsDamage(nscoord aIntervalBegin, nscoord aIntervalEnd) const
   {
-    return mFloatDamage.Intersects(aIntervalBegin + mOrigin.B(aWM),
-                                   aIntervalEnd + mOrigin.B(aWM));
+    return mFloatDamage.Intersects(aIntervalBegin + mY, aIntervalEnd + mY);
   }
 
   /**
    * Saves the current state of the float manager into aState.
    */
   void PushState(SavedState* aState);
 
   /**
@@ -279,51 +223,46 @@ public:
    * be used once --- although it can be omitted; saved states can be ignored.
    * States must be popped in the reverse order they were pushed.  A
    * call to PopState invalidates any saved states Pushed after the
    * state passed to PopState was pushed.
    */
   void PopState(SavedState* aState);
 
   /**
-   * Get the block start of the last float placed into the float
-   * manager, to enforce the rule that a float can't be above an earlier
-   * float. Returns the minimum nscoord value if there are no floats.
+   * Get the top of the last float placed into the float manager, to
+   * enforce the rule that a float can't be above an earlier float.
+   * Returns the minimum nscoord value if there are no floats.
    *
    * The result is relative to the current translation.
    */
-  nscoord GetLowestFloatTop(mozilla::WritingMode aWM,
-                            nscoord aContainerWidth) const;
+  nscoord GetLowestFloatTop() const;
 
   /**
-   * Return the coordinate of the lowest float matching aBreakType in
-   * this float manager. Returns aBCoord if there are no matching
-   * floats.
+   * Return the coordinate of the lowest float matching aBreakType in this
+   * float manager. Returns aY if there are no matching floats.
    *
-   * Both aBCoord and the result are relative to the current translation.
+   * Both aY and the result are relative to the current translation.
    */
   enum {
     // Tell ClearFloats not to push to nscoord_MAX when floats have been
     // pushed to the next page/column.
     DONT_CLEAR_PUSHED_FLOATS = (1<<0)
   };
-  nscoord ClearFloats(mozilla::WritingMode aWM, nscoord aBCoord,
-                      uint8_t aBreakType, nscoord aContainerWidth,
-                      uint32_t aFlags = 0) const;
+  nscoord ClearFloats(nscoord aY, uint8_t aBreakType, uint32_t aFlags = 0) const;
 
   /**
    * Checks if clear would pass into the floats' BFC's next-in-flow,
    * i.e. whether floats affecting this clear have continuations.
    */
   bool ClearContinues(uint8_t aBreakType) const;
 
   void AssertStateMatches(SavedState *aState) const
   {
-    NS_ASSERTION(aState->mWritingMode == mWritingMode &&
-                 aState->mOrigin == mOrigin &&
+    NS_ASSERTION(aState->mX == mX && aState->mY == mY &&
                  aState->mPushedLeftFloatPastBreak ==
                    mPushedLeftFloatPastBreak &&
                  aState->mPushedRightFloatPastBreak ==
                    mPushedRightFloatPastBreak &&
                  aState->mSplitLeftFloatAcrossBreak ==
                    mSplitLeftFloatAcrossBreak &&
                  aState->mSplitRightFloatAcrossBreak ==
                    mSplitRightFloatAcrossBreak &&
@@ -337,34 +276,28 @@ public:
    */
   nsresult List(FILE* out) const;
 #endif
 
 private:
 
   struct FloatInfo {
     nsIFrame *const mFrame;
-    mozilla::LogicalRect mRect;
-    mozilla::WritingMode mWritingMode;
-    // The lowest block-ends of left/right floats up to and including
-    // this one.
-    nscoord mLeftBEnd, mRightBEnd;
+    nsRect mRect;
+    // The lowest bottoms of left/right floats up to and including this one.
+    nscoord mLeftYMost, mRightYMost;
 
-    FloatInfo(nsIFrame* aFrame, mozilla::WritingMode aWM,
-              const mozilla::LogicalRect& aRect);
+    FloatInfo(nsIFrame* aFrame, const nsRect& aRect);
 #ifdef NS_BUILD_REFCNT_LOGGING
     FloatInfo(const FloatInfo& aOther);
     ~FloatInfo();
 #endif
   };
 
-  mozilla::WritingMode mWritingMode;
-  mozilla::LogicalPoint mOrigin;  // translation from local to global
-                                  // coordinate space
-
+  nscoord         mX, mY;     // translation from local to global coordinate space
   nsTArray<FloatInfo> mFloats;
   nsIntervalSet   mFloatDamage;
 
   // Did we try to place a float that could not fit at all and had to be
   // pushed to the next page/column?  If so, we can't place any more
   // floats in this page/column because of the rule that the top of a
   // float cannot be above the top of an earlier float.  And we also
   // need to apply this information to 'clear', and thus need to
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -911,18 +911,20 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra
   aFrame->WillReflow(mPresContext);
 
   // Adjust spacemanager coordinate system for the frame.
   nsHTMLReflowMetrics metrics(lineWM);
 #ifdef DEBUG
   metrics.ISize(lineWM) = nscoord(0xdeadbeef);
   metrics.BSize(lineWM) = nscoord(0xdeadbeef);
 #endif
-  LogicalPoint tPt = pfd->mBounds.Origin(lineWM);
-  WritingMode oldWM = mFloatManager->Translate(lineWM, tPt, mContainerWidth);
+  nsRect physicalBounds = pfd->mBounds.GetPhysicalRect(lineWM, mContainerWidth);
+  nscoord tx = physicalBounds.x;
+  nscoord ty = physicalBounds.y;
+  mFloatManager->Translate(tx, ty);
 
   int32_t savedOptionalBreakOffset;
   gfxBreakPriority savedOptionalBreakPriority;
   nsIFrame* savedOptionalBreakFrame =
     GetLastOptionalBreakPosition(&savedOptionalBreakOffset,
                                  &savedOptionalBreakPriority);
 
   if (!isText) {
@@ -999,17 +1001,17 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra
         isEmpty = !pfd->mSpan->mHasNonemptyContent && pfd->mFrame->IsSelfEmpty();
       } else {
         isEmpty = pfd->mFrame->IsEmpty();
       }
     }
   }
   pfd->mIsEmpty = isEmpty;
 
-  mFloatManager->Untranslate(oldWM, tPt, mContainerWidth);
+  mFloatManager->Translate(-tx, -ty);
 
   NS_ASSERTION(metrics.ISize(lineWM) >= 0, "bad inline size");
   NS_ASSERTION(metrics.BSize(lineWM) >= 0,"bad block size");
   if (metrics.ISize(lineWM) < 0) {
     metrics.ISize(lineWM) = 0;
   }
   if (metrics.BSize(lineWM) < 0) {
     metrics.BSize(lineWM) = 0;