Bug 264412. Optimize GetRenderedText. r=mats

With these changes we're slightly faster than Chrome on the non-reflowing part of
Olli's testcase.

--HG--
extra : commitid : 75liwqsBeJY
extra : rebase_source : 34ee5d1fdfbb3b9d2ef8945f78ded935debb9106
This commit is contained in:
Robert O'Callahan 2015-10-30 19:22:33 +13:00
Родитель 7c373233ed
Коммит 00af2dcc78
2 изменённых файлов: 63 добавлений и 49 удалений

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

@ -3396,36 +3396,38 @@ nsRange::GetInnerTextNoFlush(DOMString& aValue, ErrorResult& aError,
nsIContent* child = currentNode->GetFirstChild();
if (child) {
currentNode = child;
} else {
currentState = AFTER_NODE;
continue;
}
} else {
if (isVisibleAndNotReplaced) {
if (currentNode->IsHTMLElement(nsGkAtoms::br)) {
currentState = AFTER_NODE;
}
if (currentNode == endNode && currentState == endState) {
break;
}
if (isVisibleAndNotReplaced) {
if (currentNode->IsHTMLElement(nsGkAtoms::br)) {
result.Append('\n');
}
switch (f->StyleDisplay()->mDisplay) {
case NS_STYLE_DISPLAY_TABLE_CELL:
if (!IsLastCellOfRow(f)) {
result.Append('\t');
}
break;
case NS_STYLE_DISPLAY_TABLE_ROW:
if (!IsLastRowOfRowGroup(f) ||
!IsLastNonemptyRowGroupOfTable(f->GetParent())) {
result.Append('\n');
}
switch (f->StyleDisplay()->mDisplay) {
case NS_STYLE_DISPLAY_TABLE_CELL:
if (!IsLastCellOfRow(f)) {
result.Append('\t');
}
break;
case NS_STYLE_DISPLAY_TABLE_ROW:
if (!IsLastRowOfRowGroup(f) ||
!IsLastNonemptyRowGroupOfTable(f->GetParent())) {
result.Append('\n');
}
break;
}
result.AddRequiredLineBreakCount(GetRequiredInnerTextLineBreakCount(f));
}
nsIContent* next = currentNode->GetNextSibling();
if (next) {
currentNode = next;
currentState = AT_NODE;
} else {
currentNode = currentNode->GetParent();
break;
}
result.AddRequiredLineBreakCount(GetRequiredInnerTextLineBreakCount(f));
}
nsIContent* next = currentNode->GetNextSibling();
if (next) {
currentNode = next;
currentState = AT_NODE;
} else {
currentNode = currentNode->GetParent();
}
}

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

@ -8948,31 +8948,37 @@ nsTextFrame::RecomputeOverflow(nsIFrame* aBlockFrame)
return result;
}
static char16_t TransformChar(nsTextFrame* aFrame, const nsStyleText* aStyle,
gfxTextRun* aTextRun, uint32_t aSkippedOffset,
char16_t aChar)
static void TransformChars(nsTextFrame* aFrame, const nsStyleText* aStyle,
gfxTextRun* aTextRun, uint32_t aSkippedOffset,
const nsTextFragment* aFrag, int32_t aFragOffset,
int32_t aFragLen, nsAString& aOut)
{
if (aChar == '\n') {
return aStyle->NewlineIsSignificant(aFrame) ? aChar : ' ';
}
if (aChar == '\t') {
return aStyle->TabIsSignificant() ? aChar : ' ';
aOut.SetLength(aOut.Length() + aFragLen);
char16_t* out = aOut.EndWriting() - aFragLen;
for (int32_t i = 0; i < aFragLen; ++i) {
char16_t ch = aFrag->CharAt(aFragOffset + i);
if ((ch == '\n' && !aStyle->NewlineIsSignificant(aFrame)) ||
(ch == '\t' && !aStyle->TabIsSignificant())) {
ch = ' ';
}
out[i] = ch;
}
switch (aStyle->mTextTransform) {
case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
aChar = ToLowerCase(aChar);
ToLowerCase(out, out, aFragLen);
break;
case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
aChar = ToUpperCase(aChar);
ToUpperCase(out, out, aFragLen);
break;
case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
if (aTextRun->CanBreakLineBefore(aSkippedOffset)) {
aChar = ToTitleCase(aChar);
for (int32_t i = 0; i < aFragLen; ++i) {
if (aTextRun->CanBreakLineBefore(aSkippedOffset + i)) {
out[i] = ToTitleCase(out[i]);
}
}
break;
}
return aChar;
}
static bool
@ -9093,18 +9099,24 @@ nsTextFrame::GetRenderedText(uint32_t aStartOffset,
const nsStyleText* textStyle = textFrame->StyleText();
iter.SetOriginalOffset(trimmedOffsets.mStart);
while (iter.GetOriginalOffset() < trimmedOffsets.GetEnd()) {
char16_t ch = textFrag->CharAt(iter.GetOriginalOffset());
if (iter.IsOriginalCharSkipped()) {
if (ch == CH_SHY) {
// We should preserve soft hyphens. They can't be transformed.
result.mString.Append(ch);
int32_t runLength;
bool isSkipped = iter.IsOriginalCharSkipped(&runLength);
runLength = std::min(runLength,
trimmedOffsets.GetEnd() - iter.GetOriginalOffset());
if (isSkipped) {
for (int32_t i = 0; i < runLength; ++i) {
char16_t ch = textFrag->CharAt(iter.GetOriginalOffset() + i);
if (ch == CH_SHY) {
// We should preserve soft hyphens. They can't be transformed.
result.mString.Append(ch);
}
}
} else {
result.mString.Append(
TransformChar(textFrame, textStyle, textFrame->mTextRun,
iter.GetSkippedOffset(), ch));
TransformChars(textFrame, textStyle, textFrame->mTextRun,
iter.GetSkippedOffset(), textFrag,
iter.GetOriginalOffset(), runLength, result.mString);
}
iter.AdvanceOriginal(1);
iter.AdvanceOriginal(runLength);
}
if (trimmedSignificantNewline && GetContentEnd() <= endOffset) {