summaryrefslogtreecommitdiffstats
path: root/lib/silfont/fbtests/ttfchecks.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/silfont/fbtests/ttfchecks.py')
-rw-r--r--lib/silfont/fbtests/ttfchecks.py305
1 files changed, 305 insertions, 0 deletions
diff --git a/lib/silfont/fbtests/ttfchecks.py b/lib/silfont/fbtests/ttfchecks.py
new file mode 100644
index 0000000..e05ecb1
--- /dev/null
+++ b/lib/silfont/fbtests/ttfchecks.py
@@ -0,0 +1,305 @@
+#!/usr/bin/env python
+'Support for use of Fontbakery ttf checks'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2020 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from fontbakery.checkrunner import Section, PASS, FAIL, WARN, ERROR, INFO, SKIP
+from fontbakery.callable import condition, check, disable
+from fontbakery.message import Message
+from fontbakery.fonts_profile import profile_factory
+from fontbakery.constants import NameID, PlatformID, WindowsEncodingID
+from fontbakery.profiles.googlefonts import METADATA_CHECKS, REPO_CHECKS, DESCRIPTION_CHECKS
+from fontbakery.profiles.ufo_sources import UFO_PROFILE_CHECKS
+from fontbakery.profiles.universal import DESIGNSPACE_CHECKS
+from silfont.fbtests.silttfchecks import *
+from silfont.fbtests.silnotcjk import *
+
+from collections import OrderedDict
+
+# Set imports of standard ttf tests
+
+profile_imports = ("fontbakery.profiles.universal",
+ "fontbakery.profiles.googlefonts",
+ "fontbakery.profiles.adobefonts",
+ "fontbakery.profiles.notofonts",
+ "fontbakery.profiles.fontval")
+
+def make_base_profile():
+ profile = profile_factory(default_section=Section("SIL Fonts"))
+ profile.auto_register(globals())
+
+ # Exclude groups of checks that check files other than ttfs
+ for checkid in DESCRIPTION_CHECKS + DESIGNSPACE_CHECKS + METADATA_CHECKS + REPO_CHECKS + UFO_PROFILE_CHECKS:
+ if checkid in profile._check_registry: profile.remove_check(checkid)
+
+ return profile
+
+def make_profile(check_list, variable_font=False):
+ profile = make_base_profile()
+
+ # Exclude all the checks we don't want to run
+ for checkid in check_list:
+ if checkid in profile._check_registry:
+ check_item = check_list[checkid]
+ exclude = check_item["exclude"] if "exclude" in check_item else False
+ if exclude: profile.remove_check(checkid)
+
+ # Exclude further sets of checks to reduce number of skips and so have less clutter in html results
+ for checkid in sorted(set(profile._check_registry.keys())):
+ section = profile._check_registry[checkid]
+ check = section.get_check(checkid)
+ conditions = getattr(check, "conditions")
+ exclude = False
+ if variable_font and "not is_variable_font" in conditions: exclude = True
+ if not variable_font and "is_variable_font" in conditions: exclude = True
+ if "noto" in checkid.lower(): exclude = True # These will be specific to Noto fonts
+ if ":adobefonts" in checkid.lower(): exclude = True # Copy of standard test with overridden results so no new info
+
+ if exclude: profile.remove_check(checkid)
+ # Remove further checks that are only relevant for variable fonts but don't use the is_variable_font condition
+ if not variable_font:
+ for checkid in (
+ "com.adobe.fonts/check/stat_has_axis_value_tables",
+ "com.google.fonts/check/STAT_strings",
+ "com.google.fonts/check/STAT/axis_order"):
+ if checkid in profile._check_registry.keys(): profile.remove_check(checkid)
+ return profile
+
+def all_checks_dict(): # An ordered dict of all checks designed for exporting the data
+ profile = make_base_profile()
+ check_dict=OrderedDict()
+
+ for checkid in sorted(set(profile._check_registry.keys()), key=str.casefold):
+ if "noto" in checkid.lower(): continue # We wxclude these in make_profile()
+ if ":adobefonts" in checkid.lower(): continue # We wxclude these in make_profile()
+
+ section = profile._check_registry[checkid]
+ check = section.get_check(checkid)
+
+ conditions = getattr(check, "conditions")
+ conditionstxt=""
+ for condition in conditions:
+ conditionstxt += condition + "\n"
+ conditionstxt = conditionstxt.strip()
+
+ rationale = getattr(check,"rationale")
+ rationale = "" if rationale is None else rationale.strip().replace("\n ", "\n") # Remove extraneous whitespace
+
+ psfaction = psfcheck_list[checkid] if checkid in psfcheck_list else "Not in psfcheck_list"
+
+ item = {"psfaction": psfaction,
+ "section": section.name,
+ "description": getattr(check, "description"),
+ "rationale": rationale,
+ "conditions": conditionstxt
+ }
+ check_dict[checkid] = item
+
+ for checkid in psfcheck_list: # Look for checks no longer in Font Bakery
+ if checkid not in check_dict:
+ check_dict[checkid] = {"psfaction": psfcheck_list[checkid],
+ "section": "Missing",
+ "description": "Check not found",
+ "rationale": "",
+ "conditions": ""
+ }
+
+ return check_dict
+
+psfcheck_list = {}
+psfcheck_list['com.adobe.fonts/check/cff_call_depth'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/cff_deprecated_operators'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/cff2_call_depth'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/family/bold_italic_unique_for_nameid1'] = {}
+psfcheck_list['com.adobe.fonts/check/family/consistent_upm'] = {}
+psfcheck_list['com.adobe.fonts/check/family/max_4_fonts_per_family_name'] = {}
+psfcheck_list['com.adobe.fonts/check/find_empty_letters'] = {}
+psfcheck_list['com.adobe.fonts/check/freetype_rasterizer'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/fsselection_matches_macstyle'] = {}
+psfcheck_list['com.adobe.fonts/check/name/empty_records'] = {}
+psfcheck_list['com.adobe.fonts/check/name/postscript_name_consistency'] = {}
+psfcheck_list['com.adobe.fonts/check/nameid_1_win_english'] = {}
+psfcheck_list['com.adobe.fonts/check/name/postscript_vs_cff'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/sfnt_version'] = {}
+psfcheck_list['com.adobe.fonts/check/stat_has_axis_value_tables'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/distinct_instance_records'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/same_size_instance_records'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/valid_axis_nameid'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/valid_default_instance_nameids'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/valid_postscript_nameid'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/valid_subfamily_nameid'] = {}
+psfcheck_list['com.fontwerk/check/inconsistencies_between_fvar_stat'] = {}
+psfcheck_list['com.fontwerk/check/weight_class_fvar'] = {}
+psfcheck_list['com.google.fonts/check/aat'] = {}
+psfcheck_list['com.google.fonts/check/all_glyphs_have_codepoints'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/canonical_filename'] = {}
+psfcheck_list['com.google.fonts/check/cjk_chws_feature'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cjk_not_enough_glyphs'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cjk_vertical_metrics'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cjk_vertical_metrics_regressions'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cmap/alien_codepoints'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cmap/format_12'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cmap/unexpected_subtables'] = {}
+psfcheck_list['com.google.fonts/check/code_pages'] = {}
+psfcheck_list['com.google.fonts/check/contour_count'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/dotted_circle'] = {}
+psfcheck_list['com.google.fonts/check/dsig'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/epar'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/family/control_chars'] = {}
+psfcheck_list['com.google.fonts/check/family/equal_font_versions'] = {}
+psfcheck_list['com.google.fonts/check/family/equal_unicode_encodings'] = {}
+psfcheck_list['com.google.fonts/check/gpos7'] = {}
+psfcheck_list['com.google.fonts/check/family/has_license'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/family/italics_have_roman_counterparts'] = {}
+psfcheck_list['com.google.fonts/check/family/panose_familytype'] = {}
+psfcheck_list['com.google.fonts/check/family/panose_proportion'] = {}
+psfcheck_list['com.google.fonts/check/family/single_directory'] = {}
+psfcheck_list['com.google.fonts/check/family/tnum_horizontal_metrics'] = {}
+psfcheck_list['com.google.fonts/check/family/underline_thickness'] = {}
+psfcheck_list['com.google.fonts/check/family/vertical_metrics'] = {}
+psfcheck_list['com.google.fonts/check/family/win_ascent_and_descent'] = {'exclude': True}
+# {'change_status': {'FAIL': 'WARN', 'reason': 'Under review'}}
+psfcheck_list['com.google.fonts/check/family_naming_recommendations'] = {}
+psfcheck_list['com.google.fonts/check/file_size'] = {}
+psfcheck_list['com.google.fonts/check/font_copyright'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/font_version'] = {}
+psfcheck_list['com.google.fonts/check/fontbakery_version'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/fontdata_namecheck'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/fontv'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/fontvalidator'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/fsselection'] = {}
+psfcheck_list['com.google.fonts/check/fstype'] = {}
+psfcheck_list['com.google.fonts/check/fvar_name_entries'] = {}
+psfcheck_list['com.google.fonts/check/gasp'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/gdef_mark_chars'] = {}
+psfcheck_list['com.google.fonts/check/gdef_non_mark_chars'] = {}
+psfcheck_list['com.google.fonts/check/gdef_spacing_marks'] = {}
+psfcheck_list['com.google.fonts/check/gf-axisregistry/fvar_axis_defaults'] = {}
+psfcheck_list['com.google.fonts/check/glyf_nested_components'] = {}
+psfcheck_list['com.google.fonts/check/glyf_non_transformed_duplicate_components'] = {}
+psfcheck_list['com.google.fonts/check/glyf_unused_data'] = {}
+psfcheck_list['com.google.fonts/check/glyph_coverage'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/gpos_kerning_info'] = {}
+psfcheck_list['com.google.fonts/check/has_ttfautohint_params'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/hinting_impact'] = {}
+psfcheck_list['com.google.fonts/check/hmtx/comma_period'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/hmtx/encoded_latin_digits'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/hmtx/whitespace_advances'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/integer_ppem_if_hinted'] = {}
+psfcheck_list['com.google.fonts/check/italic_angle'] = {}
+psfcheck_list['com.google.fonts/check/kern_table'] = {}
+psfcheck_list['com.google.fonts/check/kerning_for_non_ligated_sequences'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/layout_valid_feature_tags'] = {}
+psfcheck_list['com.google.fonts/check/layout_valid_language_tags'] = \
+ {'change_status': {'FAIL': 'WARN', 'reason': 'The "invalid" ones are used by Harfbuzz'}}
+psfcheck_list['com.google.fonts/check/layout_valid_script_tags'] = {}
+psfcheck_list['com.google.fonts/check/ligature_carets'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/linegaps'] = {}
+psfcheck_list['com.google.fonts/check/loca/maxp_num_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/mac_style'] = {}
+psfcheck_list['com.google.fonts/check/mandatory_avar_table'] = {}
+psfcheck_list['com.google.fonts/check/mandatory_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/maxadvancewidth'] = {}
+psfcheck_list['com.google.fonts/check/meta/script_lang_tags'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/missing_small_caps_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/monospace'] = {}
+psfcheck_list['com.google.fonts/check/name/ascii_only_entries'] = {}
+psfcheck_list['com.google.fonts/check/name/copyright_length'] = {}
+psfcheck_list['com.google.fonts/check/name/description_max_length'] = {}
+psfcheck_list['com.google.fonts/check/name/family_and_style_max_length'] = {}
+psfcheck_list['com.google.fonts/check/name/familyname'] = {}
+psfcheck_list['com.google.fonts/check/name/familyname_first_char'] = {}
+psfcheck_list['com.google.fonts/check/name/fullfontname'] = {}
+psfcheck_list['com.google.fonts/check/name/license'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/license_url'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/line_breaks'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/mandatory_entries'] = {}
+psfcheck_list['com.google.fonts/check/name/match_familyname_fullfont'] = {}
+psfcheck_list['com.google.fonts/check/name/no_copyright_on_description'] = {}
+psfcheck_list['com.google.fonts/check/name/postscriptname'] = {}
+psfcheck_list['com.google.fonts/check/name/rfn'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/subfamilyname'] = {}
+psfcheck_list['com.google.fonts/check/name/trailing_spaces'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/typographicfamilyname'] = {}
+psfcheck_list['com.google.fonts/check/name/typographicsubfamilyname'] = {}
+psfcheck_list['com.google.fonts/check/name/unwanted_chars'] = {}
+psfcheck_list['com.google.fonts/check/name/version_format'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/no_debugging_tables'] = {}
+psfcheck_list['com.google.fonts/check/old_ttfautohint'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/os2/use_typo_metrics'] = {'exclude': True}
+#psfcheck_list['com.google.fonts/check/os2/use_typo_metrics'] = \ (Left a copy commented out as an
+# {'change_status': {'FAIL': 'WARN', 'reason': 'Under review'}} example of an override!)
+psfcheck_list['com.google.fonts/check/os2_metrics_match_hhea'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/ots'] = {}
+psfcheck_list['com.google.fonts/check/outline_alignment_miss'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/outline_colinear_vectors'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/outline_jaggy_segments'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/outline_semi_vertical'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/outline_short_segments'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/points_out_of_bounds'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/post_table_version'] = {}
+psfcheck_list['com.google.fonts/check/production_glyphs_similarity'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/render_own_name'] = {}
+psfcheck_list['com.google.fonts/check/required_tables'] = {}
+psfcheck_list['com.google.fonts/check/rupee'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/shaping/collides'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/shaping/forbidden'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/shaping/regression'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/smart_dropout'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/STAT/axis_order'] = {}
+psfcheck_list['com.google.fonts/check/STAT/gf-axisregistry'] = {}
+psfcheck_list['com.google.fonts/check/STAT_strings'] = {}
+psfcheck_list['com.google.fonts/check/stylisticset_description'] = {}
+psfcheck_list['com.google.fonts/check/superfamily/list'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/superfamily/vertical_metrics'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/transformed_components'] = {}
+psfcheck_list['com.google.fonts/check/ttx-roundtrip'] = {}
+psfcheck_list['com.google.fonts/check/unicode_range_bits'] = {}
+psfcheck_list['com.google.fonts/check/unique_glyphnames'] = {}
+psfcheck_list['com.google.fonts/check/unitsperem'] = {}
+psfcheck_list['com.google.fonts/check/unitsperem_strict'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/unreachable_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/unwanted_tables'] = {}
+psfcheck_list['com.google.fonts/check/usweightclass'] = {}
+psfcheck_list['com.google.fonts/check/valid_glyphnames'] = {}
+psfcheck_list['com.google.fonts/check/varfont_duplicate_instance_names'] = {}
+psfcheck_list['com.google.fonts/check/varfont_has_instances'] = {}
+psfcheck_list['com.google.fonts/check/varfont_instance_coordinates'] = {}
+psfcheck_list['com.google.fonts/check/varfont_instance_names'] = {}
+psfcheck_list['com.google.fonts/check/varfont_weight_instances'] = {}
+psfcheck_list['com.google.fonts/check/varfont/bold_wght_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/consistent_axes'] = {}
+psfcheck_list['com.google.fonts/check/varfont/generate_static'] = {}
+psfcheck_list['com.google.fonts/check/varfont/grade_reflow'] = {}
+psfcheck_list['com.google.fonts/check/varfont/has_HVAR'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_ital_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_opsz_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_slnt_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_wdth_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_wght_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/slnt_range'] = {}
+psfcheck_list['com.google.fonts/check/varfont/stat_axis_record_for_each_axis'] = {}
+psfcheck_list['com.google.fonts/check/varfont/unsupported_axes'] = {}
+psfcheck_list['com.google.fonts/check/varfont/wdth_valid_range'] = {}
+psfcheck_list['com.google.fonts/check/varfont/wght_valid_range'] = {}
+psfcheck_list['com.google.fonts/check/vendor_id'] = {}
+psfcheck_list['com.google.fonts/check/version_bump'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/vertical_metrics'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/vertical_metrics_regressions'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/vttclean'] = {}
+psfcheck_list['com.google.fonts/check/whitespace_glyphnames'] = {}
+psfcheck_list['com.google.fonts/check/whitespace_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/whitespace_ink'] = {}
+psfcheck_list['com.google.fonts/check/whitespace_widths'] = {}
+psfcheck_list['com.google.fonts/check/xavgcharwidth'] = {}
+psfcheck_list['org.sil/check/family/win_ascent_and_descent'] = {}
+psfcheck_list['org.sil/check/os2/use_typo_metrics'] = {}
+psfcheck_list['org.sil/check/os2_metrics_match_hhea'] = {}
+psfcheck_list['org.sil/check/vertical_metrics'] = {}
+psfcheck_list['org.sil/check/number_widths'] = {}
+psfcheck_list['org.sil/check/name/version_format'] = {}
+psfcheck_list['org.sil/check/whitespace_widths'] = {}
+
+profile = make_profile(check_list=psfcheck_list)