Bug 1116037 part 3 - Use ruby "column" instead of "pair" to match the spec term. r=dbaron

This commit is contained in:
Xidorn Quan
2014-12-29 14:30:00 +11:00
parent d1ef25d527
commit dcadfdf213
2 changed files with 84 additions and 77 deletions

View File

@@ -55,10 +55,15 @@ nsRubyBaseContainerFrame::GetFrameName(nsAString& aResult) const
} }
#endif #endif
class MOZ_STACK_CLASS PairEnumerator /**
* Ruby column is a unit consists of one ruby base and all ruby
* annotations paired with it.
* See http://dev.w3.org/csswg/css-ruby/#ruby-pairing
*/
class MOZ_STACK_CLASS RubyColumnEnumerator
{ {
public: public:
PairEnumerator(nsRubyBaseContainerFrame* aRBCFrame, RubyColumnEnumerator(nsRubyBaseContainerFrame* aRBCFrame,
const nsTArray<nsRubyTextContainerFrame*>& aRTCFrames); const nsTArray<nsRubyTextContainerFrame*>& aRTCFrames);
void Next(); void Next();
@@ -74,7 +79,7 @@ private:
nsAutoTArray<nsIFrame*, RTC_ARRAY_SIZE + 1> mFrames; nsAutoTArray<nsIFrame*, RTC_ARRAY_SIZE + 1> mFrames;
}; };
PairEnumerator::PairEnumerator( RubyColumnEnumerator::RubyColumnEnumerator(
nsRubyBaseContainerFrame* aBaseContainer, nsRubyBaseContainerFrame* aBaseContainer,
const nsTArray<nsRubyTextContainerFrame*>& aTextContainers) const nsTArray<nsRubyTextContainerFrame*>& aTextContainers)
{ {
@@ -88,7 +93,7 @@ PairEnumerator::PairEnumerator(
} }
void void
PairEnumerator::Next() RubyColumnEnumerator::Next()
{ {
for (uint32_t i = 0, iend = mFrames.Length(); i < iend; i++) { for (uint32_t i = 0, iend = mFrames.Length(); i < iend; i++) {
if (mFrames[i]) { if (mFrames[i]) {
@@ -98,7 +103,7 @@ PairEnumerator::Next()
} }
bool bool
PairEnumerator::AtEnd() const RubyColumnEnumerator::AtEnd() const
{ {
for (uint32_t i = 0, iend = mFrames.Length(); i < iend; i++) { for (uint32_t i = 0, iend = mFrames.Length(); i < iend; i++) {
if (mFrames[i]) { if (mFrames[i]) {
@@ -109,7 +114,7 @@ PairEnumerator::AtEnd() const
} }
void void
PairEnumerator::GetFrames(nsIFrame*& aBaseFrame, RubyColumnEnumerator::GetFrames(nsIFrame*& aBaseFrame,
nsTArray<nsIFrame*>& aTextFrames) const nsTArray<nsIFrame*>& aTextFrames) const
{ {
aBaseFrame = mFrames[0]; aBaseFrame = mFrames[0];
@@ -134,8 +139,8 @@ nsRubyBaseContainerFrame::CalculateMaxSpanISize(
} }
static nscoord static nscoord
CalculatePairPrefISize(nsRenderingContext* aRenderingContext, CalculateColumnPrefISize(nsRenderingContext* aRenderingContext,
const PairEnumerator& aEnumerator) const RubyColumnEnumerator& aEnumerator)
{ {
nscoord max = 0; nscoord max = 0;
uint32_t levelCount = aEnumerator.GetLevelCount(); uint32_t levelCount = aEnumerator.GetLevelCount();
@@ -160,11 +165,12 @@ nsRubyBaseContainerFrame::AddInlineMinISize(
} }
nscoord max = 0; nscoord max = 0;
PairEnumerator enumerator(this, mTextContainers); RubyColumnEnumerator enumerator(this, mTextContainers);
for (; !enumerator.AtEnd(); enumerator.Next()) { for (; !enumerator.AtEnd(); enumerator.Next()) {
// We use *pref* isize for computing the min isize of pairs // We use *pref* isize for computing the min isize of columns
// because ruby bases and texts are unbreakable internally. // because ruby bases and texts are unbreakable internally.
max = std::max(max, CalculatePairPrefISize(aRenderingContext, enumerator)); max = std::max(max, CalculateColumnPrefISize(aRenderingContext,
enumerator));
} }
aData->currentLine += max; aData->currentLine += max;
} }
@@ -174,9 +180,9 @@ nsRubyBaseContainerFrame::AddInlinePrefISize(
nsRenderingContext *aRenderingContext, nsIFrame::InlinePrefISizeData *aData) nsRenderingContext *aRenderingContext, nsIFrame::InlinePrefISizeData *aData)
{ {
nscoord sum = 0; nscoord sum = 0;
PairEnumerator enumerator(this, mTextContainers); RubyColumnEnumerator enumerator(this, mTextContainers);
for (; !enumerator.AtEnd(); enumerator.Next()) { for (; !enumerator.AtEnd(); enumerator.Next()) {
sum += CalculatePairPrefISize(aRenderingContext, enumerator); sum += CalculateColumnPrefISize(aRenderingContext, enumerator);
} }
sum = std::max(sum, CalculateMaxSpanISize(aRenderingContext)); sum = std::max(sum, CalculateMaxSpanISize(aRenderingContext));
aData->currentLine += sum; aData->currentLine += sum;
@@ -357,13 +363,13 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext,
nscoord isize = 0; nscoord isize = 0;
if (aStatus == NS_FRAME_COMPLETE) { if (aStatus == NS_FRAME_COMPLETE) {
// Reflow pairs excluding any span // Reflow columns excluding any span
bool allowInternalLineBreak = allowLineBreak && mSpanContainers.IsEmpty(); bool allowInternalLineBreak = allowLineBreak && mSpanContainers.IsEmpty();
isize = ReflowPairs(aPresContext, allowInternalLineBreak, isize = ReflowColumns(aPresContext, allowInternalLineBreak,
aReflowState, rtcReflowStates, aStatus); aReflowState, rtcReflowStates, aStatus);
} }
// If there exists any span, the pairs must either be completely // If there exists any span, the columns must either be completely
// reflowed, or be not reflowed at all. // reflowed, or be not reflowed at all.
MOZ_ASSERT(NS_INLINE_IS_BREAK_BEFORE(aStatus) || MOZ_ASSERT(NS_INLINE_IS_BREAK_BEFORE(aStatus) ||
NS_FRAME_IS_COMPLETE(aStatus) || mSpanContainers.IsEmpty()); NS_FRAME_IS_COMPLETE(aStatus) || mSpanContainers.IsEmpty());
@@ -383,7 +389,7 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext,
isize = spanISize; isize = spanISize;
} }
} }
// When there are spans, ReflowPairs and ReflowOnePair won't // When there are spans, ReflowColumns and ReflowOneColumn won't
// record any optional break position. We have to record one // record any optional break position. We have to record one
// at the end of this segment. // at the end of this segment.
if (!NS_INLINE_IS_BREAK(aStatus) && allowLineBreak && if (!NS_INLINE_IS_BREAK(aStatus) && allowLineBreak &&
@@ -443,7 +449,7 @@ struct MOZ_STACK_CLASS nsRubyBaseContainerFrame::PullFrameState
}; };
nscoord nscoord
nsRubyBaseContainerFrame::ReflowPairs(nsPresContext* aPresContext, nsRubyBaseContainerFrame::ReflowColumns(nsPresContext* aPresContext,
bool aAllowLineBreak, bool aAllowLineBreak,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsTArray<nsHTMLReflowState*>& aReflowStates, nsTArray<nsHTMLReflowState*>& aReflowStates,
@@ -456,14 +462,14 @@ nsRubyBaseContainerFrame::ReflowPairs(nsPresContext* aPresContext,
nsReflowStatus reflowStatus = NS_FRAME_COMPLETE; nsReflowStatus reflowStatus = NS_FRAME_COMPLETE;
aStatus = NS_FRAME_COMPLETE; aStatus = NS_FRAME_COMPLETE;
mPairCount = 0; mColumnCount = 0;
nsIFrame* baseFrame = nullptr; nsIFrame* baseFrame = nullptr;
nsAutoTArray<nsIFrame*, RTC_ARRAY_SIZE> textFrames; nsAutoTArray<nsIFrame*, RTC_ARRAY_SIZE> textFrames;
textFrames.SetCapacity(rtcCount); textFrames.SetCapacity(rtcCount);
PairEnumerator e(this, mTextContainers); RubyColumnEnumerator e(this, mTextContainers);
for (; !e.AtEnd(); e.Next()) { for (; !e.AtEnd(); e.Next()) {
e.GetFrames(baseFrame, textFrames); e.GetFrames(baseFrame, textFrames);
icoord += ReflowOnePair(aPresContext, aAllowLineBreak, icoord += ReflowOneColumn(aPresContext, aAllowLineBreak,
aReflowState, aReflowStates, aReflowState, aReflowStates,
baseFrame, textFrames, reflowStatus); baseFrame, textFrames, reflowStatus);
if (NS_INLINE_IS_BREAK(reflowStatus)) { if (NS_INLINE_IS_BREAK(reflowStatus)) {
@@ -481,19 +487,20 @@ nsRubyBaseContainerFrame::ReflowPairs(nsPresContext* aPresContext,
// Try pull some frames from next continuations. This call replaces // Try pull some frames from next continuations. This call replaces
// |baseFrame| and |textFrames| with the frame pulled in each level. // |baseFrame| and |textFrames| with the frame pulled in each level.
PullOnePair(lineLayout, pullFrameState, baseFrame, textFrames, isComplete); PullOneColumn(lineLayout, pullFrameState,
baseFrame, textFrames, isComplete);
if (isComplete) { if (isComplete) {
// No more frames can be pulled. // No more frames can be pulled.
break; break;
} }
icoord += ReflowOnePair(aPresContext, aAllowLineBreak, icoord += ReflowOneColumn(aPresContext, aAllowLineBreak,
aReflowState, aReflowStates, aReflowState, aReflowStates,
baseFrame, textFrames, reflowStatus); baseFrame, textFrames, reflowStatus);
} }
if (!e.AtEnd() && NS_INLINE_IS_BREAK_AFTER(reflowStatus)) { if (!e.AtEnd() && NS_INLINE_IS_BREAK_AFTER(reflowStatus)) {
// The current pair has been successfully placed. // The current column has been successfully placed.
// Skip to the next pair and mark break before. // Skip to the next column and mark break before.
e.Next(); e.Next();
e.GetFrames(baseFrame, textFrames); e.GetFrames(baseFrame, textFrames);
reflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); reflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
@@ -503,8 +510,8 @@ nsRubyBaseContainerFrame::ReflowPairs(nsPresContext* aPresContext,
} }
if (NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) { if (NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) {
if (!mPairCount || !mSpanContainers.IsEmpty()) { if (!mColumnCount || !mSpanContainers.IsEmpty()) {
// If no pair has been placed yet, or we have any span, // If no column has been placed yet, or we have any span,
// the whole container should be in the next line. // the whole container should be in the next line.
aStatus = NS_INLINE_LINE_BREAK_BEFORE(); aStatus = NS_INLINE_LINE_BREAK_BEFORE();
return 0; return 0;
@@ -524,7 +531,7 @@ nsRubyBaseContainerFrame::ReflowPairs(nsPresContext* aPresContext,
} }
} else if (NS_INLINE_IS_BREAK_AFTER(reflowStatus)) { } else if (NS_INLINE_IS_BREAK_AFTER(reflowStatus)) {
// |reflowStatus| being break after here may only happen when // |reflowStatus| being break after here may only happen when
// there is a break after the pair just pulled, or the whole // there is a break after the column just pulled, or the whole
// segment has been completely reflowed. In those cases, we do // segment has been completely reflowed. In those cases, we do
// not need to push anything. // not need to push anything.
MOZ_ASSERT(e.AtEnd()); MOZ_ASSERT(e.AtEnd());
@@ -535,7 +542,7 @@ nsRubyBaseContainerFrame::ReflowPairs(nsPresContext* aPresContext,
} }
nscoord nscoord
nsRubyBaseContainerFrame::ReflowOnePair(nsPresContext* aPresContext, nsRubyBaseContainerFrame::ReflowOneColumn(nsPresContext* aPresContext,
bool aAllowLineBreak, bool aAllowLineBreak,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsTArray<nsHTMLReflowState*>& aReflowStates, nsTArray<nsHTMLReflowState*>& aReflowStates,
@@ -548,7 +555,7 @@ nsRubyBaseContainerFrame::ReflowOnePair(nsPresContext* aPresContext,
MOZ_ASSERT(aTextFrames.Length() == rtcCount); MOZ_ASSERT(aTextFrames.Length() == rtcCount);
MOZ_ASSERT(aReflowStates.Length() == rtcCount); MOZ_ASSERT(aReflowStates.Length() == rtcCount);
nscoord istart = aReflowState.mLineLayout->GetCurrentICoord(); nscoord istart = aReflowState.mLineLayout->GetCurrentICoord();
nscoord pairISize = 0; nscoord columnISize = 0;
nsAutoString baseText; nsAutoString baseText;
if (aBaseFrame) { if (aBaseFrame) {
@@ -588,10 +595,10 @@ nsRubyBaseContainerFrame::ReflowOnePair(nsPresContext* aPresContext,
&metrics, pushedFrame); &metrics, pushedFrame);
MOZ_ASSERT(!NS_INLINE_IS_BREAK(reflowStatus) && !pushedFrame, MOZ_ASSERT(!NS_INLINE_IS_BREAK(reflowStatus) && !pushedFrame,
"Any line break inside ruby box should has been suppressed"); "Any line break inside ruby box should has been suppressed");
pairISize = std::max(pairISize, metrics.ISize(lineWM)); columnISize = std::max(columnISize, metrics.ISize(lineWM));
} }
} }
if (aAllowLineBreak && ShouldBreakBefore(aReflowState, pairISize)) { if (aAllowLineBreak && ShouldBreakBefore(aReflowState, columnISize)) {
// Since ruby text container uses an independent line layout, it // Since ruby text container uses an independent line layout, it
// may successfully place a frame because the line is empty while // may successfully place a frame because the line is empty while
// the line of base container is not. // the line of base container is not.
@@ -611,11 +618,11 @@ nsRubyBaseContainerFrame::ReflowOnePair(nsPresContext* aPresContext,
&metrics, pushedFrame); &metrics, pushedFrame);
MOZ_ASSERT(!NS_INLINE_IS_BREAK(reflowStatus) && !pushedFrame, MOZ_ASSERT(!NS_INLINE_IS_BREAK(reflowStatus) && !pushedFrame,
"Any line break inside ruby box should has been suppressed"); "Any line break inside ruby box should has been suppressed");
pairISize = std::max(pairISize, metrics.ISize(lineWM)); columnISize = std::max(columnISize, metrics.ISize(lineWM));
} }
// Align all the line layout to the new coordinate. // Align all the line layout to the new coordinate.
nscoord icoord = istart + pairISize; nscoord icoord = istart + columnISize;
nscoord deltaISize = icoord - aReflowState.mLineLayout->GetCurrentICoord(); nscoord deltaISize = icoord - aReflowState.mLineLayout->GetCurrentICoord();
if (deltaISize > 0) { if (deltaISize > 0) {
aReflowState.mLineLayout->AdvanceICoord(deltaISize); aReflowState.mLineLayout->AdvanceICoord(deltaISize);
@@ -638,15 +645,15 @@ nsRubyBaseContainerFrame::ReflowOnePair(nsPresContext* aPresContext,
} }
} }
mPairCount++; mColumnCount++;
if (aAllowLineBreak && if (aAllowLineBreak &&
aReflowState.mLineLayout->NotifyOptionalBreakPosition( aReflowState.mLineLayout->NotifyOptionalBreakPosition(
this, mPairCount, icoord <= aReflowState.AvailableISize(), this, mColumnCount, icoord <= aReflowState.AvailableISize(),
gfxBreakPriority::eNormalBreak)) { gfxBreakPriority::eNormalBreak)) {
aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus);
} }
return pairISize; return columnISize;
} }
nsRubyBaseContainerFrame::PullFrameState::PullFrameState( nsRubyBaseContainerFrame::PullFrameState::PullFrameState(
@@ -660,7 +667,7 @@ nsRubyBaseContainerFrame::PullFrameState::PullFrameState(
} }
void void
nsRubyBaseContainerFrame::PullOnePair(nsLineLayout* aLineLayout, nsRubyBaseContainerFrame::PullOneColumn(nsLineLayout* aLineLayout,
PullFrameState& aPullFrameState, PullFrameState& aPullFrameState,
nsIFrame*& aBaseFrame, nsIFrame*& aBaseFrame,
nsTArray<nsIFrame*>& aTextFrames, nsTArray<nsIFrame*>& aTextFrames,

View File

@@ -78,13 +78,13 @@ protected:
nscoord CalculateMaxSpanISize(nsRenderingContext* aRenderingContext); nscoord CalculateMaxSpanISize(nsRenderingContext* aRenderingContext);
nscoord ReflowPairs(nsPresContext* aPresContext, nscoord ReflowColumns(nsPresContext* aPresContext,
bool aAllowLineBreak, bool aAllowLineBreak,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsTArray<nsHTMLReflowState*>& aReflowStates, nsTArray<nsHTMLReflowState*>& aReflowStates,
nsReflowStatus& aStatus); nsReflowStatus& aStatus);
nscoord ReflowOnePair(nsPresContext* aPresContext, nscoord ReflowOneColumn(nsPresContext* aPresContext,
bool aAllowLineBreak, bool aAllowLineBreak,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsTArray<nsHTMLReflowState*>& aReflowStates, nsTArray<nsHTMLReflowState*>& aReflowStates,
@@ -100,7 +100,7 @@ protected:
// Pull ruby base and corresponding ruby text frames from // Pull ruby base and corresponding ruby text frames from
// continuations after them. // continuations after them.
void PullOnePair(nsLineLayout* aLineLayout, void PullOneColumn(nsLineLayout* aLineLayout,
PullFrameState& aPullFrameState, PullFrameState& aPullFrameState,
nsIFrame*& aBaseFrame, nsIFrame*& aBaseFrame,
nsTArray<nsIFrame*>& aTextFrames, nsTArray<nsIFrame*>& aTextFrames,
@@ -113,13 +113,13 @@ protected:
*/ */
// The text containers that contain a span, which spans all ruby // The text containers that contain a span, which spans all ruby
// pairs in the ruby segment. // columns in the ruby segment.
nsTArray<nsRubyTextContainerFrame*> mSpanContainers; nsTArray<nsRubyTextContainerFrame*> mSpanContainers;
// Normal text containers that do not contain spans. // Normal text containers that do not contain spans.
nsTArray<nsRubyTextContainerFrame*> mTextContainers; nsTArray<nsRubyTextContainerFrame*> mTextContainers;
nscoord mBaseline; nscoord mBaseline;
uint32_t mPairCount; uint32_t mColumnCount;
}; };
#endif /* nsRubyBaseContainerFrame_h___ */ #endif /* nsRubyBaseContainerFrame_h___ */