diff options
author | athenian200 <athenian200@outlook.com> | 2020-10-25 14:27:17 -0500 |
---|---|---|
committer | athenian200 <athenian200@outlook.com> | 2020-10-28 14:17:16 -0500 |
commit | a2c26490b4ad94336a7940e691d17f7aef040fa2 (patch) | |
tree | ae08eae81166cdaebe293eb3f19c9e677653f693 /layout/generic/nsTextFrame.cpp | |
parent | 7c2bcc48c455d4e4441b12834c3bd4c5bb33c9ba (diff) | |
download | uxp-a2c26490b4ad94336a7940e691d17f7aef040fa2.tar.gz |
Issue #1673 - Part 3: Bring minimum tab advance up to spec.
This provides a clearer rule for the minimum tab advance that brings us to alignment with the spec and both major browsers.
Diffstat (limited to 'layout/generic/nsTextFrame.cpp')
-rw-r--r-- | layout/generic/nsTextFrame.cpp | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 0aab2717f3..07e7a36557 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -1716,6 +1716,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) { @@ -3090,6 +3100,7 @@ public: mLength(aLength), mWordSpacing(WordSpacing(aFrame, mTextRun, aTextStyle)), mLetterSpacing(LetterSpacing(aFrame, aTextStyle)), + mMinTabAdvance(-1.0), mHyphenWidth(-1), mOffsetFromBlockOriginForTabs(aOffsetFromBlockOriginForTabs), mReflowing(true), @@ -3114,6 +3125,7 @@ public: mLength(aFrame->GetContentLength()), mWordSpacing(WordSpacing(aFrame, mTextRun)), mLetterSpacing(LetterSpacing(aFrame)), + mMinTabAdvance(-1.0), mHyphenWidth(-1), mOffsetFromBlockOriginForTabs(0), mReflowing(false), @@ -3178,6 +3190,13 @@ public: void CalcTabWidths(Range aTransformedRange, gfxFloat aTabWidth); + gfxFloat MinTabAdvance() { + if (mMinTabAdvance < 0.0) { + mMinTabAdvance = GetMinTabAdvanceAppUnits(mTextRun); + } + return mMinTabAdvance; + } + const gfxSkipCharsIterator& GetEndHint() { return mTempIterator; } protected: @@ -3210,6 +3229,7 @@ protected: int32_t mLength; // DOM string length, may be INT32_MAX gfxFloat mWordSpacing; // space for each whitespace char gfxFloat mLetterSpacing; // space for each letter + gfxFloat mMinTabAdvance; // min advance for <tab> char gfxFloat mHyphenWidth; gfxFloat mOffsetFromBlockOriginForTabs; @@ -3465,14 +3485,13 @@ PropertyProvider::GetSpacingInternal(Range aRange, Spacing* aSpacing, // aX and the result are in whole appunits. static gfxFloat -AdvanceToNextTab(gfxFloat aX, nsIFrame* aFrame, - gfxTextRun* aTextRun, gfxFloat aTabWidth) +AdvanceToNextTab(gfxFloat aX, nsIFrame* aFrame, gfxTextRun* aTextRun, + 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 NS_round((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 @@ -3535,7 +3554,7 @@ PropertyProvider::CalcTabWidths(Range aRange, gfxFloat aTabWidth) mFrame->SetProperty(TabWidthProperty(), mTabWidths); } double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs, - mFrame, mTextRun, aTabWidth); + mFrame, mTextRun, aTabWidth, MinTabAdvance()); mTabWidths->mWidths.AppendElement(TabWidth(i - startOffset, NSToIntRound(nextTab - mOffsetFromBlockOriginForTabs))); mOffsetFromBlockOriginForTabs = nextTab; @@ -8333,8 +8352,8 @@ nsTextFrame::AddInlineMinISizeForFlow(nsRenderingContext *aRenderingContext, tabWidth = ComputeTabWidthAppUnits(this, textRun); } gfxFloat afterTab = - AdvanceToNextTab(aData->mCurrentLine, this, - textRun, tabWidth); + AdvanceToNextTab(aData->mCurrentLine, this, textRun, tabWidth, + provider.MinTabAdvance()); aData->mCurrentLine = nscoord(afterTab + spacing.mAfter); wordStart = i + 1; } else if (i < flowEndInTextRun || @@ -8495,8 +8514,8 @@ nsTextFrame::AddInlinePrefISizeForFlow(nsRenderingContext *aRenderingContext, tabWidth = ComputeTabWidthAppUnits(this, textRun); } gfxFloat afterTab = - AdvanceToNextTab(aData->mCurrentLine, this, - textRun, tabWidth); + AdvanceToNextTab(aData->mCurrentLine, this, textRun, tabWidth, + provider.MinTabAdvance()); aData->mCurrentLine = nscoord(afterTab + spacing.mAfter); lineStart = i + 1; } else if (preformattedNewline) { |