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.'
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
yield WARN, \
Message("nonproduction-version-strings",
f'For production fonts, the NameID.VERSION_STRING'
f' (nameID={NameID.VERSION_STRING}) value must'
f' follow the pattern "Version X.nnn" with X.nnn'
f' greater than or equal to 1.000.'
f' Current version string is: "{ventry}"')
if not failed and not warned:
yield PASS, "Version format in NAME table entries is correct."
from fontbakery.utils import get_name_entry_strings
from fontbakery.constants import RIBBI_STYLE_NAMES
required_nameIDs = [NameID.FONT_FAMILY_NAME,
NameID.FONT_SUBFAMILY_NAME,
NameID.FULL_FONT_NAME,
NameID.POSTSCRIPT_NAME]
if style not in RIBBI_STYLE_NAMES:
required_nameIDs += [NameID.TYPOGRAPHIC_FAMILY_NAME,
NameID.TYPOGRAPHIC_SUBFAMILY_NAME]
failed = False
# The font must have at least these name IDs:
for nameId in required_nameIDs:
if len(get_name_entry_strings(ttFont, nameId)) == 0:
failed = True
yield FAIL, (f"Font lacks entry with nameId={nameId}"
f" ({NameID(nameId).name})")
if not failed:
yield PASS, "Font contains values for all mandatory name table entries."
def com_adobe_fonts_check_family_bold_italic_unique_for_nameid1(RIBBI_ttFonts):
"""Check that OS/2.fsSelection bold & italic settings are unique
for each NameID1"""
from collections import Counter
from fontbakery.utils import get_name_entry_strings
from fontbakery.constants import NameID, FsSelection
failed = False
family_name_and_bold_italic = list()
for ttFont in RIBBI_ttFonts:
names_list = get_name_entry_strings(ttFont, NameID.FONT_FAMILY_NAME)
# names_list will likely contain multiple entries, e.g. multiple copies
# of the same name in the same language for different platforms, but
# also different names in different languages, we use set() below
# to remove the duplicates and only store the unique family name(s)
# used for a given font
names_set = set(names_list)
bold = (ttFont['OS/2'].fsSelection & FsSelection.BOLD) != 0
italic = (ttFont['OS/2'].fsSelection & FsSelection.ITALIC) != 0
bold_italic = 'Bold=%r, Italic=%r' % (bold, italic)
for name in names_set:
family_name_and_bold_italic.append((name, bold_italic,))
counter = Counter(family_name_and_bold_italic)
def name_entry_id(name):
from fontbakery.constants import (NameID,
PlatformID)
return "[{}({}):{}({})]".format(NameID(name.nameID).name,
name.nameID,
PlatformID(name.platformID).name,
name.platformID)
def font_familynames(ttFont):
from fontbakery.utils import get_name_entry_strings
return get_name_entry_strings(ttFont, NameID.FONT_FAMILY_NAME)
def typographic_familynames(ttFont):
from fontbakery.utils import get_name_entry_strings
return get_name_entry_strings(ttFont, NameID.TYPOGRAPHIC_FAMILY_NAME)
def com_google_fonts_check_font_version(ttFont):
"""Checking font version fields (head and name table)."""
from decimal import Decimal
head_version_str = str(Decimal(ttFont["head"].fontRevision).quantize(Decimal('1.000')))
head_version = parse_version_string(head_version_str)
# Compare the head version against the name ID 5 strings in all name records.
name_id_5_records = [
record for record in ttFont["name"].names
if record.nameID == NameID.VERSION_STRING
]
failed = False
if name_id_5_records:
for record in name_id_5_records:
try:
name_version = parse_version_string(record.toUnicode())
if name_version != head_version:
failed = True
yield FAIL,\
Message("mismatch",
f'head version is "{head_version_str}"'
f' while name version string (for'
f' platform {record.platformID},'
f' encoding {record.platEncID}) is'
f' "{record.toUnicode()}".')
'field': 'Style Name',
'value': string,
'rec': 'exceeds max length (31)'
})
for string in get_name_entry_strings(ttFont,
NameID.TYPOGRAPHIC_FAMILY_NAME):
if len(string) >= 32:
bad_entries.append({
'field': 'OT Family Name',
'value': string,
'rec': 'exceeds max length (31)'
})
for string in get_name_entry_strings(ttFont,
NameID.TYPOGRAPHIC_SUBFAMILY_NAME):
if len(string) >= 32:
bad_entries.append({
'field': 'OT Style Name',
'value': string,
'rec': 'exceeds max length (31)'
})
if len(bad_entries) > 0:
table = "| Field | Value | Recommendation |\n"
table += "|:----- |:----- |:-------------- |\n"
for bad in bad_entries:
table += "| {} | {} | {} |\n".format(bad["field"],
bad["value"],
bad["rec"])
yield INFO,\
Message("bad-entries",