Skip to content

Commit 50b9cc5

Browse files
authored
fix base_has_width and add test
Fix base_has_width on Universal profile. Examine non-mark glyphs rather than mark glyphs; ignore PUA. (issue #5007)
1 parent 780e2b2 commit 50b9cc5

3 files changed

Lines changed: 64 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ A more detailed list of changes is available in the corresponding milestones for
1212

1313
### On the Universal profile
1414
- **[unwanted_tables]:** Remove checking for 'prop' because it is an AAT table. (issue #4989)
15+
- **[base_has_width]:** Examine non-mark glyphs rather than mark glyphs; ignore PUA. (issue #5007)
1516

1617

1718
## 0.13.2 (2025-Feb-03)

Lib/fontbakery/checks/base_has_width.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@
55

66

77
def is_space(codepoint):
8-
return unicodedata.category(chr(codepoint)) in [
9-
"Zs", # Space Separator
10-
"Zl", # Line Separator
11-
"Zp", # Paragraph Separator
12-
"Cf", # Format
13-
"Mn", # Nonspacing Mark
14-
"Cc", # Control
15-
]
8+
return (
9+
unicodedata.category(chr(codepoint))
10+
in [
11+
"Zs", # Space Separator
12+
"Zl", # Line Separator
13+
"Zp", # Paragraph Separator
14+
"Cf", # Format
15+
"Mn", # Nonspacing Mark
16+
"Cc", # Control
17+
]
18+
or 0xE000 <= codepoint <= 0xF8FF
19+
or 0xF0000 <= codepoint <= 0xFFFFD
20+
or 0x100000 <= codepoint <= 0x10FFFD
21+
)
1622

1723

1824
@check(
@@ -36,7 +42,7 @@ def check_base_has_width(font, config):
3642
if codepoint == 0 or codepoint is None:
3743
continue
3844

39-
if advance == 0 and not gid not in mark_glyphs(font.ttFont):
45+
if advance == 0 and gid not in mark_glyphs(font.ttFont):
4046
if is_space(codepoint):
4147
continue
4248

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from io import BytesIO
2+
from fontTools.ttLib import TTFont
3+
4+
from conftest import check_id
5+
from fontbakery.status import FAIL
6+
from fontbakery.codetesting import (
7+
assert_PASS,
8+
assert_results_contain,
9+
TEST_FILE,
10+
)
11+
12+
13+
def get_test_font():
14+
import defcon
15+
import ufo2ft
16+
17+
test_ufo = defcon.Font(TEST_FILE("test.ufo"))
18+
# Add a PUA character that has no width
19+
glyph = test_ufo.newGlyph("uniF176")
20+
glyph.unicode = 0xF176
21+
test_ttf = ufo2ft.compileTTF(test_ufo)
22+
23+
# Make the CheckTester class happy... :-P
24+
stream = BytesIO()
25+
test_ttf.save(stream)
26+
stream.seek(0)
27+
test_ttf = TTFont(stream)
28+
test_ttf.reader.file.name = "in-memory-data.ttf"
29+
return test_ttf
30+
31+
32+
@check_id("base_has_width")
33+
def test_check_base_has_width(check):
34+
"""Do some base characters have zero width?"""
35+
36+
ttfont = get_test_font()
37+
38+
assert_PASS(check(ttfont), "if acute has width...")
39+
40+
ttfont["hmtx"].metrics["A"] = (0, 0)
41+
42+
message = assert_results_contain(
43+
check(ttfont),
44+
FAIL,
45+
"zero-width-bases",
46+
"following glyphs had zero advance width",
47+
)
48+
assert "U+0041" in message

0 commit comments

Comments
 (0)