Bug 1052924 - Give rbc & rtc correct position. r=dbaron
authorXidorn Quan <quanxunzhen@gmail.com>
Wed, 26 Nov 2014 15:52:49 +1100
changeset 217540 33dddb6ab137d28182a414a241529a8169d95fb8
parent 217539 002f76d56d0f1d7d81d5f88ac3b690ca62de7876
child 217541 0ea4763c76f3e9e8509713082495bcc4487e8c18
push id52308
push userxquan@mozilla.com
push dateWed, 26 Nov 2014 04:53:51 +0000
treeherdermozilla-inbound@b657497010c2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1052924
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1052924 - Give rbc & rtc correct position. r=dbaron Important changes: * Use line layout to reflow ruby base container
layout/generic/nsRubyBaseContainerFrame.cpp
layout/generic/nsRubyBaseContainerFrame.h
layout/generic/nsRubyFrame.cpp
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -212,16 +212,22 @@ nsRubyBaseContainerFrame::ComputeSize(ns
                                       const LogicalSize& aPadding,
                                       ComputeSizeFlags aFlags)
 {
   // Ruby base container frame is inline,
   // hence don't compute size before reflow.
   return LogicalSize(aWM, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
 }
 
+/* virtual */ nscoord
+nsRubyBaseContainerFrame::GetLogicalBaseline(WritingMode aWritingMode) const
+{
+  return mBaseline;
+}
+
 /* virtual */ void
 nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext,
                                  nsHTMLReflowMetrics& aDesiredSize,
                                  const nsHTMLReflowState& aReflowState,
                                  nsReflowStatus& aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsRubyBaseContainerFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
@@ -232,16 +238,22 @@ nsRubyBaseContainerFrame::Reflow(nsPresC
       "No line layout provided to RubyBaseContainerFrame reflow method.");
     aStatus = NS_FRAME_COMPLETE;
     return;
   }
 
   aStatus = NS_FRAME_COMPLETE;
   WritingMode lineWM = aReflowState.mLineLayout->GetWritingMode();
   WritingMode frameWM = aReflowState.GetWritingMode();
+  LogicalMargin borderPadding = aReflowState.ComputedLogicalBorderPadding();
+  nscoord startEdge = borderPadding.IStart(frameWM);
+  nscoord endEdge = aReflowState.AvailableISize() - borderPadding.IEnd(frameWM);
+
+  aReflowState.mLineLayout->BeginSpan(this, &aReflowState,
+                                      startEdge, endEdge, &mBaseline);
 
   LogicalSize availSize(lineWM, aReflowState.AvailableWidth(),
                         aReflowState.AvailableHeight());
 
   const uint32_t rtcCount = mTextContainers.Length();
   const uint32_t spanCount = mSpanContainers.Length();
   const uint32_t totalCount = rtcCount + spanCount;
   // We have a reflow state and a line layout for each RTC.
@@ -358,22 +370,27 @@ nsRubyBaseContainerFrame::Reflow(nsPresC
     spanISize = std::max(spanISize, metrics.ISize(lineWM));
   }
 
   nscoord isize = icoord - istart;
   if (isize < spanISize) {
     aReflowState.mLineLayout->AdvanceICoord(spanISize - isize);
     isize = spanISize;
   }
+
+  DebugOnly<nscoord> spanSize = aReflowState.mLineLayout->EndSpan(this);
+  // When there are no frames inside the ruby base container, EndSpan
+  // will return 0. However, in this case, the actual width of the
+  // container could be non-zero because of non-empty ruby annotations.
+  MOZ_ASSERT(isize == spanSize || mFrames.IsEmpty());
   for (uint32_t i = 0; i < totalCount; i++) {
     // It happens before the ruby text container is reflowed, and that
     // when it is reflowed, it will just use this size.
     nsRubyTextContainerFrame* textContainer = i < rtcCount ?
       mTextContainers[i] : mSpanContainers[i - rtcCount];
     textContainer->SetISize(isize);
     lineLayouts[i]->EndLineReflow();
   }
 
-  LogicalMargin borderPadding = aReflowState.ComputedLogicalBorderPadding();
   aDesiredSize.ISize(lineWM) = isize;
   nsLayoutUtils::SetBSizeFromFontMetrics(this, aDesiredSize, aReflowState,
                                          borderPadding, lineWM, frameWM);
 }
--- a/layout/generic/nsRubyBaseContainerFrame.h
+++ b/layout/generic/nsRubyBaseContainerFrame.h
@@ -46,16 +46,19 @@ public:
                 const mozilla::LogicalSize& aBorder,
                 const mozilla::LogicalSize& aPadding,
                 ComputeSizeFlags aFlags) MOZ_OVERRIDE;
   virtual void Reflow(nsPresContext* aPresContext,
                       nsHTMLReflowMetrics& aDesiredSize,
                       const nsHTMLReflowState& aReflowState,
                       nsReflowStatus& aStatus) MOZ_OVERRIDE;
 
+  virtual nscoord
+    GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
+
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
 #ifdef DEBUG
   void AssertTextContainersEmpty()
   {
     MOZ_ASSERT(mSpanContainers.IsEmpty());
@@ -81,11 +84,12 @@ protected:
    */
 
   // The text containers that contain a span, which spans all ruby
   // pairs in the ruby segment.
   nsTArray<nsRubyTextContainerFrame*> mSpanContainers;
   // Normal text containers that do not contain spans.
   nsTArray<nsRubyTextContainerFrame*> mTextContainers;
 
+  nscoord mBaseline;
 };
 
 #endif /* nsRubyBaseContainerFrame_h___ */
--- a/layout/generic/nsRubyFrame.cpp
+++ b/layout/generic/nsRubyFrame.cpp
@@ -228,71 +228,61 @@ nsRubyFrame::Reflow(nsPresContext* aPres
     aStatus = NS_FRAME_COMPLETE;
     return;
   }
 
   // Begin the span for the ruby frame
   WritingMode frameWM = aReflowState.GetWritingMode();
   WritingMode lineWM = aReflowState.mLineLayout->GetWritingMode();
   LogicalMargin borderPadding = aReflowState.ComputedLogicalBorderPadding();
-  nscoord availableISize = aReflowState.AvailableISize();
-  NS_ASSERTION(availableISize != NS_UNCONSTRAINEDSIZE,
+  nscoord startEdge = borderPadding.IStart(frameWM);
+  nscoord endEdge = aReflowState.AvailableISize() - borderPadding.IEnd(frameWM);
+  NS_ASSERTION(aReflowState.AvailableISize() != NS_UNCONSTRAINEDSIZE,
                "should no longer use available widths");
-  // Subtract off inline axis border+padding from availableISize
-  availableISize -= borderPadding.IStartEnd(frameWM);
   aReflowState.mLineLayout->BeginSpan(this, &aReflowState,
-                                      borderPadding.IStart(frameWM),
-                                      availableISize, &mBaseline);
+                                      startEdge, endEdge, &mBaseline);
 
   // FIXME: line breaking / continuations not yet implemented
   aStatus = NS_FRAME_COMPLETE;
   LogicalSize availSize(lineWM, aReflowState.AvailableISize(),
                         aReflowState.AvailableBSize());
   for (SegmentEnumerator e(this); !e.AtEnd(); e.Next()) {
     nsRubyBaseContainerFrame* baseContainer = e.GetBaseContainer();
     AutoSetTextContainers holder(baseContainer);
     nsReflowStatus baseReflowStatus;
     nsHTMLReflowMetrics baseMetrics(aReflowState, aDesiredSize.mFlags);
-    nsHTMLReflowState baseReflowState(aPresContext, aReflowState,
-                                      baseContainer, availSize);
-    baseReflowState.mLineLayout = aReflowState.mLineLayout;
-    baseContainer->Reflow(aPresContext, baseMetrics, baseReflowState,
-                          baseReflowStatus);
-    NS_ASSERTION(baseReflowStatus == NS_FRAME_COMPLETE,
-                 "Ruby line breaking is not yet implemented");
-    baseContainer->SetSize(LogicalSize(lineWM, baseMetrics.ISize(lineWM),
-                                       baseMetrics.BSize(lineWM)));
-    FinishReflowChild(baseContainer, aPresContext, baseMetrics,
-                      &baseReflowState, 0, 0,
-                      NS_FRAME_NO_MOVE_FRAME | NS_FRAME_NO_MOVE_VIEW);
+    bool pushedFrame;
+    aReflowState.mLineLayout->ReflowFrame(baseContainer, baseReflowStatus,
+                                          &baseMetrics, pushedFrame);
 
+    nsRect baseRect = baseContainer->GetRect();
     for (TextContainerIterator iter(baseContainer);
          !iter.AtEnd(); iter.Next()) {
       nsRubyTextContainerFrame* textContainer = iter.GetTextContainer();
       nsReflowStatus textReflowStatus;
       nsHTMLReflowMetrics textMetrics(aReflowState, aDesiredSize.mFlags);
       nsHTMLReflowState textReflowState(aPresContext, aReflowState,
                                         textContainer, availSize);
       textReflowState.mLineLayout = aReflowState.mLineLayout;
       textContainer->Reflow(aPresContext, textMetrics,
                             textReflowState, textReflowStatus);
       NS_ASSERTION(textReflowStatus == NS_FRAME_COMPLETE,
                    "Ruby line breaking is not yet implemented");
       textContainer->SetSize(LogicalSize(lineWM, textMetrics.ISize(lineWM),
                                          textMetrics.BSize(lineWM)));
-      // FIXME: This is a temporary calculation for finding the block coordinate
-      // of the ruby text container. A better one replace it once it's been
-      // spec'ed.
-      // Find the starting block coordinate of the ruby base container for
-      // this segment. For now, the ruby text container will be placed so that
-      // its bottom edge touches this coordinate.
-      nscoord baseContainerBCoord = baseContainer->GetLogicalPosition(
-          GetParent()->GetLogicalSize().ISize(lineWM)).B(lineWM);
+      nscoord x, y;
+      nscoord bsize = textMetrics.BSize(lineWM);
+      if (lineWM.IsVertical()) {
+        x = lineWM.IsVerticalLR() ? -bsize : baseRect.XMost();
+        y = baseRect.Y();
+      } else {
+        x = baseRect.X();
+        y = -bsize;
+      }
       FinishReflowChild(textContainer, aPresContext, textMetrics,
-                        &textReflowState, 0,
-                        baseContainerBCoord - textMetrics.BSize(lineWM), 0);
+                        &textReflowState, x, y, 0);
     }
   }
 
   aDesiredSize.ISize(lineWM) = aReflowState.mLineLayout->EndSpan(this);
   nsLayoutUtils::SetBSizeFromFontMetrics(this, aDesiredSize, aReflowState,
                                          borderPadding, lineWM, frameWM);
 }