Bug 1141928 part 1 - Correct the position of ruby text containers in RTL text. r=jfkthame

This patch uses the logical version of FinishReflowChild instead, so that we are able to keep the consistent logical rect, and then fix the rect with correct container width after the whole line is reflowed.

--HG--
extra : source : e944e283799cd04b87c1ed52a3fca68174bf4439
This commit is contained in:
Xidorn Quan 2015-03-14 16:46:33 +11:00
parent b806fae66c
commit b5c74cb24b
2 changed files with 46 additions and 35 deletions

View File

@ -1245,11 +1245,13 @@ nsLineLayout::SyncAnnotationBounds(PerFrameData* aRubyFrame)
PerSpanData* span = aRubyFrame->mSpan;
WritingMode lineWM = mRootSpan->mWritingMode;
nscoord containerWidth = ContainerWidthForSpan(span);
for (PerFrameData* pfd = span->mFirstFrame; pfd; pfd = pfd->mNext) {
for (PerFrameData* rtc = pfd->mNextAnnotation;
rtc; rtc = rtc->mNextAnnotation) {
LogicalRect rtcBounds(lineWM, rtc->mFrame->GetRect(), containerWidth);
// When the annotation container is reflowed, the width of the
// ruby container is unknown, hence zero should be used here
// as container width to get the correct logical rect.
LogicalRect rtcBounds(lineWM, rtc->mFrame->GetRect(), 0);
rtc->mBounds = rtcBounds;
nscoord rtcWidth = rtcBounds.Width(lineWM);
for (PerFrameData* rt = rtc->mSpan->mFirstFrame; rt; rt = rt->mNext) {
@ -2969,8 +2971,24 @@ nsLineLayout::ExpandRubyBoxWithAnnotations(PerFrameData* aFrame,
ExpandRubyBox(aFrame, reservedISize, aContainerWidth);
}
WritingMode lineWM = mRootSpan->mWritingMode;
bool isLevelContainer =
aFrame->mFrame->GetType() == nsGkAtoms::rubyBaseContainerFrame;
for (PerFrameData* annotation = aFrame->mNextAnnotation;
annotation; annotation = annotation->mNextAnnotation) {
if (isLevelContainer) {
nsIFrame* rtcFrame = annotation->mFrame;
MOZ_ASSERT(rtcFrame->GetType() == nsGkAtoms::rubyTextContainerFrame);
// 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(
rtcFrame->GetLogicalSize(lineWM) == annotation->mBounds.Size(lineWM));
rtcFrame->SetPosition(lineWM, annotation->mBounds.Origin(lineWM),
aContainerWidth);
}
nscoord reservedISize = RubyUtils::GetReservedISize(annotation->mFrame);
if (!reservedISize) {
continue;

View File

@ -289,7 +289,7 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext,
}
nscoord segmentISize = baseMetrics.ISize(lineWM);
nsRect baseRect = aBaseContainer->GetRect();
LogicalRect baseRect = aBaseContainer->GetLogicalRect(lineWM, 0);
// We need to position our rtc frames on one side or the other of the
// base container's rect, using a coordinate space that's relative to
// the ruby frame. Right now, the base container's rect's block-axis
@ -297,9 +297,9 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext,
// lines, so we use 0 instead. (i.e. we assume that the base container
// is adjacent to the ruby frame's block-start edge.)
// XXX We may need to add border/padding here. See bug 1055667.
(lineWM.IsVertical() ? baseRect.x : baseRect.y) = 0;
baseRect.BStart(lineWM) = 0;
// The rect for offsets of text containers.
nsRect offsetRect = baseRect;
LogicalRect offsetRect = baseRect;
for (uint32_t i = 0; i < rtcCount; i++) {
nsRubyTextContainerFrame* textContainer = textContainers[i];
nsReflowStatus textReflowStatus;
@ -328,44 +328,36 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext,
uint8_t rubyPosition = textContainer->StyleText()->mRubyPosition;
MOZ_ASSERT(rubyPosition == NS_STYLE_RUBY_POSITION_OVER ||
rubyPosition == NS_STYLE_RUBY_POSITION_UNDER);
Maybe<Side> side;
Maybe<LogicalSide> side;
if (rubyPosition == NS_STYLE_RUBY_POSITION_OVER) {
side.emplace(lineWM.PhysicalSide(
lineWM.LogicalSideForLineRelativeDir(eLineRelativeDirOver)));
side.emplace(lineWM.LogicalSideForLineRelativeDir(eLineRelativeDirOver));
} else if (rubyPosition == NS_STYLE_RUBY_POSITION_UNDER) {
side.emplace(lineWM.PhysicalSide(
lineWM.LogicalSideForLineRelativeDir(eLineRelativeDirUnder)));
side.emplace(lineWM.LogicalSideForLineRelativeDir(eLineRelativeDirUnder));
} else {
// XXX inter-character support in bug 1055672
MOZ_ASSERT_UNREACHABLE("Unsupported ruby-position");
}
nsPoint position;
LogicalPoint position(lineWM);
if (side.isSome()) {
switch (side.value()) {
case eSideLeft:
offsetRect.SetLeftEdge(offsetRect.X() - bsize);
position = offsetRect.TopLeft();
break;
case eSideRight:
position = offsetRect.TopRight();
offsetRect.SetRightEdge(offsetRect.XMost() + bsize);
break;
case eSideTop:
offsetRect.SetTopEdge(offsetRect.Y() - bsize);
position = offsetRect.TopLeft();
break;
case eSideBottom:
position = offsetRect.BottomLeft();
offsetRect.SetBottomEdge(offsetRect.YMost() + bsize);
break;
if (side.value() == eLogicalSideBStart) {
offsetRect.BStart(lineWM) -= bsize;
offsetRect.BSize(lineWM) += bsize;
position = offsetRect.Origin(lineWM);
} else if (side.value() == eLogicalSideBEnd) {
position = offsetRect.Origin(lineWM) +
LogicalPoint(lineWM, 0, offsetRect.BSize(lineWM));
offsetRect.BSize(lineWM) += bsize;
} else {
MOZ_ASSERT_UNREACHABLE("???");
}
}
// Container width is set to zero here. We will fix it in
// nsLineLayout after the whole line get reflowed.
FinishReflowChild(textContainer, aPresContext, textMetrics,
&textReflowState, position.x, position.y, 0);
&textReflowState, lineWM, position, 0, 0);
}
MOZ_ASSERT(LogicalSize(lineWM, baseRect.Size()).ISize(lineWM) ==
LogicalSize(lineWM, offsetRect.Size()).ISize(lineWM),
MOZ_ASSERT(baseRect.ISize(lineWM) == offsetRect.ISize(lineWM),
"Annotations should only be placed on the block directions");
nscoord deltaISize = segmentISize - baseMetrics.ISize(lineWM);
@ -377,12 +369,13 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext,
}
// Set block leadings of the base container
LogicalMargin leadings(lineWM, offsetRect - baseRect);
NS_ASSERTION(leadings.BStart(lineWM) >= 0 && leadings.BEnd(lineWM) >= 0,
nscoord startLeading = baseRect.BStart(lineWM) - offsetRect.BStart(lineWM);
nscoord endLeading = offsetRect.BEnd(lineWM) - baseRect.BEnd(lineWM);
NS_ASSERTION(startLeading >= 0 && endLeading >= 0,
"Leadings should be non-negative (because adding "
"ruby annotation can only increase the size)");
mBStartLeading = std::max(mBStartLeading, leadings.BStart(lineWM));
mBEndLeading = std::max(mBEndLeading, leadings.BEnd(lineWM));
mBStartLeading = std::max(mBStartLeading, startLeading);
mBEndLeading = std::max(mBEndLeading, endLeading);
}
nsRubyBaseContainerFrame*