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 249016 b684185c1c542c75868adf0b7d16293d3cc6b1c7
parent 249015 e341d9d84469c1e4c93df41799b5edefaab09fbe
child 249017 922d760d0dcf2d5418f85ccbab105c4fa5929643
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1055658
milestone37.0a1
backs out3cbd9323c8963df4f15b83a19e6efa7a74a2c23e
99e071295c420e0eb237b287be1546975148ba73
55119d19e4c5f127b19b28c930c12a8ab4dc3e5b
e82f640cb53fa9765f4fefcacdb6d351fe6cf887
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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>