Bug 943918 - Part 2: layout for tab-size:<length> and tab-size:<number>. r=heycam

This commit is contained in:
Thomas Wisniewski 2016-11-25 00:18:11 -05:00
parent ae1257b378
commit 813450469e

View File

@ -3163,7 +3163,7 @@ public:
return mFontMetrics;
}
void CalcTabWidths(Range aTransformedRange);
void CalcTabWidths(Range aTransformedRange, gfxFloat aTabWidth);
const gfxSkipCharsIterator& GetEndHint() { return mTempIterator; }
@ -3349,6 +3349,28 @@ CanAddSpacingAfter(const gfxTextRun* aTextRun, uint32_t aOffset)
aTextRun->IsLigatureGroupStart(aOffset + 1);
}
static gfxFloat
ComputeTabWidthAppUnits(nsIFrame* aFrame, gfxTextRun* aTextRun)
{
const nsStyleText* textStyle = aFrame->StyleText();
if (textStyle->mTabSize.GetUnit() != eStyleUnit_Factor) {
nscoord w = textStyle->mTabSize.GetCoordValue();
MOZ_ASSERT(w >= 0);
return w;
}
gfxFloat spaces = textStyle->mTabSize.GetFactorValue();
MOZ_ASSERT(spaces >= 0);
// Round the space width when converting to appunits the same way
// textruns do.
gfxFloat spaceWidthAppUnits =
NS_round(GetFirstFontMetrics(aTextRun->GetFontGroup(),
aTextRun->IsVertical()).spaceWidth *
aTextRun->GetAppUnitsPerDevUnit());
return spaces * spaceWidthAppUnits;
}
void
PropertyProvider::GetSpacingInternal(Range aRange, Spacing* aSpacing,
bool aIgnoreTabs)
@ -3396,17 +3418,16 @@ PropertyProvider::GetSpacingInternal(Range aRange, Spacing* aSpacing,
}
}
// Ignore tab spacing rather than computing it, if the tab size is 0
if (!aIgnoreTabs)
aIgnoreTabs = mFrame->StyleText()->mTabSize == 0;
// Now add tab spacing, if there is any
if (!aIgnoreTabs) {
CalcTabWidths(aRange);
if (mTabWidths) {
mTabWidths->ApplySpacing(aSpacing,
aRange.start - mStart.GetSkippedOffset(),
aRange.Length());
gfxFloat tabWidth = ComputeTabWidthAppUnits(mFrame, mTextRun);
if (tabWidth > 0) {
CalcTabWidths(aRange, tabWidth);
if (mTabWidths) {
mTabWidths->ApplySpacing(aSpacing,
aRange.start - mStart.GetSkippedOffset(),
aRange.Length());
}
}
}
@ -3429,33 +3450,23 @@ PropertyProvider::GetSpacingInternal(Range aRange, Spacing* aSpacing,
}
}
static gfxFloat
ComputeTabWidthAppUnits(nsIFrame* aFrame, const gfxTextRun* aTextRun)
{
// Get the number of spaces from CSS -moz-tab-size
const nsStyleText* textStyle = aFrame->StyleText();
return textStyle->mTabSize * GetSpaceWidthAppUnits(aTextRun);
}
// aX and the result are in whole appunits.
static gfxFloat
AdvanceToNextTab(gfxFloat aX, nsIFrame* aFrame,
const gfxTextRun* aTextRun, gfxFloat* aCachedTabWidth)
gfxTextRun* aTextRun, gfxFloat aTabWidth)
{
if (*aCachedTabWidth < 0) {
*aCachedTabWidth = ComputeTabWidthAppUnits(aFrame, aTextRun);
}
// Advance aX to the next multiple of *aCachedTabWidth. We must advance
// by at least 1 appunit.
// XXX should we make this 1 CSS pixel?
return ceil((aX + 1)/(*aCachedTabWidth))*(*aCachedTabWidth);
return ceil((aX + 1) / aTabWidth) * aTabWidth;
}
void
PropertyProvider::CalcTabWidths(Range aRange)
PropertyProvider::CalcTabWidths(Range aRange, gfxFloat aTabWidth)
{
MOZ_ASSERT(aTabWidth > 0);
if (!mTabWidths) {
if (mReflowing && !mLineContainer) {
// Intrinsic width computation does its own tab processing. We
@ -3490,7 +3501,6 @@ PropertyProvider::CalcTabWidths(Range aRange)
NS_ASSERTION(mReflowing,
"We need precomputed tab widths, but don't have enough.");
gfxFloat tabWidth = -1;
for (uint32_t i = tabsEnd; i < aRange.end; ++i) {
Spacing spacing;
GetSpacingInternal(Range(i, i + 1), &spacing, true);
@ -3512,7 +3522,7 @@ PropertyProvider::CalcTabWidths(Range aRange)
mFrame->Properties().Set(TabWidthProperty(), mTabWidths);
}
double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs,
mFrame, mTextRun, &tabWidth);
mFrame, mTextRun, aTabWidth);
mTabWidths->mWidths.AppendElement(TabWidth(i - startOffset,
NSToIntRound(nextTab - mOffsetFromBlockOriginForTabs)));
mOffsetFromBlockOriginForTabs = nextTab;
@ -8434,9 +8444,11 @@ nsTextFrame::AddInlineMinISizeForFlow(nsRenderingContext *aRenderingContext,
PropertyProvider::Spacing spacing;
provider.GetSpacing(Range(i, i + 1), &spacing);
aData->mCurrentLine += nscoord(spacing.mBefore);
if (tabWidth < 0) {
tabWidth = ComputeTabWidthAppUnits(this, textRun);
}
gfxFloat afterTab =
AdvanceToNextTab(aData->mCurrentLine, this,
textRun, &tabWidth);
AdvanceToNextTab(aData->mCurrentLine, this, textRun, tabWidth);
aData->mCurrentLine = nscoord(afterTab + spacing.mAfter);
wordStart = i + 1;
} else if (i < flowEndInTextRun ||
@ -8595,9 +8607,11 @@ nsTextFrame::AddInlinePrefISizeForFlow(nsRenderingContext *aRenderingContext,
PropertyProvider::Spacing spacing;
provider.GetSpacing(Range(i, i + 1), &spacing);
aData->mCurrentLine += nscoord(spacing.mBefore);
if (tabWidth < 0) {
tabWidth = ComputeTabWidthAppUnits(this, textRun);
}
gfxFloat afterTab =
AdvanceToNextTab(aData->mCurrentLine, this,
textRun, &tabWidth);
AdvanceToNextTab(aData->mCurrentLine, this, textRun, tabWidth);
aData->mCurrentLine = nscoord(afterTab + spacing.mAfter);
aData->mLineIsEmpty = false;
lineStart = i + 1;