Bug 1055658 part 2 - Add relative positioning support for ruby annotations. r=dbaron
--- 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);