Bug 1141931 part 2 - Eliminate writing-mode mismatch in ruby reflow. r=dholbert
☠☠ backed out by 44c475f5adc1 ☠ ☠
authorXidorn Quan <quanxunzhen@gmail.com>
Wed, 08 Apr 2015 08:40:31 +1200
changeset 238001 8a3c71a3b5256bb5a6870be01017d5ccd4744eeb
parent 238000 119d3c0fd0f60076f0a1014e9db1dc7ba63b1b9e
child 238002 f1ab848b3fa6cb2f1af40f949922b3eadd2e6de2
push id58082
push userxquan@mozilla.com
push dateTue, 07 Apr 2015 20:41:55 +0000
treeherdermozilla-inbound@26118238484f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1141931
milestone40.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 1141931 part 2 - Eliminate writing-mode mismatch in ruby reflow. r=dholbert
layout/generic/nsRubyBaseContainerFrame.cpp
layout/generic/nsRubyFrame.cpp
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -468,17 +468,18 @@ nsRubyBaseContainerFrame::Reflow(nsPresC
   bool hasSpan = false;
   for (uint32_t i = 0; i < rtcCount; i++) {
     nsRubyTextContainerFrame* textContainer = textContainers[i];
     if (textContainer->IsSpanContainer()) {
       hasSpan = true;
     }
 
     nsHTMLReflowState* reflowState = new nsHTMLReflowState(
-      aPresContext, *aReflowState.parentReflowState, textContainer, availSize);
+      aPresContext, *aReflowState.parentReflowState, textContainer,
+      availSize.ConvertTo(textContainer->GetWritingMode(), lineWM));
     reflowStates.AppendElement(reflowState);
     nsLineLayout* lineLayout = new nsLineLayout(aPresContext,
                                                 reflowState->mFloatManager,
                                                 reflowState, nullptr,
                                                 aReflowState.mLineLayout);
     lineLayout->SetSuppressLineWrap(true);
     lineLayouts.AppendElement(lineLayout);
 
--- a/layout/generic/nsRubyFrame.cpp
+++ b/layout/generic/nsRubyFrame.cpp
@@ -207,16 +207,19 @@ void
 nsRubyFrame::ReflowSegment(nsPresContext* aPresContext,
                            const nsHTMLReflowState& aReflowState,
                            nsRubyBaseContainerFrame* aBaseContainer,
                            nsReflowStatus& aStatus)
 {
   WritingMode lineWM = aReflowState.mLineLayout->GetWritingMode();
   LogicalSize availSize(lineWM, aReflowState.AvailableISize(),
                         aReflowState.AvailableBSize());
+  WritingMode rubyWM = GetWritingMode();
+  NS_ASSERTION(!rubyWM.IsOrthogonalTo(lineWM),
+               "Ruby frame writing-mode shouldn't be orthogonal to its line");
 
   nsAutoTArray<nsRubyTextContainerFrame*, RTC_ARRAY_SIZE> textContainers;
   for (RubyTextContainerIterator iter(aBaseContainer); !iter.AtEnd(); iter.Next()) {
     textContainers.AppendElement(iter.GetTextContainer());
   }
   const uint32_t rtcCount = textContainers.Length();
 
   nsHTMLReflowMetrics baseMetrics(aReflowState);
@@ -300,38 +303,40 @@ 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.
   baseRect.BStart(lineWM) = 0;
   // The rect for offsets of text containers.
   LogicalRect offsetRect = baseRect;
   for (uint32_t i = 0; i < rtcCount; i++) {
     nsRubyTextContainerFrame* textContainer = textContainers[i];
+    WritingMode rtcWM = textContainer->GetWritingMode();
     nsReflowStatus textReflowStatus;
     nsHTMLReflowMetrics textMetrics(aReflowState);
-    nsHTMLReflowState textReflowState(aPresContext, aReflowState,
-                                      textContainer, availSize);
+    nsHTMLReflowState textReflowState(aPresContext, aReflowState, textContainer,
+                                      availSize.ConvertTo(rtcWM, lineWM));
     // 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
     // they have continuations, because the breaking has already been
     // handled when reflowing the base containers.
     NS_ASSERTION(textReflowStatus == NS_FRAME_COMPLETE,
                  "Ruby text container must not break itself inside");
-    nscoord isize = textMetrics.ISize(lineWM);
-    nscoord bsize = textMetrics.BSize(lineWM);
-    textContainer->SetSize(LogicalSize(lineWM, isize, bsize));
+    // The metrics is initialized with reflow state of this ruby frame,
+    // hence the writing-mode is tied to rubyWM instead of rtcWM.
+    LogicalSize size = textMetrics.Size(rubyWM).ConvertTo(lineWM, rubyWM);
+    textContainer->SetSize(lineWM, size);
 
     nscoord reservedISize = RubyUtils::GetReservedISize(textContainer);
-    segmentISize = std::max(segmentISize, isize + reservedISize);
+    segmentISize = std::max(segmentISize, size.ISize(lineWM) + reservedISize);
 
     uint8_t rubyPosition = textContainer->StyleText()->mRubyPosition;
     MOZ_ASSERT(rubyPosition == NS_STYLE_RUBY_POSITION_OVER ||
                rubyPosition == NS_STYLE_RUBY_POSITION_UNDER);
     Maybe<LogicalSide> side;
     if (rubyPosition == NS_STYLE_RUBY_POSITION_OVER) {
       side.emplace(lineWM.LogicalSideForLineRelativeDir(eLineRelativeDirOver));
     } else if (rubyPosition == NS_STYLE_RUBY_POSITION_UNDER) {
@@ -339,23 +344,23 @@ nsRubyFrame::ReflowSegment(nsPresContext
     } else {
       // XXX inter-character support in bug 1055672
       MOZ_ASSERT_UNREACHABLE("Unsupported ruby-position");
     }
 
     LogicalPoint position(lineWM);
     if (side.isSome()) {
       if (side.value() == eLogicalSideBStart) {
-        offsetRect.BStart(lineWM) -= bsize;
-        offsetRect.BSize(lineWM) += bsize;
+        offsetRect.BStart(lineWM) -= size.BSize(lineWM);
+        offsetRect.BSize(lineWM) += size.BSize(lineWM);
         position = offsetRect.Origin(lineWM);
       } else if (side.value() == eLogicalSideBEnd) {
         position = offsetRect.Origin(lineWM) +
           LogicalPoint(lineWM, 0, offsetRect.BSize(lineWM));
-        offsetRect.BSize(lineWM) += bsize;
+        offsetRect.BSize(lineWM) += size.BSize(lineWM);
       } else {
         MOZ_ASSERT_UNREACHABLE("???");
       }
     }
     // Container width is set to zero here. We will fix it in
     // nsLineLayout after the whole line get reflowed.
     FinishReflowChild(textContainer, aPresContext, textMetrics,
                       &textReflowState, lineWM, position, 0, 0);