Bug 1432198 - Ensure tab characters are rendered with a minimum advance of 0.5ch. r=xidorn

This commit is contained in:
Jonathan Kew 2018-09-24 13:38:52 +01:00
Родитель 51a3c01ced
Коммит 75f7196111
1 изменённых файлов: 29 добавлений и 9 удалений

Просмотреть файл

@ -1789,6 +1789,16 @@ GetSpaceWidthAppUnits(const gfxTextRun* aTextRun)
return spaceWidthAppUnits;
}
static gfxFloat
GetMinTabAdvanceAppUnits(const gfxTextRun* aTextRun)
{
gfxFloat chWidthAppUnits =
NS_round(GetFirstFontMetrics(aTextRun->GetFontGroup(),
aTextRun->IsVertical()).zeroOrAveCharWidth *
aTextRun->GetAppUnitsPerDevUnit());
return 0.5 * chWidthAppUnits;
}
static nscoord
LetterSpacing(nsIFrame* aFrame, const nsStyleText* aStyleText = nullptr)
{
@ -3100,6 +3110,7 @@ public:
mLength(aLength),
mWordSpacing(WordSpacing(aFrame, mTextRun, aTextStyle)),
mLetterSpacing(LetterSpacing(aFrame, aTextStyle)),
mMinTabAdvance(-1.0),
mHyphenWidth(-1),
mOffsetFromBlockOriginForTabs(aOffsetFromBlockOriginForTabs),
mJustificationArrayStart(0),
@ -3125,6 +3136,7 @@ public:
mLength(aFrame->GetContentLength()),
mWordSpacing(WordSpacing(aFrame, mTextRun)),
mLetterSpacing(LetterSpacing(aFrame)),
mMinTabAdvance(-1.0),
mHyphenWidth(-1),
mOffsetFromBlockOriginForTabs(0),
mJustificationArrayStart(0),
@ -3191,6 +3203,13 @@ public:
void CalcTabWidths(Range aTransformedRange, gfxFloat aTabWidth) const;
gfxFloat MinTabAdvance() const {
if (mMinTabAdvance < 0.0) {
mMinTabAdvance = GetMinTabAdvanceAppUnits(mTextRun);
}
return mMinTabAdvance;
}
const gfxSkipCharsIterator& GetEndHint() const { return mTempIterator; }
protected:
@ -3223,6 +3242,7 @@ protected:
int32_t mLength; // DOM string length, may be INT32_MAX
const gfxFloat mWordSpacing; // space for each whitespace char
const gfxFloat mLetterSpacing; // space for each letter
mutable gfxFloat mMinTabAdvance; // min advance for <tab> char
mutable gfxFloat mHyphenWidth;
mutable gfxFloat mOffsetFromBlockOriginForTabs;
@ -3480,13 +3500,11 @@ PropertyProvider::GetSpacingInternal(Range aRange, Spacing* aSpacing,
// aX and the result are in whole appunits.
static gfxFloat
AdvanceToNextTab(gfxFloat aX, gfxFloat aTabWidth)
AdvanceToNextTab(gfxFloat aX, gfxFloat aTabWidth, gfxFloat aMinAdvance)
{
// 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) / aTabWidth) * aTabWidth;
// Advance aX to the next multiple of aTabWidth. We must advance
// by at least aMinAdvance.
return ceil((aX + aMinAdvance) / aTabWidth) * aTabWidth;
}
void
@ -3549,7 +3567,7 @@ PropertyProvider::CalcTabWidths(Range aRange, gfxFloat aTabWidth) const
mFrame->SetProperty(TabWidthProperty(), mTabWidths);
}
double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs,
aTabWidth);
aTabWidth, MinTabAdvance());
mTabWidths->mWidths.AppendElement(TabWidth(i - startOffset,
NSToIntRound(nextTab - mOffsetFromBlockOriginForTabs)));
mOffsetFromBlockOriginForTabs = nextTab;
@ -8630,7 +8648,8 @@ nsTextFrame::AddInlineMinISizeForFlow(gfxContext *aRenderingContext,
tabWidth = ComputeTabWidthAppUnits(this, textRun);
}
gfxFloat afterTab =
AdvanceToNextTab(aData->mCurrentLine, tabWidth);
AdvanceToNextTab(aData->mCurrentLine, tabWidth,
provider.MinTabAdvance());
aData->mCurrentLine = nscoord(afterTab + spacing.mAfter);
wordStart = i + 1;
} else if (i < flowEndInTextRun ||
@ -8793,7 +8812,8 @@ nsTextFrame::AddInlinePrefISizeForFlow(gfxContext *aRenderingContext,
tabWidth = ComputeTabWidthAppUnits(this, textRun);
}
gfxFloat afterTab =
AdvanceToNextTab(aData->mCurrentLine, tabWidth);
AdvanceToNextTab(aData->mCurrentLine, tabWidth,
provider.MinTabAdvance());
aData->mCurrentLine = nscoord(afterTab + spacing.mAfter);
aData->mLineIsEmpty = false;
lineStart = i + 1;