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

View File

@ -747,7 +747,12 @@ public:
// which is not combined with any combining characters. This flag is
// set for all those characters except 0x20 whitespace.
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_SHIFT = 8
@ -802,6 +807,10 @@ public:
return !CharIsSpace() &&
(IsSimpleGlyph() || !(mValue & FLAG_CHAR_NO_EMPHASIS_MARK));
}
bool CharIsFormattingControl() const {
return !IsSimpleGlyph() &&
(mValue & FLAG_CHAR_IS_FORMATTING_CONTROL) != 0;
}
uint32_t CharTypeFlags() const {
return IsSimpleGlyph() ? 0 : (mValue & CHAR_TYPE_FLAGS_MASK);
@ -880,6 +889,10 @@ public:
NS_ASSERTION(!IsSimpleGlyph(), "Expected non-simple-glyph");
mValue |= FLAG_CHAR_NO_EMPHASIS_MARK;
}
void SetIsFormattingControl() {
NS_ASSERTION(!IsSimpleGlyph(), "Expected non-simple-glyph");
mValue |= FLAG_CHAR_IS_FORMATTING_CONTROL;
}
private:
uint32_t mValue;

View File

@ -1947,8 +1947,12 @@ gfxFontGroup::IsInvalidChar(char16_t ch)
if (ch <= 0x9f) {
return true;
}
// Word-separating format/bidi control characters are not shaped as part
// of words.
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));
}

View File

@ -133,6 +133,10 @@ public:
NS_ASSERTION(aPos < GetLength(), "aPos out of range");
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
// grapheme cluster boundaries! All offsets are in terms of the string
@ -532,6 +536,9 @@ public:
void SetNoEmphasisMark(uint32_t aIndex) {
EnsureComplexGlyph(aIndex).SetNoEmphasisMark();
}
void SetIsFormattingControl(uint32_t aIndex) {
EnsureComplexGlyph(aIndex).SetIsFormattingControl();
}
/**
* 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
CanAddSpacingAfter(gfxTextRun* aTextRun, uint32_t aOffset)
CanAddSpacingAfter(gfxTextRun* aTextRun, uint32_t aOffset,
bool aNewlineIsSignificant)
{
if (aOffset + 1 >= aTextRun->GetLength())
return true;
return aTextRun->IsClusterStart(aOffset + 1) &&
aTextRun->IsLigatureGroupStart(aOffset + 1);
aTextRun->IsLigatureGroupStart(aOffset + 1) &&
!aTextRun->CharIsFormattingControl(aOffset) &&
!(aNewlineIsSignificant && aTextRun->CharIsNewline(aOffset));
}
void
@ -3247,11 +3250,13 @@ PropertyProvider::GetSpacingInternal(uint32_t aStart, uint32_t aLength,
// Iterate over non-skipped characters
nsSkipCharsRunIterator
run(start, nsSkipCharsRunIterator::LENGTH_UNSKIPPED_ONLY, aLength);
bool newlineIsSignificant = mTextStyle->NewlineIsSignificant(mFrame);
while (run.NextRun()) {
uint32_t runOffsetInSubstring = run.GetSkippedOffset() - aStart;
gfxSkipCharsIterator iter = run.GetPos();
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
aSpacing[runOffsetInSubstring + i].mAfter += mLetterSpacing;
}