diff options
Diffstat (limited to 'layout/generic')
-rw-r--r-- | layout/generic/nsTextFrame.cpp | 74 |
1 files changed, 45 insertions, 29 deletions
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index c7b55961c..749b8b944 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -3178,7 +3178,7 @@ public: return mFontMetrics; } - void CalcTabWidths(Range aTransformedRange); + void CalcTabWidths(Range aTransformedRange, gfxFloat aTabWidth); const gfxSkipCharsIterator& GetEndHint() { return mTempIterator; } @@ -3364,6 +3364,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) @@ -3411,17 +3433,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); + if (mTabWidths) { + mTabWidths->ApplySpacing(aSpacing, + aRange.start - mStart.GetSkippedOffset(), + aRange.Length()); + } } } @@ -3444,33 +3465,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 @@ -3505,7 +3516,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); @@ -3527,7 +3537,7 @@ PropertyProvider::CalcTabWidths(Range aRange) mFrame->SetProperty(TabWidthProperty(), mTabWidths); } double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs, - mFrame, mTextRun, &tabWidth); + mFrame, mTextRun, aTabWidth); mTabWidths->mWidths.AppendElement(TabWidth(i - startOffset, NSToIntRound(nextTab - mOffsetFromBlockOriginForTabs))); mOffsetFromBlockOriginForTabs = nextTab; @@ -8321,9 +8331,12 @@ 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); + textRun, tabWidth); aData->mCurrentLine = nscoord(afterTab + spacing.mAfter); wordStart = i + 1; } else if (i < flowEndInTextRun || @@ -8480,9 +8493,12 @@ 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); + textRun, tabWidth); aData->mCurrentLine = nscoord(afterTab + spacing.mAfter); lineStart = i + 1; } else if (preformattedNewline) { |