Skip to content

Commit

Permalink
new test: length of family + style must not exceed 20 chars
Browse files Browse the repository at this point in the history
This is also the first test using the new markup for rationale, affected applications/OS/browsers, etc...
And includes a proper code-test as well. Future new test requests/implementations should try to do the same.
(issue fonttools#1488)
  • Loading branch information
felipesanches committed Sep 21, 2017
1 parent 0d93e8e commit 1a96fa0
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 7 deletions.
9 changes: 8 additions & 1 deletion Lib/fontbakery/callable.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,14 @@ def __init__(
name = None, # very short text
conditions=None,
# arguments_setup=None,
documentation=None, # long text, markdown?
documentation=None, # markdown?
rationale=None, # long text explaining why this test is needed. Using markdown, perhaps?
affects=None, # A list of tuples each indicating Browser/OS/Application
# and the affected versions range.
request=None, # An URL to the original request for implementation of this test.
# This is typically a github issue tracker URL.
example_failures=None, # A reference to some font or family that originally failed due to
# the problems that this test tries to detect and report.
advancedMessageSetup=None,
priority=None
):
Expand Down
36 changes: 36 additions & 0 deletions Lib/fontbakery/specifications/googlefonts.py
Original file line number Diff line number Diff line change
Expand Up @@ -4570,3 +4570,39 @@ def check_name_table_TYPOGRAPHIC_SUBFAMILY_NAME(ttFont, style):
unidecode(string))
if not failed:
yield PASS, "TYPOGRAPHIC_SUBFAMILY_NAME entries are all good."


@register_test
@test(
id='com.google.fonts/test/163'
, rationale = """According to a Glyphs tutorial (available at https://glyphsapp.com/tutorials/multiple-masters-part-3-setting-up-instances), in order to make sure all versions of Windows recognize it as a valid font file, we must make sure that the concatenated length of the familyname (NAMEID_FONT_FAMILY_NAME) and style (NAMEID_FONT_SUBFAMILY_NAME) strings in the name table do not exceed 20 characters.""" # Somebody with access to Windows should make some tests and confirm that this is really the case.
, affects = [('Windows', 'unspecified')]
, request = 'https://github.com/googlefonts/fontbakery/issues/1488'
, example_failures = None
)
def com_google_fonts_test_163(ttFont):
""" Combined length of family and style must not exceed 20 characters. """
from unidecode import unidecode
from fontbakery.utils import (get_name_entries,
get_name_entry_strings)
from fontbakery.constants import (NAMEID_FONT_FAMILY_NAME,
NAMEID_FONT_SUBFAMILY_NAME,
PLATID_STR)
failed = False
for familyname in get_name_entries(ttFont, NAMEID_FONT_FAMILY_NAME):
# we'll only match family/style name entries with the same platform ID:
plat = familyname.platformID
familyname_str = familyname.string.decode(familyname.getEncoding())
for stylename_str in get_name_entry_strings(ttFont,
NAMEID_FONT_SUBFAMILY_NAME,
platformID=plat):
if len(familyname_str + stylename_str) > 20:
failed = True
yield FAIL, ("The combined length of family and style"
" exceeds 20 chars in the following '{}' entries:"
" FONT_FAMILY_NAME = '{}' / SUBFAMILY_NAME = '{}'"
"").format(PLATID_STR[plat],
unidecode(familyname_str),
unidecode(stylename_str))
if not failed:
yield PASS, "All name entries are good."
34 changes: 34 additions & 0 deletions Lib/fontbakery/specifications/googlefonts_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1832,3 +1832,37 @@ def test_id_159():
assert status == FAIL
# restore it:
ttFont["name"].names[index].string = backup

# TODO: test_id_160
# TODO: test_id_161
# TODO: test_id_162

def test_id_163():
""" Check font name is the same as family name. """
from fontbakery.specifications.googlefonts import com_google_fonts_test_163 as test
from fontbakery.constants import (NAMEID_FONT_FAMILY_NAME,
NAMEID_FONT_SUBFAMILY_NAME)
# Our reference Cabin Regular is known to be good
ttFont = TTFont("data/test/cabin/Cabin-Regular.ttf")

# So it must PASS the test:
print ("Test PASS with a good font...")
status, message = list(test(ttFont))[-1]
assert status == PASS

# Then we FAIL with the long family/style names
# that were used as an example on the glyphs tutorial
# (at https://glyphsapp.com/tutorials/multiple-masters-part-3-setting-up-instances):
for index, name in enumerate(ttFont["name"].names):
if name.nameID == NAMEID_FONT_FAMILY_NAME:
ttFont["name"].names[index].string = "ImpossibleFamilyNameFont".encode(name.getEncoding())
break

for index, name in enumerate(ttFont["name"].names):
if name.nameID == NAMEID_FONT_SUBFAMILY_NAME:
ttFont["name"].names[index].string = "WithAVeryLongStyleName".encode(name.getEncoding())
break

print ("Test FAIL with a bad font...")
status, message = list(test(ttFont))[-1]
assert status == FAIL
21 changes: 15 additions & 6 deletions Lib/fontbakery/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,30 @@ def get_bounding_box(font):
return ymin, ymax


def get_name_entry_strings(font,
nameID,
platformID=None,
encodingID=None,
langID=None):
def get_name_entries(font,
nameID,
platformID=None,
encodingID=None,
langID=None):
results = []
for entry in font['name'].names:
if entry.nameID == nameID and \
(platformID is None or entry.platformID == platformID) and \
(encodingID is None or entry.platEncID == encodingID) and \
(langID is None or entry.langID == langID):
results.append(entry.string.decode(entry.getEncoding()))
results.append(entry)
return results


def get_name_entry_strings(font,
nameID,
platformID=None,
encodingID=None,
langID=None):
entries = get_name_entries(font, nameID, platformID, encodingID, langID)
return map(lambda e: e.string.decode(e.getEncoding()), entries)


def name_entry_id(name):
from fontbakery.constants import (NAMEID_STR,
PLATID_STR)
Expand Down

0 comments on commit 1a96fa0

Please sign in to comment.