Bug 1890773 - Create a pref to control how letter-spacing is inserted around characters. r=layout-reviewers,emilio
With the pref set to 0 by default, this does not change any existing behavior. My intention is that a following patch will set it to 2 in Nightly. This will affect a bunch of reftests, and so test/expectation adjustments will also be needed. Differential Revision: https://phabricator.services.mozilla.com/D207150
This commit is contained in:
@@ -3611,6 +3611,20 @@ void nsTextFrame::PropertyProvider::GetSpacing(Range aRange,
|
||||
!(mTextRun->GetFlags2() & nsTextFrameUtils::Flags::HasTab));
|
||||
}
|
||||
|
||||
static bool CanAddSpacingBefore(const gfxTextRun* aTextRun, uint32_t aOffset,
|
||||
bool aNewlineIsSignificant) {
|
||||
const auto* g = aTextRun->GetCharacterGlyphs();
|
||||
MOZ_ASSERT(aOffset < aTextRun->GetLength());
|
||||
if (aNewlineIsSignificant && g[aOffset].CharIsNewline()) {
|
||||
return false;
|
||||
}
|
||||
if (!aOffset) {
|
||||
return true;
|
||||
}
|
||||
return g[aOffset].IsClusterStart() && g[aOffset].IsLigatureGroupStart() &&
|
||||
!g[aOffset - 1].CharIsFormattingControl() && !g[aOffset].CharIsTab();
|
||||
}
|
||||
|
||||
static bool CanAddSpacingAfter(const gfxTextRun* aTextRun, uint32_t aOffset,
|
||||
bool aNewlineIsSignificant) {
|
||||
const auto* g = aTextRun->GetCharacterGlyphs();
|
||||
@@ -3683,14 +3697,45 @@ void nsTextFrame::PropertyProvider::GetSpacingInternal(Range aRange,
|
||||
nsSkipCharsRunIterator run(
|
||||
start, nsSkipCharsRunIterator::LENGTH_UNSKIPPED_ONLY, aRange.Length());
|
||||
bool newlineIsSignificant = mTextStyle->NewlineIsSignificant(mFrame);
|
||||
// Which letter-spacing model are we using?
|
||||
// 0 - Gecko legacy model, spacing added to trailing side of letter
|
||||
// 1 - WebKit/Blink-compatible, spacing added to right-hand side
|
||||
// 2 - Symmetrical spacing, half added to each side
|
||||
gfxFloat before, after;
|
||||
switch (StaticPrefs::layout_css_letter_spacing_model()) {
|
||||
default: // use Gecko legacy behavior if pref value is unknown
|
||||
case 0:
|
||||
before = 0.0;
|
||||
after = mLetterSpacing;
|
||||
break;
|
||||
case 1:
|
||||
if (mTextRun->IsRightToLeft()) {
|
||||
before = mLetterSpacing;
|
||||
after = 0.0;
|
||||
} else {
|
||||
before = 0.0;
|
||||
after = mLetterSpacing;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
before = mLetterSpacing / 2.0;
|
||||
after = mLetterSpacing - before;
|
||||
break;
|
||||
}
|
||||
while (run.NextRun()) {
|
||||
uint32_t runOffsetInSubstring = run.GetSkippedOffset() - aRange.start;
|
||||
gfxSkipCharsIterator iter = run.GetPos();
|
||||
for (int32_t i = 0; i < run.GetRunLength(); ++i) {
|
||||
if (CanAddSpacingAfter(mTextRun, run.GetSkippedOffset() + i,
|
||||
if (before != 0.0 &&
|
||||
CanAddSpacingBefore(mTextRun, run.GetSkippedOffset() + i,
|
||||
newlineIsSignificant)) {
|
||||
aSpacing[runOffsetInSubstring + i].mBefore += before;
|
||||
}
|
||||
if (after != 0.0 &&
|
||||
CanAddSpacingAfter(mTextRun, run.GetSkippedOffset() + i,
|
||||
newlineIsSignificant)) {
|
||||
// End of a cluster, not in a ligature: put letter-spacing after it
|
||||
aSpacing[runOffsetInSubstring + i].mAfter += mLetterSpacing;
|
||||
aSpacing[runOffsetInSubstring + i].mAfter += after;
|
||||
}
|
||||
if (IsCSSWordSpacingSpace(mFrag, i + run.GetOriginalOffset(), mFrame,
|
||||
mTextStyle)) {
|
||||
|
||||
Reference in New Issue
Block a user