Bug 419531. Don't wipe out stored tab widths during text intrinsic size calculation. r+sr=dbaron

This commit is contained in:
roc+@cs.cmu.edu 2008-02-27 01:29:46 -08:00
parent 3bf32d7606
commit 5fdb0cc854

View File

@ -2081,7 +2081,11 @@ protected:
nsTextFrame* mFrame;
gfxSkipCharsIterator mStart; // Offset in original and transformed string
gfxSkipCharsIterator mTempIterator;
nsTArray<gfxFloat>* mTabWidths; // widths for each transformed string character
// Widths for each transformed string character, 0 for non-tab characters.
// Either null, or pointing to the frame's tabWidthProperty.
nsTArray<gfxFloat>* mTabWidths;
PRInt32 mLength; // DOM string length, may be PR_INT32_MAX
gfxFloat mWordSpacing; // space for each whitespace char
gfxFloat mLetterSpacing; // space for each letter
@ -2266,6 +2270,16 @@ PropertyProvider::GetTabWidths(PRUint32 aStart, PRUint32 aLength)
return nsnull;
}
} else {
if (!mLineContainer) {
// Intrinsic width computation, no way to compute real tab widths
// (and we wouldn't want to use it if we could, because it depends
// on layout). Don't wipe out existing tab widths that might still
// be useful for painting. Just return null which uses zero for
// all tab widths.
NS_WARNING("Preformatted tabs encountered in intrinsic width situation");
return nsnull;
}
nsAutoPtr<nsTArray<gfxFloat> > tabs(new nsTArray<gfxFloat>());
if (!tabs)
return nsnull;
@ -2288,47 +2302,38 @@ PropertyProvider::GetTabWidths(PRUint32 aStart, PRUint32 aLength)
if (!mTabWidths->AppendElements(aStart + aLength - tabsEnd))
return nsnull;
PRUint32 i;
if (!mLineContainer) {
NS_WARNING("Tabs encountered in a situation where we don't support tabbing");
for (i = tabsEnd; i < aStart + aLength; ++i) {
gfxFloat tabWidth = NS_round(8*mTextRun->GetAppUnitsPerDevUnit()*
GetFontMetrics(GetFontGroupForFrame(mLineContainer)).spaceWidth);
for (PRUint32 i = tabsEnd; i < aStart + aLength; ++i) {
Spacing spacing;
GetSpacingInternal(i, 1, &spacing, PR_TRUE);
mOffsetFromBlockOriginForTabs += spacing.mBefore;
if (mTextRun->GetChar(i) != '\t') {
(*mTabWidths)[i - startOffset] = 0;
}
} else {
gfxFloat tabWidth = NS_round(8*mTextRun->GetAppUnitsPerDevUnit()*
GetFontMetrics(GetFontGroupForFrame(mLineContainer)).spaceWidth);
for (i = tabsEnd; i < aStart + aLength; ++i) {
Spacing spacing;
GetSpacingInternal(i, 1, &spacing, PR_TRUE);
mOffsetFromBlockOriginForTabs += spacing.mBefore;
if (mTextRun->GetChar(i) != '\t') {
(*mTabWidths)[i - startOffset] = 0;
if (mTextRun->IsClusterStart(i)) {
PRUint32 clusterEnd = i + 1;
while (clusterEnd < mTextRun->GetLength() &&
!mTextRun->IsClusterStart(clusterEnd)) {
++clusterEnd;
}
mOffsetFromBlockOriginForTabs +=
mTextRun->GetAdvanceWidth(i, clusterEnd - i, nsnull);
if (mTextRun->IsClusterStart(i)) {
PRUint32 clusterEnd = i + 1;
while (clusterEnd < mTextRun->GetLength() &&
!mTextRun->IsClusterStart(clusterEnd)) {
++clusterEnd;
}
} else {
// Advance mOffsetFromBlockOriginForTabs to the next multiple of tabWidth
// Ensure that if it's just epsilon less than a multiple of tabWidth, we still
// advance by tabWidth.
static const double EPSILON = 0.000001;
double nextTab = NS_ceil(mOffsetFromBlockOriginForTabs/tabWidth)*tabWidth;
if (nextTab < mOffsetFromBlockOriginForTabs + EPSILON) {
nextTab += tabWidth;
}
(*mTabWidths)[i - startOffset] = nextTab - mOffsetFromBlockOriginForTabs;
mOffsetFromBlockOriginForTabs = nextTab;
mOffsetFromBlockOriginForTabs +=
mTextRun->GetAdvanceWidth(i, clusterEnd - i, nsnull);
}
mOffsetFromBlockOriginForTabs += spacing.mAfter;
} else {
// Advance mOffsetFromBlockOriginForTabs to the next multiple of tabWidth
// Ensure that if it's just epsilon less than a multiple of tabWidth, we still
// advance by tabWidth.
static const double EPSILON = 0.000001;
double nextTab = NS_ceil(mOffsetFromBlockOriginForTabs/tabWidth)*tabWidth;
if (nextTab < mOffsetFromBlockOriginForTabs + EPSILON) {
nextTab += tabWidth;
}
(*mTabWidths)[i - startOffset] = nextTab - mOffsetFromBlockOriginForTabs;
mOffsetFromBlockOriginForTabs = nextTab;
}
mOffsetFromBlockOriginForTabs += spacing.mAfter;
}
}