tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 0b4170f632f39cb75c59a3726516f862cf0b0545
parent 4b6c27038bd397384248491fa31f3fbcb6828ed9
Author: Jonathan Kew <jkew@mozilla.com>
Date:   Wed, 31 Dec 2025 18:48:53 +0000

Bug 1342835 - Don't apply letter-spacing within cursive scripts. r=layout-reviewers,emilio

This suppresses letter-spacing for characters from cursive scripts, as required
by the spec.

Differential Revision: https://phabricator.services.mozilla.com/D277297

Diffstat:
Mlayout/generic/nsTextFrame.cpp | 22++++++++++++++++------
Dtesting/web-platform/meta/css/css-text/letter-spacing/letter-spacing-cursive-001.html.ini | 2--
Atesting/web-platform/tests/css/css-text/letter-spacing/letter-spacing-cursive-002.html | 47+++++++++++++++++++++++++++++++++++++++++++++++
Atesting/web-platform/tests/css/css-text/letter-spacing/reference/letter-spacing-cursive-002-ref.html | 36++++++++++++++++++++++++++++++++++++
4 files changed, 99 insertions(+), 8 deletions(-)

diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp @@ -4169,16 +4169,28 @@ bool nsTextFrame::PropertyProvider::GetSpacingInternal(Range aRange, uint32_t runOffsetInSubstring = run.GetSkippedOffset() - aRange.start; gfxSkipCharsIterator iter = run.GetPos(); for (int32_t i = 0; i < run.GetRunLength(); ++i) { + auto currScalar = [&]() -> char32_t { + iter.SetSkippedOffset(run.GetSkippedOffset() + i); + return mCharacterDataBuffer.ScalarValueAt(iter.GetOriginalOffset()); + }; if (!atStart && before != 0 && CanAddSpacingBefore(mTextRun, run.GetSkippedOffset() + i, - newlineIsSignificant)) { + newlineIsSignificant) && + !intl::UnicodeProperties::IsCursiveScript(currScalar())) { aSpacing[runOffsetInSubstring + i].mBefore += before; } if (after != 0 && CanAddSpacingAfter(mTextRun, run.GetSkippedOffset() + i, newlineIsSignificant)) { - // End of a cluster, not in a ligature: put letter-spacing after it - aSpacing[runOffsetInSubstring + i].mAfter += after; + // End of a cluster, not in a ligature: put letter-spacing after it, + // unless the base char of the cluster belonged to a cursive script. + iter.SetSkippedOffset(run.GetSkippedOffset() + i); + FindClusterStart(mTextRun, run.GetOriginalOffset(), &iter); + char32_t baseChar = + mCharacterDataBuffer.ScalarValueAt(iter.GetOriginalOffset()); + if (!intl::UnicodeProperties::IsCursiveScript(baseChar)) { + aSpacing[runOffsetInSubstring + i].mAfter += after; + } } if (mWordSpacing && IsCSSWordSpacingSpace(mCharacterDataBuffer, i + run.GetOriginalOffset(), @@ -4200,9 +4212,7 @@ bool nsTextFrame::PropertyProvider::GetSpacingInternal(Range aRange, (textIncludesCJK || run.GetOriginalOffset() + i == mFrame->GetContentOffset()) && mTextRun->IsClusterStart(run.GetSkippedOffset() + i)) { - const char32_t currScalar = - mCharacterDataBuffer.ScalarValueAt(run.GetOriginalOffset() + i); - const auto currClass = TextAutospace::GetCharClass(currScalar); + const auto currClass = TextAutospace::GetCharClass(currScalar()); // It is rare for the current class to be a combining mark, as // combining marks are not cluster starts. We still check in case a diff --git a/testing/web-platform/meta/css/css-text/letter-spacing/letter-spacing-cursive-001.html.ini b/testing/web-platform/meta/css/css-text/letter-spacing/letter-spacing-cursive-001.html.ini @@ -1,2 +0,0 @@ -[letter-spacing-cursive-001.html] - expected: FAIL diff --git a/testing/web-platform/tests/css/css-text/letter-spacing/letter-spacing-cursive-002.html b/testing/web-platform/tests/css/css-text/letter-spacing/letter-spacing-cursive-002.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<head> +<meta charset="utf-8"> +<title> +CSS Text Test - Letter-spacing should not be applied for Cursive Scripts. +</title> + +<link rel="help" href="https://drafts.csswg.org/css-text-4/#cursive-tracking"> +<link rel="help" href="https://drafts.csswg.org/css-text-4/#example-9902d8b5"> +<link rel="match" href="reference/letter-spacing-cursive-002-ref.html"> +<meta name="assert" content="Suppress letter-spacing between Arabic letters. +Letter-spacing is nonetheless applied to non-Arabic characters (like spaces)."> + +<style> +div { + margin: 1em; + font: 24px serif; +} + +.letterspace { + letter-spacing: 1em; /* Does not affect Arabic text, but does affect the space */ +} + +.ws { + white-space: pre; +} +.ws::after { /* Fake letter-spacing for the space only */ + content: ' '; + display: inline-block; + width: 1em; +} +</style> +</head> +<body> +<p> +Both Arabic texts should display identically. +</p> +<div class=letterspace> +الإبداع المتجدد +</div> +<br> +<div> +الإبداع<span class=ws> </span>المتجدد +</div> +<br> +</body> +</html> diff --git a/testing/web-platform/tests/css/css-text/letter-spacing/reference/letter-spacing-cursive-002-ref.html b/testing/web-platform/tests/css/css-text/letter-spacing/reference/letter-spacing-cursive-002-ref.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<head> +<meta charset="utf-8"> +<title> +CSS Text reference - Letter-spacing should not be applied for Cursive Scripts. +</title> +<style> +div { + margin: 1em; + font: 24px serif; +} + +.ws { + white-space: pre; +} +.ws::after { /* Fake letter-spacing for the space only */ + content: ' '; + display: inline-block; + width: 1em; +} +</style> +</head> +<body> +<p> +Both Arabic texts should display identically. +</p> +<div> +الإبداع<span class=ws> </span>المتجدد +</div> +<br> +<div> +الإبداع<span class=ws> </span>المتجدد +</div> +<br> +</body> +</html>