Skip to content

Commit 8cf2698

Browse files
authored
new check: com.google.fonts/check/glyf_nested_components
"Check that components do not reference glyphs which are themselves compontents" (issue #2961)
1 parent 3fb45d1 commit 8cf2698

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ A more detailed list of changes is available in the corresponding milestones for
1414
- **[com.google.fonts/check/metadata/gf-axisregistry_valid_tags]:** VF axis tags are registered on GF Axis Registry (issue #3010)
1515
- **[com.google.fonts/check/metadata/gf-axisregistry_bounds]:** VF axes have ranges compliant to the bounds specified on the GF Axis Registry (issue #3022)
1616
- **[com.google.fonts/check/STAT/gf-axisregistry]:** Check that particle names and values on STAT table match the fallback names in each axis registry at the Google Fonts Axis Registry (issue #3022)
17+
- **[com.google.fonts/check/glyf_nested_components]:** Check that components do not reference glyphs which are themselves compontents (issue #2961)
1718

1819
### Changes to existing checks
1920
- **[com.google.fonts/check/family/win_ascent_and_descent]**: Skip if font is cjk

Lib/fontbakery/profiles/glyf.py

+31
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,34 @@ def com_google_fonts_check_glyf_non_transformed_duplicate_components(ttFont):
127127
else:
128128
yield PASS, ("Glyphs do not contain duplicate components which have"
129129
" the same x,y coordinates.")
130+
131+
@check(
132+
id = 'com.google.fonts/check/glyf_nested_components',
133+
rationale = "There have been bugs rendering variable fonts with nested components. Additionally, some static fonts with nested components have been reported to have rendering and printing issues. (See googlefonts/fontbakery#2961 and arrowtype/recursive#412.)",
134+
conditions = ['is_ttf'],
135+
misc_metadata = {
136+
'request': 'https://github.com/googlefonts/fontbakery/issues/2961'
137+
}
138+
)
139+
def com_google_fonts_check_glyf_nested_components(ttFont):
140+
"""Check glyphs do not have components which are themselves components."""
141+
from fontbakery.utils import pretty_print_list
142+
failed = []
143+
for glyph_name in ttFont['glyf'].keys():
144+
glyph = ttFont['glyf'][glyph_name]
145+
if not glyph.isComposite():
146+
continue
147+
for comp in glyph.components:
148+
if ttFont['glyf'][comp.glyphName].isComposite():
149+
failed.append(glyph_name)
150+
if failed:
151+
formatted_list = "\t* " + pretty_print_list(failed,
152+
shorten=10,
153+
sep="\n\t* ")
154+
yield FAIL, \
155+
Message('found-nested-components',
156+
f"The following glyphs have components which"
157+
f" themselves are component glyphs:\n"
158+
f"{formatted_list}")
159+
else:
160+
yield PASS, ("Glyphs do not contain nested components.")

Lib/fontbakery/profiles/opentype.py

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
'com.google.fonts/check/maxadvancewidth',
7373
'com.google.fonts/check/points_out_of_bounds',
7474
'com.google.fonts/check/glyf_non_transformed_duplicate_components',
75+
'com.google.fonts/check/glyf_nested_components',
7576
'com.google.fonts/check/all_glyphs_have_codepoints',
7677
'com.google.fonts/check/code_pages',
7778
]

tests/profiles/glyf_test.py

+15
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,18 @@ def test_check_glyf_non_transformed_duplicate_components():
7070
assert_results_contain(check(ttFont),
7171
FAIL, 'found-duplicates')
7272

73+
74+
def test_check_glyf_nested_components():
75+
"""Check glyphs do not have nested components."""
76+
check = CheckTester(opentype_profile,
77+
"com.google.fonts/check/glyf_nested_components")
78+
79+
ttFont = TTFont(TEST_FILE("nunito/Nunito-Regular.ttf"))
80+
assert_PASS(check(ttFont))
81+
82+
# We need to create a nested component. "second" has components, so setting
83+
# one of "quotedbl"'s components to "second" should do it.
84+
ttFont['glyf']['quotedbl'].components[0].glyphName = "second"
85+
86+
assert_results_contain(check(ttFont),
87+
FAIL, 'found-nested-components')

0 commit comments

Comments
 (0)