Bug 1395777 (part 1) - Allow rtc to use its own writing mode. r?xidorn draft 8-1395777
authorKevin Hsieh <kevin.hsieh@ucla.edu>
Thu, 31 Aug 2017 17:40:18 -0700
branch8-1395777
changeset 663643 2236823eade093ff87be759a373c3d89c91e3a49
parent 658333 0afabd3e5c27b0036517b96eecb1f8553d027179
child 663644 bd358fb9f132e6cba8725a33526d3161860a4c5e
child 663645 8b2e30583a4fa3013d73f69083df674276ff906b
child 665810 33016faf03a5adf3664e1527fd8388e969fc563c
child 666029 d1cb16754e71a6b5551ef7980bdd4f6a0ddb6757
child 666086 46a8e29590d6a1ddeee50c95cf4b41d965eff3d0
child 666182 c391c8df4a60916262ac9a2578f949dfa7cf72f6
child 666213 dd927fbee259fc604f2be4d165c92cb29485f1da
push id79494
push userbmo:kevin.hsieh@ucla.edu
push dateWed, 13 Sep 2017 08:16:02 +0000
reviewersxidorn
bugs1395777
milestone57.0a1
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);
 }