Bug 1099807 part 3 - Use specific frame type in RubyColumn. r=dholbert
authorXidorn Quan <quanxunzhen@gmail.com>
Thu, 08 Jan 2015 18:28:09 +1100
changeset 235625 fb6b0a95a55509375ba5718ee5245fe85790dd01
parent 235624 9e82574ea4f2b6e6f6d16b6b768ec850c739d75e
child 235626 2cc185fba3dac89dbc9c83ff6be5c5235c3f152d
push id366
push usercmanchester@mozilla.com
push dateThu, 08 Jan 2015 16:40:24 +0000
reviewersdholbert
bugs1099807
milestone37.0a1
Bug 1099807 part 3 - Use specific frame type in RubyColumn. r=dholbert
layout/generic/nsRubyBaseContainerFrame.cpp
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -57,18 +57,18 @@ nsRubyBaseContainerFrame::GetFrameName(n
 
 /**
  * Ruby column is a unit consists of one ruby base and all ruby
  * annotations paired with it.
  * See http://dev.w3.org/csswg/css-ruby/#ruby-pairing
  */
 struct MOZ_STACK_CLASS mozilla::RubyColumn
 {
-  nsIFrame* mBaseFrame;
-  nsAutoTArray<nsIFrame*, RTC_ARRAY_SIZE> mTextFrames;
+  nsRubyBaseFrame* mBaseFrame;
+  nsAutoTArray<nsRubyTextFrame*, RTC_ARRAY_SIZE> mTextFrames;
   RubyColumn() : mBaseFrame(nullptr) { }
 };
 
 class MOZ_STACK_CLASS RubyColumnEnumerator
 {
 public:
   RubyColumnEnumerator(nsRubyBaseContainerFrame* aRBCFrame,
                        const nsTArray<nsRubyTextContainerFrame*>& aRTCFrames);
@@ -179,20 +179,24 @@ RubyColumnEnumerator::GetFrameAtLevel(ui
   nsRubyContentFrame* frame = mFrames[aIndex];
   return !mAtIntraLevelWhitespace ||
          (frame && frame->IsIntraLevelWhitespace()) ? frame : nullptr;
 }
 
 void
 RubyColumnEnumerator::GetColumn(RubyColumn& aColumn) const
 {
-  aColumn.mBaseFrame = GetFrameAtLevel(0);
+  nsRubyContentFrame* rbFrame = GetFrameAtLevel(0);
+  MOZ_ASSERT(!rbFrame || rbFrame->GetType() == nsGkAtoms::rubyBaseFrame);
+  aColumn.mBaseFrame = static_cast<nsRubyBaseFrame*>(rbFrame);
   aColumn.mTextFrames.ClearAndRetainStorage();
   for (uint32_t i = 1, iend = mFrames.Length(); i < iend; i++) {
-    aColumn.mTextFrames.AppendElement(GetFrameAtLevel(i));
+    nsRubyContentFrame* rtFrame = GetFrameAtLevel(i);
+    MOZ_ASSERT(!rtFrame || rtFrame->GetType() == nsGkAtoms::rubyTextFrame);
+    aColumn.mTextFrames.AppendElement(static_cast<nsRubyTextFrame*>(rtFrame));
   }
 }
 
 static nscoord
 CalculateColumnPrefISize(nsRenderingContext* aRenderingContext,
                          const RubyColumnEnumerator& aEnumerator)
 {
   nscoord max = 0;
@@ -576,17 +580,17 @@ nsRubyBaseContainerFrame::ReflowColumns(
     }
     aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus);
     MOZ_ASSERT(NS_FRAME_IS_COMPLETE(aStatus) || aReflowState.mAllowLineBreak);
 
     if (column.mBaseFrame) {
       PushChildren(column.mBaseFrame, column.mBaseFrame->GetPrevSibling());
     }
     for (uint32_t i = 0; i < rtcCount; i++) {
-      nsIFrame* textFrame = column.mTextFrames[i];
+      nsRubyTextFrame* textFrame = column.mTextFrames[i];
       if (textFrame) {
         aReflowState.mTextContainers[i]->PushChildren(
           textFrame, textFrame->GetPrevSibling());
       }
     }
   } else if (NS_INLINE_IS_BREAK_AFTER(reflowStatus)) {
     // |reflowStatus| being break after here may only happen when
     // there is a break after the column just pulled, or the whole
@@ -620,19 +624,18 @@ nsRubyBaseContainerFrame::ReflowOneColum
     if (!nsContentUtils::GetNodeTextContent(aColumn.mBaseFrame->GetContent(),
                                             true, baseText)) {
       NS_RUNTIMEABORT("OOM");
     }
   }
 
   // Reflow text frames
   for (uint32_t i = 0; i < rtcCount; i++) {
-    nsIFrame* textFrame = aColumn.mTextFrames[i];
+    nsRubyTextFrame* textFrame = aColumn.mTextFrames[i];
     if (textFrame) {
-      MOZ_ASSERT(textFrame->GetType() == nsGkAtoms::rubyTextFrame);
       nsAutoString annotationText;
       if (!nsContentUtils::GetNodeTextContent(textFrame->GetContent(),
                                               true, annotationText)) {
         NS_RUNTIMEABORT("OOM");
       }
       // Per CSS Ruby spec, the content comparison for auto-hiding
       // takes place prior to white spaces collapsing (white-space)
       // and text transformation (text-transform), and ignores elements
@@ -662,17 +665,16 @@ nsRubyBaseContainerFrame::ReflowOneColum
     // may successfully place a frame because the line is empty while
     // the line of base container is not.
     aStatus = NS_INLINE_LINE_BREAK_BEFORE();
     return 0;
   }
 
   // Reflow the base frame
   if (aColumn.mBaseFrame) {
-    MOZ_ASSERT(aColumn.mBaseFrame->GetType() == nsGkAtoms::rubyBaseFrame);
     nsReflowStatus reflowStatus;
     nsHTMLReflowMetrics metrics(baseReflowState);
     RubyUtils::ClearReservedISize(aColumn.mBaseFrame);
 
     bool pushedFrame;
     baseReflowState.mLineLayout->ReflowFrame(aColumn.mBaseFrame, reflowStatus,
                                              &metrics, pushedFrame);
     MOZ_ASSERT(!NS_INLINE_IS_BREAK(reflowStatus) && !pushedFrame,
@@ -689,17 +691,17 @@ nsRubyBaseContainerFrame::ReflowOneColum
       RubyUtils::SetReservedISize(aColumn.mBaseFrame, deltaISize);
     }
   }
   for (uint32_t i = 0; i < rtcCount; i++) {
     if (aReflowState.mTextContainers[i]->IsSpanContainer()) {
       continue;
     }
     nsLineLayout* lineLayout = textReflowStates[i]->mLineLayout;
-    nsIFrame* textFrame = aColumn.mTextFrames[i];
+    nsRubyTextFrame* textFrame = aColumn.mTextFrames[i];
     nscoord deltaISize = icoord - lineLayout->GetCurrentICoord();
     if (deltaISize > 0) {
       lineLayout->AdvanceICoord(deltaISize);
       if (textFrame) {
         RubyUtils::SetReservedISize(textFrame, deltaISize);
       }
     }
     if (aColumn.mBaseFrame && textFrame) {
@@ -733,24 +735,27 @@ void
 nsRubyBaseContainerFrame::PullOneColumn(nsLineLayout* aLineLayout,
                                         PullFrameState& aPullFrameState,
                                         RubyColumn& aColumn,
                                         bool& aIsComplete)
 {
   const TextContainerArray& textContainers = aPullFrameState.mTextContainers;
   const uint32_t rtcCount = textContainers.Length();
 
-  aColumn.mBaseFrame = PullNextInFlowChild(aPullFrameState.mBase);
+  nsIFrame* nextBase = PullNextInFlowChild(aPullFrameState.mBase);
+  MOZ_ASSERT(!nextBase || nextBase->GetType() == nsGkAtoms::rubyBaseFrame);
+  aColumn.mBaseFrame = static_cast<nsRubyBaseFrame*>(nextBase);
   aIsComplete = !aColumn.mBaseFrame;
 
   aColumn.mTextFrames.ClearAndRetainStorage();
   for (uint32_t i = 0; i < rtcCount; i++) {
     nsIFrame* nextText =
       textContainers[i]->PullNextInFlowChild(aPullFrameState.mTexts[i]);
-    aColumn.mTextFrames.AppendElement(nextText);
+    MOZ_ASSERT(!nextText || nextText->GetType() == nsGkAtoms::rubyTextFrame);
+    aColumn.mTextFrames.AppendElement(static_cast<nsRubyTextFrame*>(nextText));
     // If there exists any frame in continations, we haven't
     // completed the reflow process.
     aIsComplete = aIsComplete && !nextText;
   }
 
   if (!aIsComplete) {
     // We pulled frames from the next line, hence mark it dirty.
     aLineLayout->SetDirtyNextLine();