Skip to content

Commit

Permalink
update implementation of 'control_chars' check
Browse files Browse the repository at this point in the history
to handle single font files instead of a whole family.

On the Universal profile.

(issue #4896)
  • Loading branch information
felipesanches committed Nov 12, 2024
1 parent 2f2e288 commit e8c47f4
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 88 deletions.
66 changes: 9 additions & 57 deletions Lib/fontbakery/checks/glyphset.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,71 +101,23 @@ def check_case_mapping(ttFont):
""",
proposal="https://github.com/fonttools/fontbakery/pull/2430",
)
def check_family_control_chars(ttFonts):
def check_family_control_chars(ttFont):
"""Does font file include unacceptable control character glyphs?"""
# list of unacceptable control character glyph names
# definition includes the entire control character Unicode block except:
# - .null (U+0000)
# - CR (U+000D)
unacceptable_cc_list = [
"uni0001",
"uni0002",
"uni0003",
"uni0004",
"uni0005",
"uni0006",
"uni0007",
"uni0008",
"uni0009",
"uni000A",
"uni000B",
"uni000C",
"uni000E",
"uni000F",
"uni0010",
"uni0011",
"uni0012",
"uni0013",
"uni0014",
"uni0015",
"uni0016",
"uni0017",
"uni0018",
"uni0019",
"uni001A",
"uni001B",
"uni001C",
"uni001D",
"uni001E",
"uni001F",
]

# A dict with 'key => value' pairs of
# font path that did not pass the check => list of unacceptable glyph names
bad_fonts = {}

for ttFont in ttFonts:
passed = True
unacceptable_glyphs_in_set = [] # a list of unacceptable glyph names identified
glyph_name_set = set(ttFont["glyf"].glyphs.keys())
fontname = ttFont.reader.file.name
UNACCEPTABLE_CC = {f"uni{n:04X}" for n in range(32) if n not in [0x00, 0x0D]}

for unacceptable_glyph_name in unacceptable_cc_list:
if unacceptable_glyph_name in glyph_name_set:
passed = False
unacceptable_glyphs_in_set.append(unacceptable_glyph_name)
glyphset = set(ttFont["glyf"].glyphs.keys())
bad_glyphs = glyphset.intersection(UNACCEPTABLE_CC)

if not passed:
bad_fonts[fontname] = unacceptable_glyphs_in_set

if len(bad_fonts) > 0:
msg_unacceptable = (
"The following unacceptable control characters were identified:\n"
if bad_glyphs:
bad = ", ".join(bad_glyphs)
yield FAIL, Message(
"unacceptable",
f"The following unacceptable control characters were identified:\n{bad}",
)
for fnt in bad_fonts.keys():
bad = ", ".join(bad_fonts[fnt])
msg_unacceptable += f" {fnt}: {bad}\n"
yield FAIL, Message("unacceptable", f"{msg_unacceptable}")


@check(
Expand Down
37 changes: 6 additions & 31 deletions tests/test_checks_glyphset.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,44 +38,19 @@ def test_check_family_control_chars(check):
good_font = TEST_FILE(
"bad_character_set/control_chars/FontbakeryTesterCCGood-Regular.ttf"
)
onebad_cc_font = TEST_FILE(
bad_font = TEST_FILE(
"bad_character_set/control_chars/FontbakeryTesterCCOneBad-Regular.ttf"
)
multibad_cc_font = TEST_FILE(
"bad_character_set/control_chars/FontbakeryTesterCCMultiBad-Regular.ttf"
)

# No unacceptable control characters should pass with one file
fonts = [good_font]
assert_PASS(check(fonts), "with one good font...")

# No unacceptable control characters should pass with multiple good files
fonts = [good_font, good_font]
assert_PASS(check(fonts), "with multiple good fonts...")

# Unacceptable control chars should fail with one file x one bad char in font
fonts = [onebad_cc_font]
assert_results_contain(
check(fonts), FAIL, "unacceptable", "with one bad font that has one bad char..."
)

# Unacceptable control chars should fail with one file x multiple bad char in font
fonts = [multibad_cc_font]
assert_results_contain(
check(fonts),
FAIL,
"unacceptable",
"with one bad font that has multiple bad char...",
)
# No unacceptable control characters should pass
assert_PASS(check(good_font), "with a good font...")

# Unacceptable control chars should fail with multiple files x multiple bad chars
# in fonts
fonts = [onebad_cc_font, multibad_cc_font]
# Unacceptable control chars should fail
assert_results_contain(
check(fonts),
check(bad_font),
FAIL,
"unacceptable",
"with multiple bad fonts that have multiple bad chars...",
"with a bad font that has one bad char...",
)


Expand Down

0 comments on commit e8c47f4

Please sign in to comment.