Bug 1180443 - Consider whitespace collapse when calculating intrinsic isize of ruby. r=dbaron

This commit is contained in:
Xidorn Quan
2015-07-09 16:05:26 +10:00
parent 7945dce254
commit b4f4bab661
4 changed files with 94 additions and 3 deletions

View File

@@ -128,9 +128,18 @@ GetIsLineBreakAllowed(nsIFrame* aFrame, bool aIsLineBreakable,
*aAllowLineBreak = allowLineBreak;
}
/**
* @param aBaseISizeData is an in/out param. This method updates the
* `skipWhitespace` and `trailingWhitespace` fields of the struct with
* the base level frame. Note that we don't need to do the same thing
* for ruby text frames, because they are text run container themselves
* (see nsTextFrame.cpp:BuildTextRuns), and thus no whitespace collapse
* happens across the boundary of those frames.
*/
static nscoord
CalculateColumnPrefISize(nsRenderingContext* aRenderingContext,
const RubyColumnEnumerator& aEnumerator)
const RubyColumnEnumerator& aEnumerator,
nsIFrame::InlineIntrinsicISizeData* aBaseISizeData)
{
nscoord max = 0;
uint32_t levelCount = aEnumerator.GetLevelCount();
@@ -138,9 +147,22 @@ CalculateColumnPrefISize(nsRenderingContext* aRenderingContext,
nsIFrame* frame = aEnumerator.GetFrameAtLevel(i);
if (frame) {
nsIFrame::InlinePrefISizeData data;
if (i == 0) {
data.lineContainer = aBaseISizeData->lineContainer;
data.skipWhitespace = aBaseISizeData->skipWhitespace;
data.trailingWhitespace = aBaseISizeData->trailingWhitespace;
} else {
// The line container of ruby text frames is their parent,
// ruby text container frame.
data.lineContainer = frame->GetParent();
}
frame->AddInlinePrefISize(aRenderingContext, &data);
MOZ_ASSERT(data.prevLines == 0, "Shouldn't have prev lines");
max = std::max(max, data.currentLine);
if (i == 0) {
aBaseISizeData->skipWhitespace = data.skipWhitespace;
aBaseISizeData->trailingWhitespace = data.trailingWhitespace;
}
}
}
return max;
@@ -160,11 +182,16 @@ nsRubyBaseContainerFrame::AddInlineMinISize(
// Since spans are not breakable internally, use our pref isize
// directly if there is any span.
nsIFrame::InlinePrefISizeData data;
data.lineContainer = aData->lineContainer;
data.skipWhitespace = aData->skipWhitespace;
data.trailingWhitespace = aData->trailingWhitespace;
AddInlinePrefISize(aRenderingContext, &data);
aData->currentLine += data.currentLine;
if (data.currentLine > 0) {
aData->atStartOfLine = false;
}
aData->skipWhitespace = data.skipWhitespace;
aData->trailingWhitespace = data.trailingWhitespace;
return;
}
}
@@ -188,7 +215,8 @@ nsRubyBaseContainerFrame::AddInlineMinISize(
}
}
firstFrame = false;
nscoord isize = CalculateColumnPrefISize(aRenderingContext, enumerator);
nscoord isize = CalculateColumnPrefISize(aRenderingContext,
enumerator, aData);
aData->currentLine += isize;
if (isize > 0) {
aData->atStartOfLine = false;
@@ -208,7 +236,7 @@ nsRubyBaseContainerFrame::AddInlinePrefISize(
RubyColumnEnumerator enumerator(
static_cast<nsRubyBaseContainerFrame*>(frame), textContainers);
for (; !enumerator.AtEnd(); enumerator.Next()) {
sum += CalculateColumnPrefISize(aRenderingContext, enumerator);
sum += CalculateColumnPrefISize(aRenderingContext, enumerator, aData);
}
}
for (uint32_t i = 0, iend = textContainers.Length(); i < iend; i++) {