Bug 1395777 (part 1) - Allow rtc to use its own writing mode. r=xidorn
authorKevin Hsieh <kevin.hsieh@ucla.edu>
Thu, 31 Aug 2017 17:40:18 -0700
changeset 433541 044422a93db9435ea419f895f77a5352a81aa3e2
parent 433540 b2e85eb4879dafd1533fff1e106307caf38672c8
child 433542 ad20c4bf0d579b3d998a2775b5d52dce42520d15
push id1567
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 12:36:05 +0000
treeherdermozilla-release@e512c14a0406 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersxidorn
bugs1395777
milestone57.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 1395777 (part 1) - Allow rtc to use its own writing mode. r=xidorn MozReview-Commit-ID: EkYL53YxGQV
layout/generic/nsLineLayout.cpp
layout/generic/nsRubyBaseContainerFrame.cpp
layout/generic/nsRubyFrame.cpp
layout/generic/nsRubyTextContainerFrame.cpp
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -76,19 +76,19 @@ nsLineLayout::nsLineLayout(nsPresContext
     mDirtyNextLine(false),
     mLineAtStart(false),
     mHasRuby(false),
     mSuppressLineWrap(nsSVGUtils::IsInSVGTextSubtree(aOuterReflowInput->mFrame))
 {
   MOZ_ASSERT(aOuterReflowInput, "aOuterReflowInput must not be null");
   NS_ASSERTION(aFloatManager || aOuterReflowInput->mFrame->IsLetterFrame(),
                "float manager should be present");
-  MOZ_ASSERT((!!mBaseLineLayout) ==
-              aOuterReflowInput->mFrame->IsRubyTextContainerFrame(),
-             "Only ruby text container frames have "
+  MOZ_ASSERT(aOuterReflowInput->mFrame->IsRubyTextContainerFrame() ||
+             !mBaseLineLayout,
+             "Only ruby text container frames may have "
              "a different base line layout");
   MOZ_COUNT_CTOR(nsLineLayout);
 
   // Stash away some style data that we need
   nsBlockFrame* blockFrame = do_QueryFrame(aOuterReflowInput->mFrame);
   if (blockFrame)
     mStyleText = blockFrame->StyleTextForLineLayout();
   else
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -336,45 +336,51 @@ nsRubyBaseContainerFrame::Reflow(nsPresC
   AutoTArray<UniquePtr<nsLineLayout>, RTC_ARRAY_SIZE> lineLayouts;
   reflowInputs.SetCapacity(rtcCount);
   lineLayouts.SetCapacity(rtcCount);
 
   // Begin the line layout for each ruby text container in advance.
   bool hasSpan = false;
   for (uint32_t i = 0; i < rtcCount; i++) {
     nsRubyTextContainerFrame* textContainer = textContainers[i];
+    WritingMode rtcWM = textContainer->GetWritingMode();
+    nsLineLayout* baseLineLayout =
+        lineWM.IsOrthogonalTo(rtcWM) ? nullptr : aReflowInput.mLineLayout;
+        // Don't attach a base line layout in the inter-character case.
     if (textContainer->IsSpanContainer()) {
       hasSpan = true;
     }
 
     ReflowInput* reflowInput = new ReflowInput(
       aPresContext, *aReflowInput.mParentReflowInput, textContainer,
       availSize.ConvertTo(textContainer->GetWritingMode(), lineWM));
     reflowInputs.AppendElement(reflowInput);
     nsLineLayout* lineLayout = new nsLineLayout(aPresContext,
                                                 reflowInput->mFloatManager,
                                                 reflowInput, nullptr,
-                                                aReflowInput.mLineLayout);
+                                                baseLineLayout);
     lineLayout->SetSuppressLineWrap(true);
     lineLayouts.AppendElement(lineLayout);
 
     // Line number is useless for ruby text
     // XXX nullptr here may cause problem, see comments for
     //     nsLineLayout::mBlockRI and nsLineLayout::AddFloat
     lineLayout->Init(nullptr, reflowInput->CalcLineHeight(), -1);
     reflowInput->mLineLayout = lineLayout;
 
     // Border and padding are suppressed on ruby text containers.
     // If the writing mode is vertical-rl, the horizontal position of
     // rt frames will be updated when reflowing this text container,
     // hence leave container size 0 here for now.
     lineLayout->BeginLineReflow(0, 0, reflowInput->ComputedISize(),
-                                NS_UNCONSTRAINEDSIZE,
-                                false, false, lineWM, nsSize(0, 0));
-    lineLayout->AttachRootFrameToBaseLineLayout();
+                                NS_UNCONSTRAINEDSIZE, false, false,
+                                baseLineLayout ? lineWM : rtcWM, nsSize(0, 0));
+    if (baseLineLayout) {
+      lineLayout->AttachRootFrameToBaseLineLayout();
+    }
   }
 
   aReflowInput.mLineLayout->BeginSpan(this, &aReflowInput,
                                       0, aReflowInput.AvailableISize(),
                                       &mBaseline);
 
   bool allowInitialLineBreak, allowLineBreak;
   GetIsLineBreakAllowed(this, aReflowInput.mLineLayout->LineIsBreakable(),
--- a/layout/generic/nsRubyFrame.cpp
+++ b/layout/generic/nsRubyFrame.cpp
@@ -310,21 +310,16 @@ nsRubyFrame::ReflowSegment(nsPresContext
   offsetRect.BSize(lineWM) += descLeadings.mStart + descLeadings.mEnd;
   for (uint32_t i = 0; i < rtcCount; i++) {
     nsRubyTextContainerFrame* textContainer = textContainers[i];
     WritingMode rtcWM = textContainer->GetWritingMode();
     nsReflowStatus textReflowStatus;
     ReflowOutput textMetrics(aReflowInput);
     ReflowInput textReflowInput(aPresContext, aReflowInput, 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.
-    textReflowInput.mLineLayout = aReflowInput.mLineLayout;
     textContainer->Reflow(aPresContext, textMetrics,
                           textReflowInput, textReflowStatus);
     // Ruby text containers always return complete reflow status even when
     // they have continuations, because the breaking has already been
     // handled when reflowing the base containers.
     NS_ASSERTION(textReflowStatus.IsEmpty(),
                  "Ruby text container must not break itself inside");
     // The metrics is initialized with reflow state of this ruby frame,
--- a/layout/generic/nsRubyTextContainerFrame.cpp
+++ b/layout/generic/nsRubyTextContainerFrame.cpp
@@ -123,53 +123,53 @@ nsRubyTextContainerFrame::Reflow(nsPresC
   DO_GLOBAL_REFLOW_COUNT("nsRubyTextContainerFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
 
   // Although a ruby text container may have continuations, returning
   // complete reflow status 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.Reset();
-  WritingMode lineWM = aReflowInput.mLineLayout->GetWritingMode();
+  WritingMode rtcWM = GetWritingMode();
 
   nscoord minBCoord = nscoord_MAX;
   nscoord maxBCoord = nscoord_MIN;
   // The container size is not yet known, so we use a dummy (0, 0) size.
   // The block-dir position will be corrected below after containerSize
   // is finalized.
   const nsSize dummyContainerSize;
   for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
     nsIFrame* child = e.get();
     MOZ_ASSERT(child->IsRubyTextFrame());
-    LogicalRect rect = child->GetLogicalRect(lineWM, dummyContainerSize);
-    LogicalMargin margin = child->GetLogicalUsedMargin(lineWM);
-    nscoord blockStart = rect.BStart(lineWM) - margin.BStart(lineWM);
+    LogicalRect rect = child->GetLogicalRect(rtcWM, dummyContainerSize);
+    LogicalMargin margin = child->GetLogicalUsedMargin(rtcWM);
+    nscoord blockStart = rect.BStart(rtcWM) - margin.BStart(rtcWM);
     minBCoord = std::min(minBCoord, blockStart);
-    nscoord blockEnd = rect.BEnd(lineWM) + margin.BEnd(lineWM);
+    nscoord blockEnd = rect.BEnd(rtcWM) + margin.BEnd(rtcWM);
     maxBCoord = std::max(maxBCoord, blockEnd);
   }
 
-  LogicalSize size(lineWM, mISize, 0);
+  LogicalSize size(rtcWM, mISize, 0);
   if (!mFrames.IsEmpty()) {
     if (MOZ_UNLIKELY(minBCoord > maxBCoord)) {
       // XXX When bug 765861 gets fixed, this warning should be upgraded.
       NS_WARNING("bad block coord");
       minBCoord = maxBCoord = 0;
     }
-    size.BSize(lineWM) = maxBCoord - minBCoord;
-    nsSize containerSize = size.GetPhysicalSize(lineWM);
+    size.BSize(rtcWM) = maxBCoord - minBCoord;
+    nsSize containerSize = size.GetPhysicalSize(rtcWM);
     for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
       nsIFrame* child = e.get();
       // We reflowed the child with a dummy container size, as the true size
       // was not yet known at that time.
-      LogicalPoint pos = child->GetLogicalPosition(lineWM, dummyContainerSize);
+      LogicalPoint pos = child->GetLogicalPosition(rtcWM, dummyContainerSize);
       // Adjust block position to account for minBCoord,
       // then reposition child based on the true container width.
-      pos.B(lineWM) -= minBCoord;
+      pos.B(rtcWM) -= minBCoord;
       // Relative positioning hasn't happened yet.
       // So MovePositionBy should not be used here.
-      child->SetPosition(lineWM, pos, containerSize);
+      child->SetPosition(rtcWM, pos, containerSize);
       nsContainerFrame::PlaceFrameView(child);
     }
   }
 
-  aDesiredSize.SetSize(lineWM, size);
+  aDesiredSize.SetSize(rtcWM, size);
 }