#612: M253143 M1643126

This commit is contained in:
Cameron Kaiser 2020-10-01 22:27:54 -07:00
parent 191db31e60
commit 9d3a836029
5 changed files with 38 additions and 5 deletions

View File

@ -2717,6 +2717,8 @@ gfxFont::ShapeTextWithoutWordCache(gfxContext *aContext,
aTextRun->SetIsTab(aOffset + i); aTextRun->SetIsTab(aOffset + i);
} else if (ch == '\n') { } else if (ch == '\n') {
aTextRun->SetIsNewline(aOffset + i); aTextRun->SetIsNewline(aOffset + i);
} else if (GetGeneralCategory(ch) == HB_UNICODE_GENERAL_CATEGORY_FORMAT) {
aTextRun->SetIsFormattingControl(aOffset + i);
} else if (IsInvalidControlChar(ch) && } else if (IsInvalidControlChar(ch) &&
!(aTextRun->GetFlags() & gfxTextRunFactory::TEXT_HIDE_CONTROL_CHARACTERS)) { !(aTextRun->GetFlags() & gfxTextRunFactory::TEXT_HIDE_CONTROL_CHARACTERS)) {
if (GetFontEntry()->IsUserFont() && HasCharacter(ch)) { if (GetFontEntry()->IsUserFont() && HasCharacter(ch)) {
@ -2931,6 +2933,8 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext,
aTextRun->SetIsTab(aRunStart + i); aTextRun->SetIsTab(aRunStart + i);
} else if (ch == '\n') { } else if (ch == '\n') {
aTextRun->SetIsNewline(aRunStart + i); aTextRun->SetIsNewline(aRunStart + i);
} else if (GetGeneralCategory(ch) == HB_UNICODE_GENERAL_CATEGORY_FORMAT) {
aTextRun->SetIsFormattingControl(aRunStart + i);
} else if (IsInvalidControlChar(ch) && } else if (IsInvalidControlChar(ch) &&
!(aTextRun->GetFlags() & gfxTextRunFactory::TEXT_HIDE_CONTROL_CHARACTERS)) { !(aTextRun->GetFlags() & gfxTextRunFactory::TEXT_HIDE_CONTROL_CHARACTERS)) {
if (GetFontEntry()->IsUserFont() && HasCharacter(ch)) { if (GetFontEntry()->IsUserFont() && HasCharacter(ch)) {

View File

@ -747,7 +747,12 @@ public:
// which is not combined with any combining characters. This flag is // which is not combined with any combining characters. This flag is
// set for all those characters except 0x20 whitespace. // set for all those characters except 0x20 whitespace.
FLAG_CHAR_NO_EMPHASIS_MARK = 0x20, FLAG_CHAR_NO_EMPHASIS_MARK = 0x20,
CHAR_TYPE_FLAGS_MASK = 0x38, // Per CSS Text, letter-spacing is not applied to formatting chars
// (category Cf). We mark those in the textrun so as to be able to
// skip them when setting up spacing in nsTextFrame.
FLAG_CHAR_IS_FORMATTING_CONTROL = 0x40,
CHAR_TYPE_FLAGS_MASK = 0x78,
GLYPH_COUNT_MASK = 0x00FFFF00U, GLYPH_COUNT_MASK = 0x00FFFF00U,
GLYPH_COUNT_SHIFT = 8 GLYPH_COUNT_SHIFT = 8
@ -802,6 +807,10 @@ public:
return !CharIsSpace() && return !CharIsSpace() &&
(IsSimpleGlyph() || !(mValue & FLAG_CHAR_NO_EMPHASIS_MARK)); (IsSimpleGlyph() || !(mValue & FLAG_CHAR_NO_EMPHASIS_MARK));
} }
bool CharIsFormattingControl() const {
return !IsSimpleGlyph() &&
(mValue & FLAG_CHAR_IS_FORMATTING_CONTROL) != 0;
}
uint32_t CharTypeFlags() const { uint32_t CharTypeFlags() const {
return IsSimpleGlyph() ? 0 : (mValue & CHAR_TYPE_FLAGS_MASK); return IsSimpleGlyph() ? 0 : (mValue & CHAR_TYPE_FLAGS_MASK);
@ -880,6 +889,10 @@ public:
NS_ASSERTION(!IsSimpleGlyph(), "Expected non-simple-glyph"); NS_ASSERTION(!IsSimpleGlyph(), "Expected non-simple-glyph");
mValue |= FLAG_CHAR_NO_EMPHASIS_MARK; mValue |= FLAG_CHAR_NO_EMPHASIS_MARK;
} }
void SetIsFormattingControl() {
NS_ASSERTION(!IsSimpleGlyph(), "Expected non-simple-glyph");
mValue |= FLAG_CHAR_IS_FORMATTING_CONTROL;
}
private: private:
uint32_t mValue; uint32_t mValue;

View File

@ -1947,8 +1947,12 @@ gfxFontGroup::IsInvalidChar(char16_t ch)
if (ch <= 0x9f) { if (ch <= 0x9f) {
return true; return true;
} }
// Word-separating format/bidi control characters are not shaped as part
// of words.
return (((ch & 0xFF00) == 0x2000 /* Unicode control character */ && return (((ch & 0xFF00) == 0x2000 /* Unicode control character */ &&
(ch == 0x200B/*ZWSP*/ || ch == 0x2028/*LSEP*/ || ch == 0x2029/*PSEP*/)) || (ch == 0x200B/*ZWSP*/ || ch == 0x2028/*LSEP*/ ||
ch == 0x2029/*PSEP*/ || ch == 0x2060/*WJ*/)) ||
ch == 0xfeff/*ZWNBSP*/ ||
IsBidiControl(ch)); IsBidiControl(ch));
} }

View File

@ -133,6 +133,10 @@ public:
NS_ASSERTION(aPos < GetLength(), "aPos out of range"); NS_ASSERTION(aPos < GetLength(), "aPos out of range");
return mCharacterGlyphs[aPos].CharMayHaveEmphasisMark(); return mCharacterGlyphs[aPos].CharMayHaveEmphasisMark();
} }
bool CharIsFormattingControl(uint32_t aPos) const {
MOZ_ASSERT(aPos < GetLength());
return mCharacterGlyphs[aPos].CharIsFormattingControl();
}
// All uint32_t aStart, uint32_t aLength ranges below are restricted to // All uint32_t aStart, uint32_t aLength ranges below are restricted to
// grapheme cluster boundaries! All offsets are in terms of the string // grapheme cluster boundaries! All offsets are in terms of the string
@ -532,6 +536,9 @@ public:
void SetNoEmphasisMark(uint32_t aIndex) { void SetNoEmphasisMark(uint32_t aIndex) {
EnsureComplexGlyph(aIndex).SetNoEmphasisMark(); EnsureComplexGlyph(aIndex).SetNoEmphasisMark();
} }
void SetIsFormattingControl(uint32_t aIndex) {
EnsureComplexGlyph(aIndex).SetIsFormattingControl();
}
/** /**
* Prefetch all the glyph extents needed to ensure that Measure calls * Prefetch all the glyph extents needed to ensure that Measure calls

View File

@ -3218,12 +3218,15 @@ PropertyProvider::GetSpacing(uint32_t aStart, uint32_t aLength,
} }
static bool static bool
CanAddSpacingAfter(gfxTextRun* aTextRun, uint32_t aOffset) CanAddSpacingAfter(gfxTextRun* aTextRun, uint32_t aOffset,
bool aNewlineIsSignificant)
{ {
if (aOffset + 1 >= aTextRun->GetLength()) if (aOffset + 1 >= aTextRun->GetLength())
return true; return true;
return aTextRun->IsClusterStart(aOffset + 1) && return aTextRun->IsClusterStart(aOffset + 1) &&
aTextRun->IsLigatureGroupStart(aOffset + 1); aTextRun->IsLigatureGroupStart(aOffset + 1) &&
!aTextRun->CharIsFormattingControl(aOffset) &&
!(aNewlineIsSignificant && aTextRun->CharIsNewline(aOffset));
} }
void void
@ -3247,11 +3250,13 @@ PropertyProvider::GetSpacingInternal(uint32_t aStart, uint32_t aLength,
// Iterate over non-skipped characters // Iterate over non-skipped characters
nsSkipCharsRunIterator nsSkipCharsRunIterator
run(start, nsSkipCharsRunIterator::LENGTH_UNSKIPPED_ONLY, aLength); run(start, nsSkipCharsRunIterator::LENGTH_UNSKIPPED_ONLY, aLength);
bool newlineIsSignificant = mTextStyle->NewlineIsSignificant(mFrame);
while (run.NextRun()) { while (run.NextRun()) {
uint32_t runOffsetInSubstring = run.GetSkippedOffset() - aStart; uint32_t runOffsetInSubstring = run.GetSkippedOffset() - aStart;
gfxSkipCharsIterator iter = run.GetPos(); gfxSkipCharsIterator iter = run.GetPos();
for (int32_t i = 0; i < run.GetRunLength(); ++i) { for (int32_t i = 0; i < run.GetRunLength(); ++i) {
if (CanAddSpacingAfter(mTextRun, run.GetSkippedOffset() + i)) { if (CanAddSpacingAfter(mTextRun, run.GetSkippedOffset() + i,
newlineIsSignificant)) {
// End of a cluster, not in a ligature: put letter-spacing after it // End of a cluster, not in a ligature: put letter-spacing after it
aSpacing[runOffsetInSubstring + i].mAfter += mLetterSpacing; aSpacing[runOffsetInSubstring + i].mAfter += mLetterSpacing;
} }