зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1316482 - use the refactored TransformText as a template function for both char16_t and uint8_t text. r=xidorn
With this patch, we shall only maintain one version of the TransformText logic. MozReview-Commit-ID: JAIksFVqvqf --HG-- extra : rebase_source : 49ec749ae74f872e9749e026affe7f2e22db71f9
This commit is contained in:
Родитель
7b8e25751d
Коммит
f53d660a40
|
@ -56,12 +56,13 @@ IsSpaceOrTabOrSegmentBreak(char16_t aCh)
|
||||||
return IsSpaceOrTab(aCh) || IsSegmentBreak(aCh);
|
return IsSpaceOrTab(aCh) || IsSegmentBreak(aCh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char16_t*
|
template<class CharT>
|
||||||
TransformWhiteSpaces(const char16_t* aText, uint32_t aLength,
|
static CharT*
|
||||||
|
TransformWhiteSpaces(const CharT* aText, uint32_t aLength,
|
||||||
uint32_t aBegin, uint32_t aEnd,
|
uint32_t aBegin, uint32_t aEnd,
|
||||||
bool aHasSegmentBreak,
|
bool aHasSegmentBreak,
|
||||||
bool& aInWhitespace,
|
bool& aInWhitespace,
|
||||||
char16_t* aOutput,
|
CharT* aOutput,
|
||||||
uint32_t& aFlags,
|
uint32_t& aFlags,
|
||||||
nsTextFrameUtils::CompressionMode aCompression,
|
nsTextFrameUtils::CompressionMode aCompression,
|
||||||
gfxSkipChars* aSkipChars)
|
gfxSkipChars* aSkipChars)
|
||||||
|
@ -70,10 +71,14 @@ TransformWhiteSpaces(const char16_t* aText, uint32_t aLength,
|
||||||
aCompression == nsTextFrameUtils::COMPRESS_WHITESPACE_NEWLINE,
|
aCompression == nsTextFrameUtils::COMPRESS_WHITESPACE_NEWLINE,
|
||||||
"whitespaces should be skippable!!");
|
"whitespaces should be skippable!!");
|
||||||
// Get the context preceding/following this white space range.
|
// Get the context preceding/following this white space range.
|
||||||
|
// For 8-bit text (sizeof CharT == 1), the checks here should get optimized
|
||||||
|
// out, and isSegmentBreakSkippable should be initialized to be 'false'.
|
||||||
bool isSegmentBreakSkippable =
|
bool isSegmentBreakSkippable =
|
||||||
(aBegin > 0 && IS_ZERO_WIDTH_SPACE(aText[aBegin - 1])) ||
|
sizeof(CharT) > 1 &&
|
||||||
(aEnd < aLength && IS_ZERO_WIDTH_SPACE(aText[aEnd]));
|
((aBegin > 0 && IS_ZERO_WIDTH_SPACE(aText[aBegin - 1])) ||
|
||||||
if (!isSegmentBreakSkippable && aBegin > 0 && aEnd < aLength) {
|
(aEnd < aLength && IS_ZERO_WIDTH_SPACE(aText[aEnd])));
|
||||||
|
if (sizeof(CharT) > 1 && !isSegmentBreakSkippable &&
|
||||||
|
aBegin > 0 && aEnd < aLength) {
|
||||||
uint32_t ucs4before;
|
uint32_t ucs4before;
|
||||||
uint32_t ucs4after;
|
uint32_t ucs4after;
|
||||||
if (aBegin > 1 &&
|
if (aBegin > 1 &&
|
||||||
|
@ -97,7 +102,7 @@ TransformWhiteSpaces(const char16_t* aText, uint32_t aLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = aBegin; i < aEnd; ++i) {
|
for (uint32_t i = aBegin; i < aEnd; ++i) {
|
||||||
char16_t ch = aText[i];
|
CharT ch = aText[i];
|
||||||
bool keepChar = false;
|
bool keepChar = false;
|
||||||
bool keepTransformedWhiteSpace = false;
|
bool keepTransformedWhiteSpace = false;
|
||||||
if (IsDiscardable(ch, &aFlags)) {
|
if (IsDiscardable(ch, &aFlags)) {
|
||||||
|
@ -167,16 +172,17 @@ TransformWhiteSpaces(const char16_t* aText, uint32_t aLength,
|
||||||
return aOutput;
|
return aOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
char16_t*
|
template<class CharT>
|
||||||
nsTextFrameUtils::TransformText(const char16_t* aText, uint32_t aLength,
|
CharT*
|
||||||
char16_t* aOutput,
|
nsTextFrameUtils::TransformText(const CharT* aText, uint32_t aLength,
|
||||||
|
CharT* aOutput,
|
||||||
CompressionMode aCompression,
|
CompressionMode aCompression,
|
||||||
uint8_t* aIncomingFlags,
|
uint8_t* aIncomingFlags,
|
||||||
gfxSkipChars* aSkipChars,
|
gfxSkipChars* aSkipChars,
|
||||||
uint32_t* aAnalysisFlags)
|
uint32_t* aAnalysisFlags)
|
||||||
{
|
{
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
char16_t* outputStart = aOutput;
|
CharT* outputStart = aOutput;
|
||||||
|
|
||||||
bool lastCharArabic = false;
|
bool lastCharArabic = false;
|
||||||
if (aCompression == COMPRESS_NONE ||
|
if (aCompression == COMPRESS_NONE ||
|
||||||
|
@ -184,7 +190,7 @@ nsTextFrameUtils::TransformText(const char16_t* aText, uint32_t aLength,
|
||||||
// Skip discardables.
|
// Skip discardables.
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for (i = 0; i < aLength; ++i) {
|
for (i = 0; i < aLength; ++i) {
|
||||||
char16_t ch = aText[i];
|
CharT ch = aText[i];
|
||||||
if (IsDiscardable(ch, &flags)) {
|
if (IsDiscardable(ch, &flags)) {
|
||||||
aSkipChars->SkipChar();
|
aSkipChars->SkipChar();
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,7 +221,7 @@ nsTextFrameUtils::TransformText(const char16_t* aText, uint32_t aLength,
|
||||||
bool inWhitespace = (*aIncomingFlags & INCOMING_WHITESPACE) != 0;
|
bool inWhitespace = (*aIncomingFlags & INCOMING_WHITESPACE) != 0;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for (i = 0; i < aLength; ++i) {
|
for (i = 0; i < aLength; ++i) {
|
||||||
char16_t ch = aText[i];
|
CharT ch = aText[i];
|
||||||
// CSS Text 3 - 4.1. The White Space Processing Rules
|
// CSS Text 3 - 4.1. The White Space Processing Rules
|
||||||
// White space processing in CSS affects only the document white space
|
// White space processing in CSS affects only the document white space
|
||||||
// characters: spaces (U+0020), tabs (U+0009), and segment breaks.
|
// characters: spaces (U+0020), tabs (U+0009), and segment breaks.
|
||||||
|
@ -244,7 +250,7 @@ nsTextFrameUtils::TransformText(const char16_t* aText, uint32_t aLength,
|
||||||
}
|
}
|
||||||
// If the last white space is followed by a combining sequence tail,
|
// If the last white space is followed by a combining sequence tail,
|
||||||
// exclude it from the range of TransformWhiteSpaces.
|
// exclude it from the range of TransformWhiteSpaces.
|
||||||
if (aText[j - 1] == ' ' && j < aLength &&
|
if (sizeof(CharT) > 1 && aText[j - 1] == ' ' && j < aLength &&
|
||||||
IsSpaceCombiningSequenceTail(&aText[j], aLength - j)) {
|
IsSpaceCombiningSequenceTail(&aText[j], aLength - j)) {
|
||||||
keepLastSpace = true;
|
keepLastSpace = true;
|
||||||
j--;
|
j--;
|
||||||
|
@ -299,85 +305,28 @@ nsTextFrameUtils::TransformText(const char16_t* aText, uint32_t aLength,
|
||||||
*aAnalysisFlags = flags;
|
*aAnalysisFlags = flags;
|
||||||
return aOutput;
|
return aOutput;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
uint8_t*
|
* NOTE: This template is part of public API of nsTextFrameUtils, while
|
||||||
|
* its function body is not available in the header. It may stop working
|
||||||
|
* (fail to resolve symbol in link time) once its callsites are moved to a
|
||||||
|
* different translation unit (e.g. a different unified source file).
|
||||||
|
* Explicit instantiating this function template with `uint8_t` and `char16_t`
|
||||||
|
* could prevent us from the potential risk.
|
||||||
|
*/
|
||||||
|
template uint8_t*
|
||||||
nsTextFrameUtils::TransformText(const uint8_t* aText, uint32_t aLength,
|
nsTextFrameUtils::TransformText(const uint8_t* aText, uint32_t aLength,
|
||||||
uint8_t* aOutput,
|
uint8_t* aOutput,
|
||||||
CompressionMode aCompression,
|
CompressionMode aCompression,
|
||||||
uint8_t* aIncomingFlags,
|
uint8_t* aIncomingFlags,
|
||||||
gfxSkipChars* aSkipChars,
|
gfxSkipChars* aSkipChars,
|
||||||
uint32_t* aAnalysisFlags)
|
uint32_t* aAnalysisFlags);
|
||||||
{
|
template char16_t*
|
||||||
uint32_t flags = 0;
|
nsTextFrameUtils::TransformText(const char16_t* aText, uint32_t aLength,
|
||||||
uint8_t* outputStart = aOutput;
|
char16_t* aOutput,
|
||||||
|
CompressionMode aCompression,
|
||||||
if (aCompression == COMPRESS_NONE ||
|
uint8_t* aIncomingFlags,
|
||||||
aCompression == COMPRESS_NONE_TRANSFORM_TO_SPACE) {
|
gfxSkipChars* aSkipChars,
|
||||||
// Skip discardables.
|
uint32_t* aAnalysisFlags);
|
||||||
uint32_t i;
|
|
||||||
for (i = 0; i < aLength; ++i) {
|
|
||||||
uint8_t ch = aText[i];
|
|
||||||
if (IsDiscardable(ch, &flags)) {
|
|
||||||
aSkipChars->SkipChar();
|
|
||||||
} else {
|
|
||||||
aSkipChars->KeepChar();
|
|
||||||
if (aCompression == COMPRESS_NONE_TRANSFORM_TO_SPACE) {
|
|
||||||
if (ch == '\t' || ch == '\n') {
|
|
||||||
ch = ' ';
|
|
||||||
flags |= TEXT_WAS_TRANSFORMED;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// aCompression == COMPRESS_NONE
|
|
||||||
if (ch == '\t') {
|
|
||||||
flags |= TEXT_HAS_TAB;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*aOutput++ = ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*aIncomingFlags &= ~(INCOMING_ARABICCHAR | INCOMING_WHITESPACE);
|
|
||||||
} else {
|
|
||||||
bool inWhitespace = (*aIncomingFlags & INCOMING_WHITESPACE) != 0;
|
|
||||||
uint32_t i;
|
|
||||||
for (i = 0; i < aLength; ++i) {
|
|
||||||
uint8_t ch = aText[i];
|
|
||||||
bool nowInWhitespace = ch == ' ' || ch == '\t' ||
|
|
||||||
(ch == '\n' && aCompression == COMPRESS_WHITESPACE_NEWLINE);
|
|
||||||
if (!nowInWhitespace) {
|
|
||||||
if (IsDiscardable(ch, &flags)) {
|
|
||||||
aSkipChars->SkipChar();
|
|
||||||
nowInWhitespace = inWhitespace;
|
|
||||||
} else {
|
|
||||||
*aOutput++ = ch;
|
|
||||||
aSkipChars->KeepChar();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (inWhitespace) {
|
|
||||||
aSkipChars->SkipChar();
|
|
||||||
} else {
|
|
||||||
if (ch != ' ') {
|
|
||||||
flags |= TEXT_WAS_TRANSFORMED;
|
|
||||||
}
|
|
||||||
*aOutput++ = ' ';
|
|
||||||
aSkipChars->KeepChar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inWhitespace = nowInWhitespace;
|
|
||||||
}
|
|
||||||
*aIncomingFlags &= ~INCOMING_ARABICCHAR;
|
|
||||||
if (inWhitespace) {
|
|
||||||
*aIncomingFlags |= INCOMING_WHITESPACE;
|
|
||||||
} else {
|
|
||||||
*aIncomingFlags &= ~INCOMING_WHITESPACE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outputStart + aLength != aOutput) {
|
|
||||||
flags |= TEXT_WAS_TRANSFORMED;
|
|
||||||
}
|
|
||||||
*aAnalysisFlags = flags;
|
|
||||||
return aOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
nsTextFrameUtils::ComputeApproximateLengthWithWhitespaceCompression(
|
nsTextFrameUtils::ComputeApproximateLengthWithWhitespaceCompression(
|
||||||
|
|
|
@ -87,6 +87,10 @@ public:
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
static bool
|
||||||
|
IsSpaceCombiningSequenceTail(const uint8_t* aChars, int32_t aLength) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
enum CompressionMode {
|
enum CompressionMode {
|
||||||
COMPRESS_NONE,
|
COMPRESS_NONE,
|
||||||
|
@ -109,19 +113,13 @@ public:
|
||||||
* or an Arabic character preceding this text. We set it to indicate if
|
* or an Arabic character preceding this text. We set it to indicate if
|
||||||
* there's an Arabic character or whitespace preceding the end of this text.
|
* there's an Arabic character or whitespace preceding the end of this text.
|
||||||
*/
|
*/
|
||||||
static char16_t* TransformText(const char16_t* aText, uint32_t aLength,
|
template<class CharT>
|
||||||
char16_t* aOutput,
|
static CharT* TransformText(const CharT* aText, uint32_t aLength,
|
||||||
CompressionMode aCompression,
|
CharT* aOutput,
|
||||||
uint8_t* aIncomingFlags,
|
CompressionMode aCompression,
|
||||||
gfxSkipChars* aSkipChars,
|
uint8_t* aIncomingFlags,
|
||||||
uint32_t* aAnalysisFlags);
|
gfxSkipChars* aSkipChars,
|
||||||
|
uint32_t* aAnalysisFlags);
|
||||||
static uint8_t* TransformText(const uint8_t* aText, uint32_t aLength,
|
|
||||||
uint8_t* aOutput,
|
|
||||||
CompressionMode aCompression,
|
|
||||||
uint8_t* aIncomingFlags,
|
|
||||||
gfxSkipChars* aSkipChars,
|
|
||||||
uint32_t* aAnalysisFlags);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
AppendLineBreakOffset(nsTArray<uint32_t>* aArray, uint32_t aOffset)
|
AppendLineBreakOffset(nsTArray<uint32_t>* aArray, uint32_t aOffset)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче