commit 9c7e00925b4d983e697e7b033f27b57194d352d3
parent 6893699abb0aa8c1e15a7b4a9ae001cc248ad801
Author: Frédéric Wang <fwang@igalia.com>
Date: Wed, 17 Dec 2025 13:21:37 +0000
Bug 1989246 - Make font-unicode-PUA.html more robust. r=jfkthame
font-unicode-PUA.html renders PUA characters with a font-family list
made of generic families except the last one. It verifies that this
perfectly matches the same text rendered with only this last non-generic
family, based on this requirement from the CSS spec [1]:
"If a given character is a Private-Use Area Unicode codepoint, user
agents must only match font families named in the font-family list that
are not generic families"
However, nothing in the spec actually prevents the "first available
font" to be one of the generic font family, which can affects other
metrics (e.g. line-height). In particular, the test currently uses
'Times' as the last (non-generic) family, which likely does not provide
the requested PUA glyphs and so be rendered with a missing-glyph box
that again uses the metrics from the "first available font".
The test covers the generic font-family "math", and for the reasons
described in the previous paragraph, it regressed after [2].
Instead, we rewrite this as a testharness test to use the Ahem web font,
the three PUA characters it contains (U+F000, U+F001, U+F002) and only
check the glyph's widths, making the whole setup more robust.
[1] https://drafts.csswg.org/css-fonts-4/#char-handling-issues
[2] https://phabricator.services.mozilla.com/D256978
Differential Revision: https://phabricator.services.mozilla.com/D276810
Diffstat:
3 files changed, 24 insertions(+), 35 deletions(-)
diff --git a/testing/web-platform/meta/css/css-fonts/matching/font-unicode-PUA.html.ini b/testing/web-platform/meta/css/css-fonts/matching/font-unicode-PUA.html.ini
@@ -1,4 +0,0 @@
-[font-unicode-PUA.html]
- expected:
- if os == "linux": FAIL
- if os == "android": FAIL
diff --git a/testing/web-platform/tests/css/css-fonts/matching/font-unicode-PUA-ref.html b/testing/web-platform/tests/css/css-fonts/matching/font-unicode-PUA-ref.html
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="author" title="Vitor Roriz" href="https://github.com/vitorroriz">
-<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#char-handling-issues">
-<style>
-.target {
- font-family: serif, sans-serif, cursive, fantasy, monospace, system-ui, emoji, math, fangsong, ui-serif, ui-sans-serif, ui-monospace, ui-rounded, 'Times';
-}
-p {
- font-size: 22px;
-}
-.times {
- font-family: 'Times';
-}
-</style>
-</head>
-<body>
-"If a given character is a Private-Use Area Unicode codepoint, user agents must only match font families named in the font-family list that are not generic families. If none of the families named in the font-family list contain a glyph for that codepoint, user agents must display some form of missing glyph symbol for that character rather than attempting installed font fallback for that codepoint." - <a href="https://drafts.csswg.org/css-fonts-4/#char-handling-issues">css-fonts-4</a>
-<h3>The first line should render as the second. This means that no generic font was used during fallback and the first non generic font was used. </h3>
-<p class="times"></p>
-<p class="times"></p>
-</body>
-</html>
diff --git a/testing/web-platform/tests/css/css-fonts/matching/font-unicode-PUA.html b/testing/web-platform/tests/css/css-fonts/matching/font-unicode-PUA.html
@@ -3,23 +3,40 @@
<head>
<link rel="author" title="Vitor Roriz" href="https://github.com/vitorroriz">
<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#char-handling-issues">
-<link rel="match" href="./font-unicode-PUA-ref.html">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
<style>
-.target {
- font-family: serif, sans-serif, cursive, fantasy, monospace, system-ui, emoji, math, fangsong, ui-serif, ui-sans-serif, ui-monospace, ui-rounded, 'Times';
+#target {
+ font-family: serif, sans-serif, cursive, fantasy, monospace, system-ui, emoji, math, fangsong, ui-serif, ui-sans-serif, ui-monospace, ui-rounded, 'Ahem';
}
p {
font-size: 22px;
}
-.times {
- font-family: 'Times';
+#ahem {
+ font-family: 'Ahem';
+}
+.box {
+ display: inline-block;
}
</style>
</head>
<body>
"If a given character is a Private-Use Area Unicode codepoint, user agents must only match font families named in the font-family list that are not generic families. If none of the families named in the font-family list contain a glyph for that codepoint, user agents must display some form of missing glyph symbol for that character rather than attempting installed font fallback for that codepoint." - <a href="https://drafts.csswg.org/css-fonts-4/#char-handling-issues">css-fonts-4</a>
<h3>The first line should render as the second. This means that no generic font was used during fallback and the first non generic font was used. </h3>
-<p class="target"></p>
-<p class="times"></p>
+<p id="target"><span class="box"></span><span class="box"></span><span class="box"></span></p>
+<p id="ahem"><span class="box"></span><span class="box"></span><span class="box"></span></p>
+<script>
+ promise_setup(_ => Promise.all([...document.fonts].map(f => f.load())));
+ const target = document.getElementById("target");
+ const ahem = document.getElementById("ahem");
+ for (let i = 0; i < target.children.length; i++) {
+ promise_test(async t => {
+ let targetBox = target.children[i].getBoundingClientRect();
+ let ahemBox = ahem.children[i].getBoundingClientRect();
+ assert_equals(targetBox.width, ahemBox.width);
+ }, `PUA character U+F00${i} is rendered with a non-generic font.`);
+ }
+</script>
</body>
</html>