diff --git a/CHANGELOG.md b/CHANGELOG.md index 844edff0fa..8f73426d6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ A more detailed list of changes is available in the corresponding milestones for ## 0.7.25 (2020-May-??) ### New checks - **[com.google.fonts/check/varfont/unsupported_axes]**: Ensure VFs do not contain opsz or ital axes. (issue #2866) + - **[com.google.fonts/check/STAT_strings]**: Check correctness of name table strings referenced by STAT table. (issue #2863) ### Added rationale metadata to these checks - **com.google.fonts/check/vendor_id** diff --git a/Lib/fontbakery/profiles/universal.py b/Lib/fontbakery/profiles/universal.py index b805feb392..0f7375ff08 100644 --- a/Lib/fontbakery/profiles/universal.py +++ b/Lib/fontbakery/profiles/universal.py @@ -42,6 +42,7 @@ 'com.google.fonts/check/unique_glyphnames', # 'com.google.fonts/check/glyphnames_max_length', 'com.google.fonts/check/family/vertical_metrics', + 'com.google.fonts/check/STAT_strings' ] @check( @@ -545,6 +546,51 @@ def com_google_fonts_check_unwanted_tables(ttFont): yield PASS, "There are no unwanted tables." +@condition +def STAT_table(ttFont): + return "STAT" in ttFont + + +@check( + id = 'com.google.fonts/check/STAT_strings', + conditions = ["STAT_table"], + rationale = """ + On the STAT table, the "Italic" keyword must not be used on AxisValues for variation axes other than 'ital'. + """, + misc_metadata = { + 'requested': "https://github.com/googlefonts/fontbakery/issues/2863" + } +) +def com_google_fonts_check_STAT_strings(ttFont): + """ Check correctness of STAT table strings """ + passed = True + ital_axis_index = None + for index, axis in enumerate(ttFont["STAT"].table.DesignAxisRecord.Axis): + if axis.AxisTag == 'ital': + ital_axis_index = index + break + + nameIDs = [] + for value in ttFont["STAT"].table.AxisValueArray.AxisValue: + if value.AxisIndex != ital_axis_index: nameIDs.append(value.ValueNameID) + + bad_values = [] + for name in ttFont['name'].names: + if name.nameID in nameIDs and "italic" in name.toUnicode().lower(): + passed = False + bad_values.append(name.toUnicode()) + + if bad_values: + yield FAIL,\ + Message("bad-italic", + f'The following AxisValue entries on the STAT table' + f' should not contain "Italic":\n' + f' {bad_values}') + + if passed: + yield PASS, "Looks good!" + + @check( id = 'com.google.fonts/check/valid_glyphnames', rationale = """ diff --git a/data/test/ibmplexsans-vf/IBMPlexSansVar-Italic.ttf b/data/test/ibmplexsans-vf/IBMPlexSansVar-Italic.ttf new file mode 100644 index 0000000000..473e284c33 Binary files /dev/null and b/data/test/ibmplexsans-vf/IBMPlexSansVar-Italic.ttf differ diff --git a/data/test/ibmplexsans-vf/IBMPlexSansVar-Roman.ttf b/data/test/ibmplexsans-vf/IBMPlexSansVar-Roman.ttf new file mode 100644 index 0000000000..44e2c2291d Binary files /dev/null and b/data/test/ibmplexsans-vf/IBMPlexSansVar-Roman.ttf differ diff --git a/tests/profiles/universal_test.py b/tests/profiles/universal_test.py index f26e5107ee..85f93d6d49 100644 --- a/tests/profiles/universal_test.py +++ b/tests/profiles/universal_test.py @@ -690,3 +690,13 @@ def test_check_superfamily_vertical_metrics(montserrat_ttFonts, cabin_ttFonts, c status, message = list(check([cabin_ttFonts, montserrat_ttFonts]))[-1] assert status == WARN + +def test_check_STAT_strings(): + from fontbakery.profiles.universal import com_google_fonts_check_STAT_strings as check + print("Test pass...") + status, message = list(check(TEST_FILE("ibmplexsans-vf/IBMPlexSansVar-Roman.ttf")))[-1] + assert status == PASS + + print("Test fail...") + status, message = list(check(TEST_FILE("ibmplexsans-vf/IBMPlexSansVar-Italic.ttf")))[-1] + assert status == FAIL