Backed out 4 changesets (bug 1055658) for M5 bustage on a CLOSED TREE
authorNigel Babu <nigelbabu@gmail.com>
Mon, 12 Jan 2015 10:43:11 +0530
changeset 223248 b684185c1c542c75868adf0b7d16293d3cc6b1c7
parent 223247 e341d9d84469c1e4c93df41799b5edefaab09fbe
child 223249 922d760d0dcf2d5418f85ccbab105c4fa5929643
push id10769
push usercbook@mozilla.com
push dateMon, 12 Jan 2015 14:15:52 +0000
treeherderfx-team@0e9765732906 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1055658
milestone37.0a1
backs out3cbd9323c8963df4f15b83a19e6efa7a74a2c23e
99e071295c420e0eb237b287be1546975148ba73
55119d19e4c5f127b19b28c930c12a8ab4dc3e5b
e82f640cb53fa9765f4fefcacdb6d351fe6cf887
Backed out 4 changesets (bug 1055658) for M5 bustage on a CLOSED TREE Backed out changeset 3cbd9323c896 (bug 1055658) Backed out changeset 99e071295c42 (bug 1055658) Backed out changeset 55119d19e4c5 (bug 1055658) Backed out changeset e82f640cb53f (bug 1055658)
layout/generic/RubyReflowState.cpp
layout/generic/RubyReflowState.h
layout/generic/moz.build
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsHTMLReflowState.h
layout/generic/nsLineLayout.cpp
layout/generic/nsLineLayout.h
layout/generic/nsRubyBaseContainerFrame.cpp
layout/generic/nsRubyBaseContainerFrame.h
layout/generic/nsRubyFrame.cpp
layout/generic/nsRubyTextContainerFrame.cpp
layout/generic/nsRubyTextContainerFrame.h
layout/reftests/css-ruby/reftest.list
layout/reftests/css-ruby/relative-positioning-1-ref.html
layout/reftests/css-ruby/relative-positioning-1.html
layout/reftests/css-ruby/relative-positioning-2-ref.html
layout/reftests/css-ruby/relative-positioning-2.html
new file mode 100644
--- /dev/null
+++ b/layout/generic/RubyReflowState.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* states and methods used while laying out a ruby segment */
+
+#include "RubyReflowState.h"
+
+using namespace mozilla;
+
+RubyReflowState::RubyReflowState(
+  WritingMode aLineWM,
+  const nsTArray<nsRubyTextContainerFrame*>& aTextContainers)
+  : mCurrentContainerIndex(kBaseContainerIndex)
+{
+  uint32_t rtcCount = aTextContainers.Length();
+  mTextContainers.SetCapacity(rtcCount);
+  for (uint32_t i = 0; i < rtcCount; i++) {
+    mTextContainers.AppendElement(
+      TextContainerInfo(aLineWM, aTextContainers[i]));
+  }
+}
new file mode 100644
--- /dev/null
+++ b/layout/generic/RubyReflowState.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* states and methods used while laying out a ruby segment */
+
+#ifndef mozilla_RubyReflowState_h_
+#define mozilla_RubyReflowState_h_
+
+#include "mozilla/Attributes.h"
+#include "WritingModes.h"
+#include "nsTArray.h"
+
+#define RTC_ARRAY_SIZE 1
+
+class nsRubyTextContainerFrame;
+
+namespace mozilla {
+
+class MOZ_STACK_CLASS RubyReflowState MOZ_FINAL
+{
+public:
+  explicit RubyReflowState(
+    WritingMode aLineWM,
+    const nsTArray<nsRubyTextContainerFrame*>& aTextContainers);
+
+  struct TextContainerInfo
+  {
+    nsRubyTextContainerFrame* mFrame;
+    LogicalSize mLineSize;
+
+    TextContainerInfo(WritingMode aLineWM, nsRubyTextContainerFrame* aFrame)
+      : mFrame(aFrame)
+      , mLineSize(aLineWM) { }
+  };
+
+  void AdvanceCurrentContainerIndex() { mCurrentContainerIndex++; }
+
+  void SetTextContainerInfo(int32_t aIndex,
+                            nsRubyTextContainerFrame* aContainer,
+                            const LogicalSize& aLineSize)
+  {
+    MOZ_ASSERT(mTextContainers[aIndex].mFrame == aContainer);
+    mTextContainers[aIndex].mLineSize = aLineSize;
+  }
+
+  const TextContainerInfo&
+    GetCurrentTextContainerInfo(nsRubyTextContainerFrame* aFrame) const
+  {
+    MOZ_ASSERT(mTextContainers[mCurrentContainerIndex].mFrame == aFrame);
+    return mTextContainers[mCurrentContainerIndex];
+  }
+
+private:
+  static MOZ_CONSTEXPR_VAR int32_t kBaseContainerIndex = -1;
+  // The index of the current reflowing container. When it equals to
+  // kBaseContainerIndex, we are reflowing ruby base. Otherwise, it
+  // stands for the index of text containers in the ruby segment.
+  int32_t mCurrentContainerIndex;
+
+  nsAutoTArray<TextContainerInfo, RTC_ARRAY_SIZE> mTextContainers;
+};
+
+}
+
+#endif // mozilla_RubyReflowState_h_
--- a/layout/generic/moz.build
+++ b/layout/generic/moz.build
@@ -90,16 +90,17 @@ UNIFIED_SOURCES += [
     'nsSimplePageSequenceFrame.cpp',
     'nsSplittableFrame.cpp',
     'nsSubDocumentFrame.cpp',
     'nsTextFrame.cpp',
     'nsTextFrameUtils.cpp',
     'nsTextRunTransformations.cpp',
     'nsVideoFrame.cpp',
     'nsViewportFrame.cpp',
+    'RubyReflowState.cpp',
     'RubyUtils.cpp',
     'ScrollbarActivity.cpp',
     'StickyScrollContainer.cpp',
     'TextOverflow.cpp',
 ]
 
 # nsLineLayout.cpp needs to be built separately because it uses plarena.h.
 # nsPluginFrame.cpp needs to be built separately because of name clashes in the OS X headers.
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -67,16 +67,17 @@ nsHTMLReflowState::nsHTMLReflowState(nsP
   MOZ_ASSERT(aPresContext, "no pres context");
   MOZ_ASSERT(aFrame, "no frame");
   MOZ_ASSERT(aPresContext == aFrame->PresContext(), "wrong pres context");
   parentReflowState = nullptr;
   AvailableISize() = aAvailableSpace.ISize(mWritingMode);
   AvailableBSize() = aAvailableSpace.BSize(mWritingMode);
   mFloatManager = nullptr;
   mLineLayout = nullptr;
+  mRubyReflowState = nullptr;
   memset(&mFlags, 0, sizeof(mFlags));
   mDiscoveredClearance = nullptr;
   mPercentHeightObserver = nullptr;
 
   if (aFlags & DUMMY_PARENT_REFLOW_STATE) {
     mFlags.mDummyParentReflowState = true;
   }
 
@@ -202,16 +203,17 @@ nsHTMLReflowState::nsHTMLReflowState(nsP
     }
   }
 
   mFloatManager = aParentReflowState.mFloatManager;
   if (frame->IsFrameOfType(nsIFrame::eLineParticipant))
     mLineLayout = aParentReflowState.mLineLayout;
   else
     mLineLayout = nullptr;
+  mRubyReflowState = nullptr;
 
   // Note: mFlags was initialized as a copy of aParentReflowState.mFlags up in
   // this constructor's init list, so the only flags that we need to explicitly
   // initialize here are those that may need a value other than our parent's.
   mFlags.mNextInFlowUntouched = aParentReflowState.mFlags.mNextInFlowUntouched &&
     CheckNextInFlowParenthood(aFrame, aParentReflowState.frame);
   mFlags.mAssumingHScrollbar = mFlags.mAssumingVScrollbar = false;
   mFlags.mHasClearance = false;
--- a/layout/generic/nsHTMLReflowState.h
+++ b/layout/generic/nsHTMLReflowState.h
@@ -16,16 +16,20 @@
 
 class nsPresContext;
 class nsRenderingContext;
 class nsFloatManager;
 class nsLineLayout;
 class nsIPercentHeightObserver;
 struct nsHypotheticalBox;
 
+namespace mozilla {
+class RubyReflowState;
+}
+
 /**
  * @return aValue clamped to [aMinValue, aMaxValue].
  *
  * @note This function needs to handle aMinValue > aMaxValue. In that case,
  *       aMinValue is returned.
  * @see http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
  * @see http://www.w3.org/TR/CSS21/visudet.html#min-max-heights
  */
@@ -253,16 +257,19 @@ struct nsHTMLReflowState : public nsCSSO
   const nsHTMLReflowState* parentReflowState;
 
   // pointer to the float manager associated with this area
   nsFloatManager* mFloatManager;
 
   // LineLayout object (only for inline reflow; set to nullptr otherwise)
   nsLineLayout*    mLineLayout;
 
+  // RubyReflowState object (only for ruby reflow; set to nullptr otherwise)
+  mozilla::RubyReflowState* mRubyReflowState;
+
   // The appropriate reflow state for the containing block (for
   // percentage widths, etc.) of this reflow state's frame.
   const nsHTMLReflowState *mCBReflowState;
 
   // The type of frame, from css's perspective. This value is
   // initialized by the Init method below.
   nsCSSFrameType   mFrameType;
 
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -62,16 +62,17 @@ nsLineLayout::nsLineLayout(nsPresContext
     mLastOptionalBreakFrame(nullptr),
     mForceBreakFrame(nullptr),
     mBlockRS(nullptr),/* XXX temporary */
     mLastOptionalBreakPriority(gfxBreakPriority::eNoBreak),
     mLastOptionalBreakFrameOffset(-1),
     mForceBreakFrameOffset(-1),
     mMinLineBSize(0),
     mTextIndent(0),
+    mRubyReflowState(nullptr),
     mFirstLetterStyleOK(false),
     mIsTopOfPage(false),
     mImpactedByFloats(false),
     mLastFloatWasLetterFrame(false),
     mLineIsEmpty(false),
     mLineEndsInBR(false),
     mNeedBackup(false),
     mInFirstLine(false),
@@ -247,31 +248,16 @@ nsLineLayout::BeginLineReflow(nscoord aI
 
     psd->mICoord += indent;
   }
 
   PerFrameData* pfd = NewPerFrameData(mBlockReflowState->frame);
   pfd->mAscent = 0;
   pfd->mSpan = psd;
   psd->mFrame = pfd;
-  nsIFrame* frame = mBlockReflowState->frame;
-  if (frame->GetType() == nsGkAtoms::rubyTextContainerFrame) {
-    // Ruby text container won't be reflowed via ReflowFrame, hence the
-    // relative positioning information should be recorded here.
-    MOZ_ASSERT(mBaseLineLayout != this);
-    pfd->mRelativePos =
-      mBlockReflowState->mStyleDisplay->IsRelativelyPositionedStyle();
-    if (pfd->mRelativePos) {
-      MOZ_ASSERT(
-        mBlockReflowState->GetWritingMode() == frame->GetWritingMode(),
-        "mBlockReflowState->frame == frame, "
-        "hence they should have identical writing mode");
-      pfd->mOffsets = mBlockReflowState->ComputedLogicalOffsets();
-    }
-  }
 }
 
 void
 nsLineLayout::EndLineReflow()
 {
 #ifdef NOISY_REFLOW
   nsFrame::ListTag(stdout, mBlockReflowState->frame);
   printf(": EndLineReflow: width=%d\n", mRootSpan->mICoord - mRootSpan->mIStart);
@@ -684,17 +670,16 @@ nsLineLayout::NewPerFrameData(nsIFrame* 
   pfd->mIsBullet = false;
   pfd->mSkipWhenTrimmingWhitespace = false;
   pfd->mIsEmpty = false;
   pfd->mIsLinkedToBase = false;
 
   WritingMode frameWM = aFrame->GetWritingMode();
   WritingMode lineWM = mRootSpan->mWritingMode;
   pfd->mBounds = LogicalRect(lineWM);
-  pfd->mOverflowAreas.Clear();
   pfd->mMargin = LogicalMargin(lineWM);
   pfd->mBorderPadding = LogicalMargin(lineWM);
   pfd->mOffsets = LogicalMargin(frameWM);
 
   pfd->mJustificationInfo = JustificationInfo();
   pfd->mJustificationAssignment = JustificationAssignment();
 
 #ifdef DEBUG
@@ -880,16 +865,20 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra
     // includes room for the side margins.
     // For now, set the available block-size to unconstrained always.
     LogicalSize availSize = mBlockReflowState->ComputedSize(frameWM);
     availSize.BSize(frameWM) = NS_UNCONSTRAINEDSIZE;
     reflowStateHolder.emplace(mPresContext, *psd->mReflowState,
                               aFrame, availSize);
     nsHTMLReflowState& reflowState = *reflowStateHolder;
     reflowState.mLineLayout = this;
+    if (mRubyReflowState) {
+      reflowState.mRubyReflowState = mRubyReflowState;
+      mRubyReflowState = nullptr;
+    }
     reflowState.mFlags.mIsTopOfPage = mIsTopOfPage;
     if (reflowState.ComputedISize() == NS_UNCONSTRAINEDSIZE) {
       reflowState.AvailableISize() = availableSpaceOnLine;
     }
     WritingMode stateWM = reflowState.GetWritingMode();
     pfd->mMargin =
       reflowState.ComputedLogicalMargin().ConvertTo(lineWM, stateWM);
     pfd->mBorderPadding =
@@ -3027,55 +3016,16 @@ nsLineLayout::TextAlignLine(nsLineBox* a
 }
 
 void
 nsLineLayout::RelativePositionFrames(nsOverflowAreas& aOverflowAreas)
 {
   RelativePositionFrames(mRootSpan, aOverflowAreas);
 }
 
-// This method applies any relative positioning to the given frame.
-void
-nsLineLayout::ApplyRelativePositioning(PerFrameData* aPFD)
-{
-  if (!aPFD->mRelativePos) {
-    return;
-  }
-
-  nsIFrame* frame = aPFD->mFrame;
-  WritingMode frameWM = frame->GetWritingMode();
-  LogicalPoint origin = frame->GetLogicalPosition(mContainerWidth);
-  // right and bottom are handled by
-  // nsHTMLReflowState::ComputeRelativeOffsets
-  nsHTMLReflowState::ApplyRelativePositioning(frame, frameWM,
-                                              aPFD->mOffsets, &origin,
-                                              mContainerWidth);
-  frame->SetPosition(frameWM, origin, mContainerWidth);
-}
-
-// This method do relative positioning for ruby annotations.
-void
-nsLineLayout::RelativePositionAnnotations(PerSpanData* aRubyPSD,
-                                          nsOverflowAreas& aOverflowAreas)
-{
-  MOZ_ASSERT(aRubyPSD->mFrame->mFrame->GetType() == nsGkAtoms::rubyFrame);
-  for (PerFrameData* pfd = aRubyPSD->mFirstFrame; pfd; pfd = pfd->mNext) {
-    MOZ_ASSERT(pfd->mFrame->GetType() == nsGkAtoms::rubyBaseContainerFrame);
-    for (PerFrameData* rtc = pfd->mNextAnnotation;
-         rtc; rtc = rtc->mNextAnnotation) {
-      nsIFrame* rtcFrame = rtc->mFrame;
-      MOZ_ASSERT(rtcFrame->GetType() == nsGkAtoms::rubyTextContainerFrame);
-      ApplyRelativePositioning(rtc);
-      nsOverflowAreas rtcOverflowAreas;
-      RelativePositionFrames(rtc->mSpan, rtcOverflowAreas);
-      aOverflowAreas.UnionWith(rtcOverflowAreas + rtcFrame->GetPosition());
-    }
-  }
-}
-
 void
 nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas)
 {
   nsOverflowAreas overflowAreas;
   WritingMode wm = psd->mWritingMode;
   if (psd != mRootSpan) {
     // The span's overflow areas come in three parts:
     // -- this frame's width and height
@@ -3104,17 +3054,26 @@ nsLineLayout::RelativePositionFrames(Per
     overflowAreas.VisualOverflow() = rect.GetPhysicalRect(wm, mContainerWidth);
     overflowAreas.ScrollableOverflow() = overflowAreas.VisualOverflow();
   }
 
   for (PerFrameData* pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) {
     nsIFrame* frame = pfd->mFrame;
 
     // Adjust the origin of the frame
-    ApplyRelativePositioning(pfd);
+    if (pfd->mRelativePos) {
+      WritingMode frameWM = frame->GetWritingMode();
+      LogicalPoint origin = frame->GetLogicalPosition(mContainerWidth);
+      // right and bottom are handled by
+      // nsHTMLReflowState::ComputeRelativeOffsets
+      nsHTMLReflowState::ApplyRelativePositioning(frame, frameWM,
+                                                  pfd->mOffsets, &origin,
+                                                  mContainerWidth);
+      frame->SetPosition(frameWM, origin, mContainerWidth);
+    }
 
     // We must position the view correctly before positioning its
     // descendants so that widgets are positioned properly (since only
     // some views have widgets).
     if (frame->HasView())
       nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, frame,
         frame->GetView(), pfd->mOverflowAreas.VisualOverflow(),
         NS_FRAME_NO_SIZE_VIEW);
@@ -3160,21 +3119,16 @@ nsLineLayout::RelativePositionFrames(Per
       nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, frame,
                                                  frame->GetView(),
                                                  r.VisualOverflow(),
                                                  NS_FRAME_NO_MOVE_VIEW);
 
     overflowAreas.UnionWith(r + frame->GetPosition());
   }
 
-  // Also compute relative position in the annotations.
-  if (psd->mFrame->mFrame->GetType() == nsGkAtoms::rubyFrame) {
-    RelativePositionAnnotations(psd, overflowAreas);
-  }
-
   // If we just computed a spans combined area, we need to update its
   // overflow rect...
   if (psd != mRootSpan) {
     PerFrameData* spanPFD = psd->mFrame;
     nsIFrame* frame = spanPFD->mFrame;
     frame->FinishAndStoreOverflow(overflowAreas, frame->GetSize());
   }
   aOverflowAreas = overflowAreas;
--- a/layout/generic/nsLineLayout.h
+++ b/layout/generic/nsLineLayout.h
@@ -22,16 +22,20 @@
 #include "plarena.h"
 #include "gfxTypes.h"
 #include "WritingModes.h"
 #include "JustificationUtils.h"
 
 class nsFloatManager;
 struct nsStyleText;
 
+namespace mozilla {
+class RubyReflowState;
+}
+
 class nsLineLayout {
 public:
   /**
    * @param aBaseLineLayout the nsLineLayout for ruby base,
    * nullptr if no separate base nsLineLayout is needed.
    */
   nsLineLayout(nsPresContext* aPresContext,
                nsFloatManager* aFloatManager,
@@ -93,16 +97,23 @@ public:
   }
 
   int32_t GetCurrentSpanCount() const;
 
   void SplitLineTo(int32_t aNewCount);
 
   bool IsZeroBSize();
 
+  // The ruby layout will be passed to the next frame to be reflowed
+  // via the HTML reflow state.
+  void SetRubyReflowState(mozilla::RubyReflowState* aRubyReflowState)
+  {
+    mRubyReflowState = aRubyReflowState;
+  }
+
   // Reflows the frame and returns the reflow status. aPushedFrame is true
   // if the frame is pushed to the next line because it doesn't fit.
   void ReflowFrame(nsIFrame* aFrame,
                    nsReflowStatus& aReflowStatus,
                    nsHTMLReflowMetrics* aMetrics,
                    bool& aPushedFrame);
 
   void AddBulletFrame(nsIFrame* aFrame, const nsHTMLReflowMetrics& aMetrics);
@@ -549,16 +560,20 @@ protected:
   // max-element-size calculation.
   nscoord mTextIndent;
 
   // This state varies during the reflow of a line but is line
   // "global" state not span "local" state.
   int32_t mLineNumber;
   mozilla::JustificationInfo mJustificationInfo;
 
+  // The ruby layout for the next frame to be reflowed.
+  // It is reset every time it is used.
+  mozilla::RubyReflowState* mRubyReflowState;
+
   int32_t mTotalPlacedFrames;
 
   nscoord mBStartEdge;
   nscoord mMaxStartBoxBSize;
   nscoord mMaxEndBoxBSize;
 
   nscoord mInflationMinFontSize;
 
@@ -645,21 +660,16 @@ protected:
                   nsHTMLReflowMetrics& aMetrics);
 
   void VerticalAlignFrames(PerSpanData* psd);
 
   void PlaceTopBottomFrames(PerSpanData* psd,
                             nscoord aDistanceFromStart,
                             nscoord aLineBSize);
 
-  void ApplyRelativePositioning(PerFrameData* aPFD);
-
-  void RelativePositionAnnotations(PerSpanData* aRubyPSD,
-                                   nsOverflowAreas& aOverflowAreas);
-
   void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas);
 
   bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize);
 
   struct JustificationComputationState;
   int32_t ComputeFrameJustification(PerSpanData* psd,
                                     JustificationComputationState& aState);
 
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -336,16 +336,17 @@ nsRubyBaseContainerFrame::Reflow(nsPresC
   aStatus = NS_FRAME_COMPLETE;
 
   if (!aReflowState.mLineLayout) {
     NS_ASSERTION(
       aReflowState.mLineLayout,
       "No line layout provided to RubyBaseContainerFrame reflow method.");
     return;
   }
+  MOZ_ASSERT(aReflowState.mRubyReflowState, "No ruby reflow state provided");
 
   AutoTextContainerArray textContainers;
   GetTextContainers(textContainers);
 
   MoveOverflowToChildList();
   // Ask text containers to drain overflows
   const uint32_t rtcCount = textContainers.Length();
   for (uint32_t i = 0; i < rtcCount; i++) {
@@ -488,17 +489,17 @@ nsRubyBaseContainerFrame::Reflow(nsPresC
     if (!textContainer->IsSpanContainer()) {
       rtcISize = isize;
     } else if (isize > rtcISize) {
       RubyUtils::SetReservedISize(textContainer, isize - rtcISize);
     }
 
     lineLayout->VerticalAlignLine();
     LogicalSize lineSize(lineWM, rtcISize, lineLayout->GetFinalLineBSize());
-    textContainer->SetLineSize(lineSize);
+    aReflowState.mRubyReflowState->SetTextContainerInfo(i, textContainer, lineSize);
     lineLayout->EndLineReflow();
   }
 
   nsLayoutUtils::SetBSizeFromFontMetrics(this, aDesiredSize, aReflowState,
                                          borderPadding, lineWM, frameWM);
 }
 
 /**
--- a/layout/generic/nsRubyBaseContainerFrame.h
+++ b/layout/generic/nsRubyBaseContainerFrame.h
@@ -8,18 +8,17 @@
 
 #ifndef nsRubyBaseContainerFrame_h___
 #define nsRubyBaseContainerFrame_h___
 
 #include "nsContainerFrame.h"
 #include "nsRubyTextContainerFrame.h"
 #include "nsRubyBaseFrame.h"
 #include "nsRubyTextFrame.h"
-
-#define RTC_ARRAY_SIZE 1
+#include "RubyReflowState.h"
 
 /**
  * Factory function.
  * @return a newly allocated nsRubyBaseContainerFrame (infallible)
  */
 nsContainerFrame* NS_NewRubyBaseContainerFrame(nsIPresShell* aPresShell,
                                                nsStyleContext* aContext);
 
--- a/layout/generic/nsRubyFrame.cpp
+++ b/layout/generic/nsRubyFrame.cpp
@@ -6,16 +6,17 @@
 
 /* rendering object for CSS "display: ruby" */
 #include "nsRubyFrame.h"
 #include "nsLineLayout.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "WritingModes.h"
 #include "RubyUtils.h"
+#include "RubyReflowState.h"
 #include "nsRubyBaseContainerFrame.h"
 #include "nsRubyTextContainerFrame.h"
 
 using namespace mozilla;
 
 //----------------------------------------------------------------------
 
 // Frame class boilerplate
@@ -235,19 +236,21 @@ nsRubyFrame::ReflowSegment(nsPresContext
   LogicalSize availSize(lineWM, aReflowState.AvailableISize(),
                         aReflowState.AvailableBSize());
 
   nsAutoTArray<nsRubyTextContainerFrame*, RTC_ARRAY_SIZE> textContainers;
   for (RubyTextContainerIterator iter(aBaseContainer); !iter.AtEnd(); iter.Next()) {
     textContainers.AppendElement(iter.GetTextContainer());
   }
   const uint32_t rtcCount = textContainers.Length();
+  RubyReflowState rubyReflowState(lineWM, textContainers);
 
   nsHTMLReflowMetrics baseMetrics(aReflowState);
   bool pushedFrame;
+  aReflowState.mLineLayout->SetRubyReflowState(&rubyReflowState);
   aReflowState.mLineLayout->ReflowFrame(aBaseContainer, aStatus,
                                         &baseMetrics, pushedFrame);
 
   if (NS_INLINE_IS_BREAK_BEFORE(aStatus)) {
     if (aBaseContainer != mFrames.FirstChild()) {
       // Some segments may have been reflowed before, hence it is not
       // a break-before for the ruby container.
       aStatus = NS_INLINE_LINE_BREAK_AFTER(NS_FRAME_NOT_COMPLETE);
@@ -322,20 +325,23 @@ nsRubyFrame::ReflowSegment(nsPresContext
   // lines, so we use 0 instead. (i.e. we assume that the base container
   // is adjacent to the ruby frame's block-start edge.)
   // XXX We may need to add border/padding here. See bug 1055667.
   (lineWM.IsVertical() ? baseRect.x : baseRect.y) = 0;
   // The rect for offsets of text containers.
   nsRect offsetRect = baseRect;
   for (uint32_t i = 0; i < rtcCount; i++) {
     nsRubyTextContainerFrame* textContainer = textContainers[i];
+    rubyReflowState.AdvanceCurrentContainerIndex();
+
     nsReflowStatus textReflowStatus;
     nsHTMLReflowMetrics textMetrics(aReflowState);
     nsHTMLReflowState textReflowState(aPresContext, aReflowState,
                                       textContainer, availSize);
+    textReflowState.mRubyReflowState = &rubyReflowState;
     // FIXME We probably shouldn't be using the same nsLineLayout for
     //       the text containers. But it should be fine now as we are
     //       not actually using this line layout to reflow something,
     //       but just read the writing mode from it.
     textReflowState.mLineLayout = aReflowState.mLineLayout;
     textContainer->Reflow(aPresContext, textMetrics,
                           textReflowState, textReflowStatus);
     // Ruby text containers always return NS_FRAME_COMPLETE even when
--- a/layout/generic/nsRubyTextContainerFrame.cpp
+++ b/layout/generic/nsRubyTextContainerFrame.cpp
@@ -5,16 +5,17 @@
  * http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for CSS "display: ruby-text-container" */
 
 #include "nsRubyTextContainerFrame.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "WritingModes.h"
+#include "RubyReflowState.h"
 #include "mozilla/UniquePtr.h"
 
 using namespace mozilla;
 
 //----------------------------------------------------------------------
 
 // Frame class boilerplate
 // =======================
@@ -119,20 +120,24 @@ nsRubyTextContainerFrame::UpdateSpanFlag
 nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext,
                                  nsHTMLReflowMetrics& aDesiredSize,
                                  const nsHTMLReflowState& aReflowState,
                                  nsReflowStatus& aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsRubyTextContainerFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
 
+  MOZ_ASSERT(aReflowState.mRubyReflowState, "No ruby reflow state provided");
+
   // All rt children have already been reflowed. All we need to do is
   // to report complete and return the desired size provided by the
   // ruby base container.
 
   // Although a ruby text container may have continuations, returning
   // NS_FRAME_COMPLETE here is still safe, since its parent, ruby frame,
   // ignores the status, and continuations of the ruby base container
   // will take care of our continuations.
   aStatus = NS_FRAME_COMPLETE;
   WritingMode lineWM = aReflowState.mLineLayout->GetWritingMode();
-  aDesiredSize.SetSize(lineWM, mLineSize);
+  const RubyReflowState::TextContainerInfo& info =
+    aReflowState.mRubyReflowState->GetCurrentTextContainerInfo(this);
+  aDesiredSize.SetSize(lineWM, info.mLineSize);
 }
--- a/layout/generic/nsRubyTextContainerFrame.h
+++ b/layout/generic/nsRubyTextContainerFrame.h
@@ -57,23 +57,17 @@ public:
     return GetStateBits() & NS_RUBY_TEXT_CONTAINER_IS_SPAN;
   }
 
 protected:
   friend nsContainerFrame*
     NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
                                  nsStyleContext* aContext);
   explicit nsRubyTextContainerFrame(nsStyleContext* aContext)
-    : nsRubyTextContainerFrameSuper(aContext)
-    , mLineSize(mozilla::WritingMode(aContext)) {}
+    : nsRubyTextContainerFrameSuper(aContext) {}
 
   void UpdateSpanFlag();
 
+  // For MoveOverflowToChildList
   friend class nsRubyBaseContainerFrame;
-  void SetLineSize(const mozilla::LogicalSize& aSize) { mLineSize = aSize; }
-
-  // The intended dimensions of the ruby text container. It is set by
-  // the corresponding ruby base container when the segment is reflowed,
-  // and used when the ruby text container is reflowed by its parent.
-  mozilla::LogicalSize mLineSize;
 };
 
 #endif /* nsRubyTextContainerFrame_h___ */
--- a/layout/reftests/css-ruby/reftest.list
+++ b/layout/reftests/css-ruby/reftest.list
@@ -23,18 +23,16 @@ fuzzy-if(winWidget,35,1) == dynamic-remo
 == intra-level-whitespace-1.html intra-level-whitespace-1-ref.html
 == intra-level-whitespace-2.html intra-level-whitespace-2-ref.html
 == intra-level-whitespace-3.html intra-level-whitespace-3-ref.html
 == justification-1.html justification-1-ref.html
 == justification-2.html justification-2-ref.html
 == line-height-1.html line-height-1-ref.html
 == line-height-2.html line-height-2-ref.html
 == line-height-3.html line-height-3-ref.html
-fails-if(cocoaWidget) == relative-positioning-1.html relative-positioning-1-ref.html # bug 1120280
-== relative-positioning-2.html relative-positioning-2-ref.html
 == ruby-span-1.html ruby-span-1-ref.html
 == ruby-whitespace-1.html ruby-whitespace-1-ref.html
 == ruby-whitespace-2.html ruby-whitespace-2-ref.html
 == ruby-position-horizontal.html ruby-position-horizontal-ref.html
 pref(layout.css.vertical-text.enabled,true) fails == ruby-position-vertical-lr.html ruby-position-vertical-lr-ref.html # bug 1112474
 pref(layout.css.vertical-text.enabled,true) fails == ruby-position-vertical-rl.html ruby-position-vertical-rl-ref.html # bug 1112474
 != ruby-reflow-1-opaqueruby.html ruby-reflow-1-noruby.html
 == ruby-reflow-1-transparentruby.html ruby-reflow-1-noruby.html
deleted file mode 100644
--- a/layout/reftests/css-ruby/relative-positioning-1-ref.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <title>Bug 1055658 - Relative positioning for ruby</title>
-  <style>
-    .wrapper {
-      width: 50px;
-      text-align: center;
-    }
-    .annotation, .annotation > div {
-      position: absolute;
-      line-height: 1;
-    }
-  </style>
-</head>
-<body>
-  <div style="height: 80px; line-height: 80px;">
-    <div class="wrapper" style="display: inline-block; line-height: normal; position: relative;">
-      <div class="annotation" style="top: 0;">
-        <div class="wrapper" style="top: -100%;">a<span style="position: relative; top: -10px;">b</span>c</div>
-        &nbsp; <!-- to give container a nonzero size for
-                    percent values to resolve against -->
-      </div>
-      base
-    </div>
-  </div>
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/css-ruby/relative-positioning-1.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <title>Bug 1055658 - Relative positioning for ruby</title>
-  <link rel="stylesheet" href="common.css">
-  <style>
-    body {
-      line-height: 80px;
-    }
-    rtc, rt {
-      font-size: 100% !important;
-      line-height: 1 !important;
-    }
-  </style>
-</head>
-<body>
-  <ruby style="position: relative;">
-    <rb>base</rb>
-    <rtc><rt>a<span style="position: relative; top: -10px;">b</span>c</rt></rtc>
-    <rtc><div style="width: 50px; height: 0;"></div></rtc>
-  </ruby>
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/css-ruby/relative-positioning-2-ref.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <title>Bug 1055658 - Relative positioning for ruby</title>
-  <style>
-    body {
-      font-family: monospace;
-    }
-    .annotation, .annotation > div {
-      position: absolute;
-      line-height: 1;
-    }
-  </style>
-</head>
-<body>
-  <div style="height: 80px; line-height: 80px;">
-    before
-    <div style="display: inline-block; line-height: normal; position: relative; top: 20px;">
-      <div class="annotation" style="top: 0; width: 100%;">
-        <div style="top: -100%;">
-          text1
-          <span style="position: relative; top: -20px;">text2</span>
-          <span style="position: relative; right: 10px;">text3</span>
-        </div>
-        &nbsp; <!-- to give container a nonzero size for
-                    percent values to resolve against -->
-      </div>
-      base1
-      <span style="position: relative; left: 10px;">base2</span>
-      <span style="position: relative; bottom: -20px;">base3</span>
-    </div>
-    after
-  </div>
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/css-ruby/relative-positioning-2.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <title>Bug 1055658 - Relative positioning for ruby</title>
-  <link rel="stylesheet" href="common.css">
-  <style>
-    body {
-      font-family: monospace;
-      line-height: 80px;
-    }
-    rtc, rt {
-      font-size: 100% !important;
-      line-height: 1 !important;
-    }
-  </style>
-</head>
-<body>
-  before
-  <ruby style="position: relative; top: 20px;">
-    <rb>base1</rb>
-    <rtc>text1</rtc>
-    <rb style="position: relative; left: 10px;">base2</rb>
-    <rtc style="position: relative; top: -20px;">text2</rtc>
-    <rbc style="position: relative; bottom: -20px;"><rb>base3</rb></rbc>
-    <rtc><rt style="position: relative; right: 10px;">text3</rt></rtc>
-  </ruby>
-  after
-</body>
-</html>