Bug 1055658 part 2 - Add relative positioning support for ruby annotations. r=dbaron
☠☠ backed out by 1e81483663a0 ☠ ☠
authorXidorn Quan <quanxunzhen@gmail.com>
Thu, 08 Jan 2015 23:20:16 +1100
changeset 222747 f4e02295ff1fdef14dcef09fe1f837b2819145e1
parent 222746 68d2b24c9351576aede149f46d52cb0e97624ff7
child 222748 9371c6f11873968d0eb358b5b7ab233648dae6d5
push id28073
push userkwierso@gmail.com
push dateFri, 09 Jan 2015 01:08:23 +0000
treeherdermozilla-central@b3f84cf78dc2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1055658
milestone37.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 1055658 part 2 - Add relative positioning support for ruby annotations. r=dbaron
layout/generic/nsLineLayout.cpp
layout/generic/nsLineLayout.h
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -248,16 +248,31 @@ nsLineLayout::BeginLineReflow(nscoord aI
 
     psd->mICoord += indent;
   }
 
   PerFrameData* pfd = NewPerFrameData(mBlockReflowState->frame);
   pfd->mAscent = 0;
   pfd->mSpan = psd;
   psd->mFrame = pfd;
+  nsIFrame* frame = mBlockReflowState->frame;
+  if (frame->GetType() == nsGkAtoms::rubyTextContainerFrame) {
+    // Ruby text container won't be reflowed via ReflowFrame, hence the
+    // relative positioning information should be recorded here.
+    MOZ_ASSERT(mBaseLineLayout != this);
+    pfd->mRelativePos =
+      mBlockReflowState->mStyleDisplay->IsRelativelyPositionedStyle();
+    if (pfd->mRelativePos) {
+      MOZ_ASSERT(
+        mBlockReflowState->GetWritingMode() == frame->GetWritingMode(),
+        "mBlockReflowState->frame == frame, "
+        "hence they should have identical writing mode");
+      pfd->mOffsets = mBlockReflowState->ComputedLogicalOffsets();
+    }
+  }
 }
 
 void
 nsLineLayout::EndLineReflow()
 {
 #ifdef NOISY_REFLOW
   nsFrame::ListTag(stdout, mBlockReflowState->frame);
   printf(": EndLineReflow: width=%d\n", mRootSpan->mICoord - mRootSpan->mIStart);
@@ -670,16 +685,17 @@ nsLineLayout::NewPerFrameData(nsIFrame* 
   pfd->mIsBullet = false;
   pfd->mSkipWhenTrimmingWhitespace = false;
   pfd->mIsEmpty = false;
   pfd->mIsLinkedToBase = false;
 
   WritingMode frameWM = aFrame->GetWritingMode();
   WritingMode lineWM = mRootSpan->mWritingMode;
   pfd->mBounds = LogicalRect(lineWM);
+  pfd->mOverflowAreas.Clear();
   pfd->mMargin = LogicalMargin(lineWM);
   pfd->mBorderPadding = LogicalMargin(lineWM);
   pfd->mOffsets = LogicalMargin(frameWM);
 
   pfd->mJustificationInfo = JustificationInfo();
   pfd->mJustificationAssignment = JustificationAssignment();
 
 #ifdef DEBUG
@@ -3035,16 +3051,36 @@ nsLineLayout::ApplyRelativePositioning(P
   // right and bottom are handled by
   // nsHTMLReflowState::ComputeRelativeOffsets
   nsHTMLReflowState::ApplyRelativePositioning(frame, frameWM,
                                               aPFD->mOffsets, &origin,
                                               mContainerWidth);
   frame->SetPosition(frameWM, origin, mContainerWidth);
 }
 
+// This method do relative positioning for ruby annotations.
+void
+nsLineLayout::RelativePositionAnnotations(PerSpanData* aRubyPSD,
+                                          nsOverflowAreas& aOverflowAreas)
+{
+  MOZ_ASSERT(aRubyPSD->mFrame->mFrame->GetType() == nsGkAtoms::rubyFrame);
+  for (PerFrameData* pfd = aRubyPSD->mFirstFrame; pfd; pfd = pfd->mNext) {
+    MOZ_ASSERT(pfd->mFrame->GetType() == nsGkAtoms::rubyBaseContainerFrame);
+    for (PerFrameData* rtc = pfd->mNextAnnotation;
+         rtc; rtc = rtc->mNextAnnotation) {
+      nsIFrame* rtcFrame = rtc->mFrame;
+      MOZ_ASSERT(rtcFrame->GetType() == nsGkAtoms::rubyTextContainerFrame);
+      ApplyRelativePositioning(rtc);
+      nsOverflowAreas rtcOverflowAreas;
+      RelativePositionFrames(rtc->mSpan, rtcOverflowAreas);
+      aOverflowAreas.UnionWith(rtcOverflowAreas + rtcFrame->GetPosition());
+    }
+  }
+}
+
 void
 nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas)
 {
   nsOverflowAreas overflowAreas;
   WritingMode wm = psd->mWritingMode;
   if (psd != mRootSpan) {
     // The span's overflow areas come in three parts:
     // -- this frame's width and height
@@ -3129,16 +3165,21 @@ nsLineLayout::RelativePositionFrames(Per
       nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, frame,
                                                  frame->GetView(),
                                                  r.VisualOverflow(),
                                                  NS_FRAME_NO_MOVE_VIEW);
 
     overflowAreas.UnionWith(r + frame->GetPosition());
   }
 
+  // Also compute relative position in the annotations.
+  if (psd->mFrame->mFrame->GetType() == nsGkAtoms::rubyFrame) {
+    RelativePositionAnnotations(psd, overflowAreas);
+  }
+
   // If we just computed a spans combined area, we need to update its
   // overflow rect...
   if (psd != mRootSpan) {
     PerFrameData* spanPFD = psd->mFrame;
     nsIFrame* frame = spanPFD->mFrame;
     frame->FinishAndStoreOverflow(overflowAreas, frame->GetSize());
   }
   aOverflowAreas = overflowAreas;
--- a/layout/generic/nsLineLayout.h
+++ b/layout/generic/nsLineLayout.h
@@ -662,16 +662,19 @@ protected:
   void VerticalAlignFrames(PerSpanData* psd);
 
   void PlaceTopBottomFrames(PerSpanData* psd,
                             nscoord aDistanceFromStart,
                             nscoord aLineBSize);
 
   void ApplyRelativePositioning(PerFrameData* aPFD);
 
+  void RelativePositionAnnotations(PerSpanData* aRubyPSD,
+                                   nsOverflowAreas& aOverflowAreas);
+
   void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas);
 
   bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize);
 
   struct JustificationComputationState;
   int32_t ComputeFrameJustification(PerSpanData* psd,
                                     JustificationComputationState& aState);