mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
LibWeb: Verify whitespace font has the glyph in font_for_space()
When inline layout emits a whitespace chunk, it previously selected the surrounding text's font without checking whether that font actually contains a glyph for the whitespace codepoint. On pages that use `@font-face` rules sharded by `unicode-range` (e.g. a Roboto webfont split across one file for Cyrillic letters and another for basic Latin), the shard covering the letters is picked for an adjacent space even though the space codepoint lives in a different shard. HarfBuzz then shapes the space with a font that has no glyph for it and emits `.notdef`, rendering spaces as tofu boxes. Check `contains_glyph(space_code_point)` on each candidate in `font_for_space()` and fall through to `FontCascadeList::font_for_code_point()` for the whitespace codepoint when no surrounding font has the glyph. Fixes whitespace rendering on web.telegram.org/a.
This commit is contained in:
committed by
Andreas Kling
parent
1f46651af5
commit
0bfe4677ae
Notes:
github-actions[bot]
2026-04-22 18:28:54 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/0bfe4677ae2 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/9040 Reviewed-by: https://github.com/gmta ✅
BIN
Tests/LibWeb/Assets/HashSansNoSpace.woff
Normal file
BIN
Tests/LibWeb/Assets/HashSansNoSpace.woff
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
||||
space matches fallback: true
|
||||
37
Tests/LibWeb/Text/input/font-cascade-space-fallback.html
Normal file
37
Tests/LibWeb/Text/input/font-cascade-space-fallback.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "HashFontNoSpace";
|
||||
src: url("../../Assets/HashSansNoSpace.woff");
|
||||
unicode-range: U+0041-005A;
|
||||
}
|
||||
.subset {
|
||||
font-family: "HashFontNoSpace", "SerenitySans";
|
||||
font-size: 100px;
|
||||
}
|
||||
.fallback-only {
|
||||
font-family: "SerenitySans";
|
||||
font-size: 100px;
|
||||
}
|
||||
span {
|
||||
white-space: pre;
|
||||
}
|
||||
</style>
|
||||
<script src="include.js"></script>
|
||||
<div>
|
||||
<span class="subset" id="letters-only">AB</span>
|
||||
<span class="subset" id="with-space">A B</span>
|
||||
<span class="fallback-only" id="ref-space"> </span>
|
||||
</div>
|
||||
<script>
|
||||
test(() => {
|
||||
// HashFontNoSpace covers only A–Z; the space in "A B" must come from the
|
||||
// SerenitySans fallback, not from HashFontNoSpace's .notdef glyph.
|
||||
let lettersOnlyWidth = document.getElementById("letters-only").getBoundingClientRect().width;
|
||||
let withSpaceWidth = document.getElementById("with-space").getBoundingClientRect().width;
|
||||
let fallbackSpaceWidth = document.getElementById("ref-space").getBoundingClientRect().width;
|
||||
|
||||
let spaceWidth = withSpaceWidth - lettersOnlyWidth;
|
||||
println("space matches fallback: " + (Math.abs(spaceWidth - fallbackSpaceWidth) < 2));
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user