Bug 1395777 (part 1) - Allow rtc to use its own writing mode. r?xidorn
MozReview-Commit-ID: EkYL53YxGQV
--- 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((!!mBaseLineLayout) ==
- aOuterReflowInput->mFrame->IsRubyTextContainerFrame(),
- "Only ruby text container frames have "
+ MOZ_ASSERT(aOuterReflowInput->mFrame->IsRubyTextContainerFrame() ||
+ !mBaseLineLayout,
+ "Only ruby text container frames may 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
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -336,45 +336,51 @@ nsRubyBaseContainerFrame::Reflow(nsPresC
AutoTArray<UniquePtr<nsLineLayout>, RTC_ARRAY_SIZE> lineLayouts;
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.
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,
- aReflowInput.mLineLayout);
+ baseLineLayout);
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, lineWM, nsSize(0, 0));
- lineLayout->AttachRootFrameToBaseLineLayout();
+ NS_UNCONSTRAINEDSIZE, false, false,
+ baseLineLayout ? lineWM : rtcWM, nsSize(0, 0));
+ if (baseLineLayout) {
+ lineLayout->AttachRootFrameToBaseLineLayout();
+ }
}
aReflowInput.mLineLayout->BeginSpan(this, &aReflowInput,
0, aReflowInput.AvailableISize(),
&mBaseline);
bool allowInitialLineBreak, allowLineBreak;
GetIsLineBreakAllowed(this, aReflowInput.mLineLayout->LineIsBreakable(),
--- a/layout/generic/nsRubyFrame.cpp
+++ b/layout/generic/nsRubyFrame.cpp
@@ -310,21 +310,16 @@ nsRubyFrame::ReflowSegment(nsPresContext
offsetRect.BSize(lineWM) += descLeadings.mStart + descLeadings.mEnd;
for (uint32_t i = 0; i < rtcCount; i++) {
nsRubyTextContainerFrame* textContainer = textContainers[i];
WritingMode rtcWM = textContainer->GetWritingMode();
nsReflowStatus textReflowStatus;
ReflowOutput textMetrics(aReflowInput);
ReflowInput textReflowInput(aPresContext, aReflowInput, textContainer,
availSize.ConvertTo(rtcWM, lineWM));
- // FIXME We probably shouldn't be using the same nsLineLayout for
- // the text containers. But it should be fine now as we are
- // not actually using this line layout to reflow something,
- // but just read the writing mode from it.
- textReflowInput.mLineLayout = aReflowInput.mLineLayout;
textContainer->Reflow(aPresContext, textMetrics,
textReflowInput, textReflowStatus);
// Ruby text containers always return complete reflow status even when
// they have continuations, because the breaking has already been
// handled when reflowing the base containers.
NS_ASSERTION(textReflowStatus.IsEmpty(),
"Ruby text container must not break itself inside");
// The metrics is initialized with reflow state of this ruby frame,
--- a/layout/generic/nsRubyTextContainerFrame.cpp
+++ b/layout/generic/nsRubyTextContainerFrame.cpp
@@ -123,53 +123,53 @@ nsRubyTextContainerFrame::Reflow(nsPresC
DO_GLOBAL_REFLOW_COUNT("nsRubyTextContainerFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
// Although a ruby text container may have continuations, returning
// complete reflow status is still safe, since its parent, ruby frame,
// ignores the status, and continuations of the ruby base container
// will take care of our continuations.
aStatus.Reset();
- WritingMode lineWM = aReflowInput.mLineLayout->GetWritingMode();
+ WritingMode rtcWM = GetWritingMode();
nscoord minBCoord = nscoord_MAX;
nscoord maxBCoord = nscoord_MIN;
// The container size is not yet known, so we use a dummy (0, 0) size.
// The block-dir position will be corrected below after containerSize
// is finalized.
const nsSize dummyContainerSize;
for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
nsIFrame* child = e.get();
MOZ_ASSERT(child->IsRubyTextFrame());
- LogicalRect rect = child->GetLogicalRect(lineWM, dummyContainerSize);
- LogicalMargin margin = child->GetLogicalUsedMargin(lineWM);
- nscoord blockStart = rect.BStart(lineWM) - margin.BStart(lineWM);
+ LogicalRect rect = child->GetLogicalRect(rtcWM, dummyContainerSize);
+ LogicalMargin margin = child->GetLogicalUsedMargin(rtcWM);
+ nscoord blockStart = rect.BStart(rtcWM) - margin.BStart(rtcWM);
minBCoord = std::min(minBCoord, blockStart);
- nscoord blockEnd = rect.BEnd(lineWM) + margin.BEnd(lineWM);
+ nscoord blockEnd = rect.BEnd(rtcWM) + margin.BEnd(rtcWM);
maxBCoord = std::max(maxBCoord, blockEnd);
}
- LogicalSize size(lineWM, mISize, 0);
+ LogicalSize size(rtcWM, mISize, 0);
if (!mFrames.IsEmpty()) {
if (MOZ_UNLIKELY(minBCoord > maxBCoord)) {
// XXX When bug 765861 gets fixed, this warning should be upgraded.
NS_WARNING("bad block coord");
minBCoord = maxBCoord = 0;
}
- size.BSize(lineWM) = maxBCoord - minBCoord;
- nsSize containerSize = size.GetPhysicalSize(lineWM);
+ size.BSize(rtcWM) = maxBCoord - minBCoord;
+ nsSize containerSize = size.GetPhysicalSize(rtcWM);
for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
nsIFrame* child = e.get();
// We reflowed the child with a dummy container size, as the true size
// was not yet known at that time.
- LogicalPoint pos = child->GetLogicalPosition(lineWM, dummyContainerSize);
+ LogicalPoint pos = child->GetLogicalPosition(rtcWM, dummyContainerSize);
// Adjust block position to account for minBCoord,
// then reposition child based on the true container width.
- pos.B(lineWM) -= minBCoord;
+ pos.B(rtcWM) -= minBCoord;
// Relative positioning hasn't happened yet.
// So MovePositionBy should not be used here.
- child->SetPosition(lineWM, pos, containerSize);
+ child->SetPosition(rtcWM, pos, containerSize);
nsContainerFrame::PlaceFrameView(child);
}
}
- aDesiredSize.SetSize(lineWM, size);
+ aDesiredSize.SetSize(rtcWM, size);
}