Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def org_sil_software_version_format(ttFont):
"Version format is correct in 'name' table?"
from fontbakery.utils import get_name_entry_strings
import re
failed = False
warned = False
version_entries = get_name_entry_strings(ttFont, NameID.VERSION_STRING)
if len(version_entries) == 0:
failed = True
yield FAIL,\
Message("no-version-string",
f"Font lacks a NameID.VERSION_STRING"
f" (nameID={NameID.VERSION_STRING}) entry")
for ventry in version_entries:
if not re.match(r'Version [0-9]+\.\d{3}( .+)*$', ventry):
failed = True
yield FAIL,\
Message("bad-version-strings",
f'The NameID.VERSION_STRING'
f' (nameID={NameID.VERSION_STRING}) value must'
f' follow the pattern "Version X.nnn devstring" with X.nnn'
f' greater than or equal to 0.000.'
f' Current version string is: "{ventry}"')
elif not re.match(r'Version [1-9][0-9]*\.\d{3}$', ventry):
warned = True
def com_roboto_fonts_check_italic_angle(ttFont):
"""Check italic fonts have correct italic angle"""
failed = False
if ttFont['post'].italicAngle != -12:
yield FAIL, "post.italicAngle must be set to -12"
else:
yield PASS, "post.italicAngle is set correctly"
def com_daltonmaag_check_required_fields(ufo_font):
"""Check that required fields are present in the UFO fontinfo."""
recommended_fields = []
for field in [
"unitsPerEm", "ascender", "descender", "xHeight", "capHeight",
"familyName"
]:
if ufo_font.info.__dict__.get("_" + field) is None:
recommended_fields.append(field)
if recommended_fields:
yield FAIL, f"Required field(s) missing: {recommended_fields}"
else:
yield PASS, "Required fields present."
def com_google_fonts_check_maxadvancewidth(ttFont):
"""MaxAdvanceWidth is consistent with values in the Hmtx and Hhea tables?"""
hhea_advance_width_max = ttFont['hhea'].advanceWidthMax
hmtx_advance_width_max = None
for g in ttFont['hmtx'].metrics.values():
if hmtx_advance_width_max is None:
hmtx_advance_width_max = max(0, g[0])
else:
hmtx_advance_width_max = max(g[0], hmtx_advance_width_max)
if hmtx_advance_width_max != hhea_advance_width_max:
yield FAIL,\
Message("mismatch",
f"AdvanceWidthMax mismatch:"
f" expected {hmtx_advance_width_max} (from hmtx);"
f" got {hhea_advance_width_max} (from hhea)")
else:
yield PASS, ("MaxAdvanceWidth is consistent"
" with values in the Hmtx and Hhea tables.")
def check_bit_entry(ttFont, table, attr, expected, bitmask, bitname):
from fontbakery.message import Message
from fontbakery.checkrunner import (PASS, FAIL)
value = getattr(ttFont[table], attr)
name_str = f"{table} {attr} {bitname} bit"
if bool(value & bitmask) == expected:
return PASS, f"{name_str} is properly set."
else:
if expected:
expected_str = "set"
else:
expected_str = "unset"
return FAIL, Message(f"bad-{bitname}",
f"{name_str} should be {expected_str}.")
def com_google_fonts_check_glyf_unused_data(ttFont):
"""Is there any unused data at the end of the glyf table?"""
try:
expected_glyphs = len(ttFont.getGlyphOrder())
actual_glyphs = len(ttFont['glyf'].glyphs)
diff = actual_glyphs - expected_glyphs
if diff < 0:
yield FAIL,\
Message("unreachable-data",
f"Glyf table has unreachable data at the end of the table."
f" Expected glyf table length {expected_glyphs} (from loca"
f" table), got length {actual_glyphs}"
f" (difference: {diff})")
elif not diff: # negative diff -> exception below
yield PASS, "There is no unused data at the end of the glyf table."
else:
raise Exception("Bug: fontTools did not raise an expected exception.")
except fontTools.ttLib.TTLibError as error:
if "not enough 'glyf' table data" in format(error):
yield FAIL,\
Message("missing-data",
f"Loca table references data beyond"
f" the end of the glyf table."
f" Expected glyf table length {expected_glyphs}"
def com_google_fonts_check_ligature_carets(ttFont, ligature_glyphs):
"""Are there caret positions declared for every ligature?"""
if ligature_glyphs == -1:
yield FAIL, Message("malformed", "Failed to lookup ligatures."
" This font file seems to be malformed."
" For more info, read:"
" https://github.com"
"/googlefonts/fontbakery/issues/1596")
elif "GDEF" not in ttFont:
yield WARN, Message("GDEF-missing",
("GDEF table is missing, but it is mandatory"
" to declare it on fonts that provide ligature"
" glyphs because the caret (text cursor)"
" positioning for each ligature must be"
" provided in this table."))
else:
lig_caret_list = ttFont["GDEF"].table.LigCaretList
if lig_caret_list is None:
missing = set(ligature_glyphs)
else:
def com_adobe_fonts_check_family_consistent_upm(ttFonts):
"""Fonts have consistent Units Per Em?"""
upm_set = set()
for ttFont in ttFonts:
upm_set.add(ttFont['head'].unitsPerEm)
if len(upm_set) > 1:
yield FAIL, ("Fonts have different units per em: {}."
).format(sorted(upm_set))
else:
yield PASS, "Fonts have consistent units per em."