Bug 1114297 - Improve performance of nsTreeBodyFrame::AdjustForCellText for very long strings; r=smontagu

This commit is contained in:
Geoff Lankow 2015-01-11 00:07:58 +13:00
Родитель 867642220c
Коммит 125624cd03
3 изменённых файлов: 41 добавлений и 8 удалений

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

@ -5121,6 +5121,28 @@ nsLayoutUtils::AppUnitWidthOfStringBidi(const char16_t* aString,
aContext);
}
bool
nsLayoutUtils::StringWidthIsGreaterThan(const nsString& aString,
nsFontMetrics& aFontMetrics,
nsRenderingContext& aContext,
nscoord aWidth)
{
const char16_t *string = aString.get();
uint32_t length = aString.Length();
uint32_t maxChunkLength = GetMaxChunkLength(aFontMetrics);
nscoord width = 0;
while (length > 0) {
int32_t len = FindSafeLength(string, length, maxChunkLength);
width += aFontMetrics.GetWidth(string, len, &aContext);
if (width > aWidth) {
return true;
}
length -= len;
string += len;
}
return false;
}
nsBoundingMetrics
nsLayoutUtils::AppUnitBoundsOfString(const char16_t* aString,
uint32_t aLength,

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

@ -1486,6 +1486,11 @@ public:
nsFontMetrics& aFontMetrics,
nsRenderingContext& aContext);
static bool StringWidthIsGreaterThan(const nsString& aString,
nsFontMetrics& aFontMetrics,
nsRenderingContext& aContext,
nscoord aWidth);
static nsBoundingMetrics AppUnitBoundsOfString(const char16_t* aString,
uint32_t aLength,
nsFontMetrics& aFontMetrics,

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

@ -1319,15 +1319,16 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText,
{
NS_PRECONDITION(aColumn && aColumn->GetFrame(), "invalid column passed");
nscoord width = nsLayoutUtils::AppUnitWidthOfStringBidi(aText, this,
aFontMetrics,
aRenderingContext);
nscoord maxWidth = aTextRect.width;
bool widthIsGreater = nsLayoutUtils::StringWidthIsGreaterThan(aText,
aFontMetrics,
aRenderingContext,
maxWidth);
if (aColumn->Overflow()) {
DebugOnly<nsresult> rv;
nsTreeColumn* nextColumn = aColumn->GetNext();
while (nextColumn && width > maxWidth) {
while (nextColumn && widthIsGreater) {
while (nextColumn) {
nscoord width;
rv = nextColumn->GetWidthInTwips(this, &width);
@ -1351,6 +1352,10 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText,
NS_ASSERTION(NS_SUCCEEDED(rv), "nextColumn is invalid");
maxWidth += width;
widthIsGreater = nsLayoutUtils::StringWidthIsGreaterThan(aText,
aFontMetrics,
aRenderingContext,
maxWidth);
nextColumn = nextColumn->GetNext();
}
@ -1361,7 +1366,8 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText,
}
}
if (width > maxWidth) {
nscoord width;
if (widthIsGreater) {
// See if the width is even smaller than the ellipsis
// If so, clear the text completely.
const nsDependentString& kEllipsis = nsContentUtils::GetLocalizedEllipsis();
@ -1458,11 +1464,11 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText,
break;
}
}
width = nsLayoutUtils::AppUnitWidthOfStringBidi(aText, this, aFontMetrics,
aRenderingContext);
}
width = nsLayoutUtils::AppUnitWidthOfStringBidi(aText, this, aFontMetrics,
aRenderingContext);
switch (aColumn->GetTextAlignment()) {
case NS_STYLE_TEXT_ALIGN_RIGHT: {
aTextRect.x += aTextRect.width - width;