Bug 1820988 - Handle separator characters in canvas2d TextReplaceWhitespaceCharacters, to avoid a second preprocessing of the string in ProcessText. r=gfx-reviewers,aosmond

This avoids an extra string copy/scan in ProcessText, by including the block/segment
separators it cares about in the preprocessing that's already being done to normalize
whitespace characters by the caller.

Depends on D171986

Differential Revision: https://phabricator.services.mozilla.com/D171987
This commit is contained in:
Jonathan Kew 2023-03-08 18:28:08 +00:00
Родитель 533e50d65c
Коммит e746d47f7e
2 изменённых файлов: 15 добавлений и 12 удалений

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

@ -3845,10 +3845,13 @@ void CanvasRenderingContext2D::GetFontKerning(nsAString& aFontKerning) {
* with U+0020 SPACE. The whitespace characters are defined as U+0020 SPACE,
* U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000B LINE
* TABULATION, U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR).
* We also replace characters with Bidi type Segment Separator or Block
* Separator.
* @param str The string whose whitespace characters to replace.
*/
static inline void TextReplaceWhitespaceCharacters(nsAutoString& aStr) {
aStr.ReplaceChar(u"\x09\x0A\x0B\x0C\x0D", char16_t(' '));
aStr.ReplaceChar(u"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F\x85\x2029",
char16_t(' '));
}
void CanvasRenderingContext2D::FillText(const nsAString& aText, double aX,

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

@ -2144,11 +2144,12 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, size_t aLength,
NS_ASSERTION((aPosResolve == nullptr) != (aPosResolveCount > 0),
"Incorrect aPosResolve / aPosResolveCount arguments");
nsAutoString textBuffer(aText, aLength);
textBuffer.ReplaceChar(kSeparators, kSpace);
const char16_t* text = textBuffer.get();
// Caller should have already replaced any separators in the original text
// with <space> characters.
MOZ_ASSERT(nsDependentString(aText, aLength).FindCharInSet(kSeparators) ==
kNotFound);
if (aBidiEngine->SetParagraph(Span(text, aLength), aBaseLevel).isErr()) {
if (aBidiEngine->SetParagraph(Span(aText, aLength), aBaseLevel).isErr()) {
return NS_ERROR_FAILURE;
}
@ -2209,7 +2210,7 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, size_t aLength,
*/
if (dir == intl::BidiDirection::RTL) {
aprocessor.SetText(text + start, subRunLength, intl::BidiDirection::RTL);
aprocessor.SetText(aText + start, subRunLength, intl::BidiDirection::RTL);
width = aprocessor.GetWidth();
xOffset += width;
xEndRun = xOffset;
@ -2218,11 +2219,10 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, size_t aLength,
while (subRunCount > 0) {
// CalculateBidiClass can increment subRunCount if the run
// contains mixed character types
CalculateBidiClass(text, lineOffset, typeLimit, subRunLimit, subRunLength,
subRunCount, bidiClass, prevClass);
CalculateBidiClass(aText, lineOffset, typeLimit, subRunLimit,
subRunLength, subRunCount, bidiClass, prevClass);
nsAutoString runVisualText;
runVisualText.Assign(text + start, subRunLength);
nsAutoString runVisualText(aText + start, subRunLength);
if (aPresContext) {
FormatUnicodeText(aPresContext, runVisualText.BeginWriting(),
subRunLength, bidiClass);
@ -2308,14 +2308,14 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText, size_t aLength,
visualStart +
(subRunLength - (posResolve->logicalIndex + 1 - start));
// Skipping to the "left part".
visualLeftPart = text + posResolve->logicalIndex + 1;
visualLeftPart = aText + posResolve->logicalIndex + 1;
// Skipping to the right side of the current character
visualRightSide = visualLeftPart - 1;
} else {
posResolve->visualIndex =
visualStart + (posResolve->logicalIndex - start);
// Skipping to the "left part".
visualLeftPart = text + start;
visualLeftPart = aText + start;
// In LTR mode this is the same as visualLeftPart
visualRightSide = visualLeftPart;
}