Bug 1401709 - Do attach base line layout to orthogonal rtc. r?xidorn draft 13-1401709
authorKevin Hsieh <kevin.hsieh@ucla.edu>
Thu, 21 Sep 2017 19:36:12 -0700
branch13-1401709
changeset 668903 ef4b789a4537df34d8e84bd98364d218faa10121
parent 666213 dd927fbee259fc604f2be4d165c92cb29485f1da
child 732798 fd9ddb1936e93456940cc140f177cd29c0402ca7
push id81149
push userbmo:kevin.hsieh@ucla.edu
push dateFri, 22 Sep 2017 05:43:46 +0000
reviewersxidorn
bugs1401709
milestone57.0a1
Bug 1401709 - Do attach base line layout to orthogonal rtc. r?xidorn MozReview-Commit-ID: JCgaXWD43m5
layout/generic/crashtests/1401709.html
layout/generic/crashtests/crashtests.list
layout/generic/nsLineLayout.cpp
layout/generic/nsRubyBaseContainerFrame.cpp
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/1401709.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <ruby>
+    <rtc style="writing-mode: vertical-rl">
+      <div style="float: left"></div>
+    </rtc>
+  </ruby>
+</body>
+</html>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -653,8 +653,9 @@ load 1304441.html
 load 1308876-1.html
 load 1316649.html
 load 1349650.html
 asserts-if(browserIsRemote,0-5) load 1349816-1.html # bug 1350352
 load 1364361-1.html
 load 1367413-1.html
 load 1368617-1.html
 load 1373586.html
+load 1401709.html
--- 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(aOuterReflowInput->mFrame->IsRubyTextContainerFrame() ||
-             !mBaseLineLayout,
-             "Only ruby text container frames may have "
+  MOZ_ASSERT((!!mBaseLineLayout) ==
+              aOuterReflowInput->mFrame->IsRubyTextContainerFrame(),
+             "Only ruby text container frames 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
@@ -1209,16 +1209,20 @@ nsLineLayout::SyncAnnotationBounds(PerFr
   MOZ_ASSERT(aRubyFrame->mFrame->IsRubyFrame());
   MOZ_ASSERT(aRubyFrame->mSpan);
 
   PerSpanData* span = aRubyFrame->mSpan;
   WritingMode lineWM = mRootSpan->mWritingMode;
   for (PerFrameData* pfd = span->mFirstFrame; pfd; pfd = pfd->mNext) {
     for (PerFrameData* rtc = pfd->mNextAnnotation;
          rtc; rtc = rtc->mNextAnnotation) {
+      if (lineWM.IsOrthogonalTo(rtc->mFrame->GetWritingMode())) {
+        // Inter-character case: don't attempt to sync annotation bounds.
+        continue;
+      }
       // When the annotation container is reflowed, the width of the
       // ruby container is unknown so we use a dummy container size;
       // in the case of RTL block direction, the final position will be
       // fixed up later.
       const nsSize dummyContainerSize;
       LogicalRect rtcBounds(lineWM, rtc->mFrame->GetRect(),
                             dummyContainerSize);
       rtc->mBounds = rtcBounds;
@@ -3012,16 +3016,20 @@ nsLineLayout::ExpandRubyBoxWithAnnotatio
   if (reservedISize) {
     ExpandRubyBox(aFrame, reservedISize, aContainerSize);
   }
 
   WritingMode lineWM = mRootSpan->mWritingMode;
   bool isLevelContainer = aFrame->mFrame->IsRubyBaseContainerFrame();
   for (PerFrameData* annotation = aFrame->mNextAnnotation;
        annotation; annotation = annotation->mNextAnnotation) {
+    if (lineWM.IsOrthogonalTo(annotation->mFrame->GetWritingMode())) {
+      // Inter-character case: don't attempt to expand ruby annotations.
+      continue;
+    }
     if (isLevelContainer) {
       nsIFrame* rtcFrame = annotation->mFrame;
       MOZ_ASSERT(rtcFrame->IsRubyTextContainerFrame());
       // It is necessary to set the rect again because the container
       // width was unknown, and zero was used instead when we reflow
       // them. The corresponding base containers were repositioned in
       // VerticalAlignFrames and PlaceTopBottomFrames.
       MOZ_ASSERT(
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -337,50 +337,46 @@ nsRubyBaseContainerFrame::Reflow(nsPresC
   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.
+    WritingMode reflowWM = lineWM.IsOrthogonalTo(rtcWM) ? rtcWM : lineWM;
     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,
-                                                baseLineLayout);
+                                                aReflowInput.mLineLayout);
     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,
-                                baseLineLayout ? lineWM : rtcWM, nsSize(0, 0));
-    if (baseLineLayout) {
-      lineLayout->AttachRootFrameToBaseLineLayout();
-    }
+                                NS_UNCONSTRAINEDSIZE,
+                                false, false, reflowWM, nsSize(0, 0));
+    lineLayout->AttachRootFrameToBaseLineLayout();
   }
 
   aReflowInput.mLineLayout->BeginSpan(this, &aReflowInput,
                                       0, aReflowInput.AvailableISize(),
                                       &mBaseline);
 
   bool allowInitialLineBreak, allowLineBreak;
   GetIsLineBreakAllowed(this, aReflowInput.mLineLayout->LineIsBreakable(),