Bug 1081770 - Move ruby annotation frames when text-align: justify is applied to ruby bases. r=dbaron

--HG--
extra : rebase_source : 959be07c7a44c96eba46963213de01525e5292b0
extra : source : c5e6e8898b2df7b29fe1b2071291bde17d7780fc
This commit is contained in:
Xidorn Quan 2014-12-09 17:43:24 +11:00
parent 85ef94a712
commit e1e70e4d49
2 changed files with 66 additions and 0 deletions

View File

@ -2532,6 +2532,61 @@ nsLineLayout::ComputeFrameJustification(PerSpanData* aPSD,
return result;
}
void
nsLineLayout::AdvanceAnnotationInlineBounds(PerFrameData* aPFD,
nscoord aContainerWidth,
nscoord aDeltaICoord,
nscoord aDeltaISize)
{
MOZ_ASSERT(aPFD->mFrame->GetType() == nsGkAtoms::rubyTextFrame ||
aPFD->mFrame->GetType() == nsGkAtoms::rubyTextContainerFrame);
MOZ_ASSERT(aPFD->mSpan, "rt and rtc should have span.");
WritingMode lineWM = mRootSpan->mWritingMode;
WritingMode frameWM = aPFD->mSpan->mWritingMode;
LogicalRect bounds = aPFD->mFrame->GetLogicalRect(aContainerWidth);
bounds = bounds.ConvertTo(lineWM, frameWM, aContainerWidth);
bounds.IStart(lineWM) += aDeltaICoord;
bounds.ISize(lineWM) += aDeltaISize;
aPFD->mBounds = bounds.ConvertTo(frameWM, lineWM, aContainerWidth);
aPFD->mFrame->SetRect(frameWM, aPFD->mBounds, aContainerWidth);
}
/**
* This function applies the changes of icoord and isize caused by
* justification to annotations of the given frame.
* aPFD must be one of the frames in aContainingSpan.
*/
void
nsLineLayout::ApplyLineJustificationToAnnotations(PerFrameData* aPFD,
PerSpanData* aContainingSpan,
nscoord aDeltaICoord,
nscoord aDeltaISize)
{
PerFrameData* pfd = aPFD->mNextAnnotation;
nscoord containerWidth = ContainerWidthForSpan(aContainingSpan);
while (pfd) {
AdvanceAnnotationInlineBounds(pfd, containerWidth,
aDeltaICoord, aDeltaISize);
// There are two cases where an annotation frame has siblings which
// do not attached to a ruby base-level frame:
// 1. there's an intra-annotation whitespace which has no intra-base
// white-space to pair with;
// 2. there are not enough ruby bases to be paired with annotations.
// In these cases, their size should not be affected, but we still
// need to move them so that they won't overlap other frames.
PerFrameData* sibling = pfd->mNext;
while (sibling && !sibling->GetFlag(PFD_ISLINKEDTOBASE)) {
AdvanceAnnotationInlineBounds(sibling, containerWidth,
aDeltaICoord + aDeltaISize, 0);
sibling = sibling->mNext;
}
pfd = pfd->mNextAnnotation;
}
}
nscoord
nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD,
JustificationApplicationState& aState)
@ -2570,6 +2625,7 @@ nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD,
pfd->mBounds.ISize(lineWM) += dw;
ApplyLineJustificationToAnnotations(pfd, aPSD, deltaICoord, dw);
deltaICoord += dw;
pfd->mFrame->SetRect(lineWM, pfd->mBounds, ContainerWidthForSpan(aPSD));
}

View File

@ -670,6 +670,16 @@ protected:
int32_t ComputeFrameJustification(PerSpanData* psd,
JustificationComputationState& aState);
void AdvanceAnnotationInlineBounds(PerFrameData* aPFD,
nscoord aContainerWidth,
nscoord aDeltaICoord,
nscoord aDeltaISize);
void ApplyLineJustificationToAnnotations(PerFrameData* aPFD,
PerSpanData* aContainingSpan,
nscoord aDeltaICoord,
nscoord aDeltaISize);
// Apply justification. The return value is the amount by which the width of
// the span corresponding to aPSD got increased due to justification.
nscoord ApplyFrameJustification(