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:
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>