diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-03-02 20:01:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-03-02 20:01:10 +0000 |
commit | da875fcb62c801b8d19b3d4d984ad963574fb356 (patch) | |
tree | 3d85503747c56c2a387b291524442946f4bebb73 /lib/silfont/fbtests | |
parent | Initial commit. (diff) | |
download | pysilfont-da875fcb62c801b8d19b3d4d984ad963574fb356.tar.xz pysilfont-da875fcb62c801b8d19b3d4d984ad963574fb356.zip |
Adding upstream version 1.6.0.upstream/1.6.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/silfont/fbtests')
-rwxr-xr-x | lib/silfont/fbtests/__init__.py | 0 | ||||
-rw-r--r-- | lib/silfont/fbtests/silnotcjk.py | 230 | ||||
-rw-r--r-- | lib/silfont/fbtests/silttfchecks.py | 250 | ||||
-rw-r--r-- | lib/silfont/fbtests/ttfchecks.py | 305 |
4 files changed, 785 insertions, 0 deletions
diff --git a/lib/silfont/fbtests/__init__.py b/lib/silfont/fbtests/__init__.py new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/lib/silfont/fbtests/__init__.py diff --git a/lib/silfont/fbtests/silnotcjk.py b/lib/silfont/fbtests/silnotcjk.py new file mode 100644 index 0000000..9ebdafd --- /dev/null +++ b/lib/silfont/fbtests/silnotcjk.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python +'''These are copies of checks that have the "not is_cjk" condition, but these versions have that condition removed. +The is_cjk condition was being matched by multiple fonts that are not cjk fonts - but do have some cjk punctuation characters. +These checks based on based on examples from Font Bakery, copyright 2017 The Font Bakery Authors, licensed under the Apache 2.0 license''' +__url__ = 'http://github.com/silnrsi/pysilfont' +__copyright__ = 'Copyright (c) 2022 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.profiles.shared_conditions import typo_metrics_enabled +import os +from fontbakery.constants import NameID, PlatformID, WindowsEncodingID + +@check( + id = 'org.sil/check/family/win_ascent_and_descent', + conditions = ['vmetrics'], + rationale = """ + Based on com.google.fonts/check/family/win_ascent_and_descent but with the 'not is_cjk' condition removed + """ +) +def org_sil_check_family_win_ascent_and_descent(ttFont, vmetrics): + """Checking OS/2 usWinAscent & usWinDescent.""" + + if "OS/2" not in ttFont: + yield FAIL,\ + Message("lacks-OS/2", + "Font file lacks OS/2 table") + return + + failed = False + os2_table = ttFont['OS/2'] + win_ascent = os2_table.usWinAscent + win_descent = os2_table.usWinDescent + y_max = vmetrics['ymax'] + y_min = vmetrics['ymin'] + + # OS/2 usWinAscent: + if win_ascent < y_max: + failed = True + yield FAIL,\ + Message("ascent", + f"OS/2.usWinAscent value should be" + f" equal or greater than {y_max}," + f" but got {win_ascent} instead") + if win_ascent > y_max * 2: + failed = True + yield FAIL,\ + Message("ascent", + f"OS/2.usWinAscent value" + f" {win_ascent} is too large." + f" It should be less than double the yMax." + f" Current yMax value is {y_max}") + # OS/2 usWinDescent: + if win_descent < abs(y_min): + failed = True + yield FAIL,\ + Message("descent", + f"OS/2.usWinDescent value should be equal or" + f" greater than {abs(y_min)}, but got" + f" {win_descent} instead.") + + if win_descent > abs(y_min) * 2: + failed = True + yield FAIL,\ + Message("descent", + f"OS/2.usWinDescent value" + f" {win_descent} is too large." + f" It should be less than double the yMin." + f" Current absolute yMin value is {abs(y_min)}") + if not failed: + yield PASS, "OS/2 usWinAscent & usWinDescent values look good!" + + +@check( + id = 'org.sil/check/os2_metrics_match_hhea', + rationale=""" + Based on com.google.fonts/check/os2_metrics_match_hhea but with the 'not is_cjk' condition removed + """ +) +def org_sil_check_os2_metrics_match_hhea(ttFont): + """Checking OS/2 Metrics match hhea Metrics.""" + + filename = os.path.basename(ttFont.reader.file.name) + + # Check both OS/2 and hhea are present. + missing_tables = False + + required = ["OS/2", "hhea"] + for key in required: + if key not in ttFont: + missing_tables = True + yield FAIL,\ + Message(f'lacks-{key}', + f"{filename} lacks a '{key}' table.") + + if missing_tables: + return + + # OS/2 sTypoAscender and sTypoDescender match hhea ascent and descent + if ttFont["OS/2"].sTypoAscender != ttFont["hhea"].ascent: + yield FAIL,\ + Message("ascender", + f"OS/2 sTypoAscender ({ttFont['OS/2'].sTypoAscender})" + f" and hhea ascent ({ttFont['hhea'].ascent})" + f" must be equal.") + elif ttFont["OS/2"].sTypoDescender != ttFont["hhea"].descent: + yield FAIL,\ + Message("descender", + f"OS/2 sTypoDescender ({ttFont['OS/2'].sTypoDescender})" + f" and hhea descent ({ttFont['hhea'].descent})" + f" must be equal.") + elif ttFont["OS/2"].sTypoLineGap != ttFont["hhea"].lineGap: + yield FAIL,\ + Message("lineGap", + f"OS/2 sTypoLineGap ({ttFont['OS/2'].sTypoLineGap})" + f" and hhea lineGap ({ttFont['hhea'].lineGap})" + f" must be equal.") + else: + yield PASS, ("OS/2.sTypoAscender/Descender values" + " match hhea.ascent/descent.") + +@check( + id = "org.sil/check/os2/use_typo_metrics", + rationale=""" + Based on com.google.fonts/check/os2/use_typo_metrics but with the 'not is_cjk' condition removed + """ + ) +def corg_sil_check_os2_fsselectionbit7(ttFonts): + """OS/2.fsSelection bit 7 (USE_TYPO_METRICS) is set in all fonts.""" + + bad_fonts = [] + for ttFont in ttFonts: + if not ttFont["OS/2"].fsSelection & (1 << 7): + bad_fonts.append(ttFont.reader.file.name) + + if bad_fonts: + yield FAIL,\ + Message('missing-os2-fsselection-bit7', + f"OS/2.fsSelection bit 7 (USE_TYPO_METRICS) was" + f"NOT set in the following fonts: {bad_fonts}.") + else: + yield PASS, "OK" + + +@check( + id = 'org.sil/check/vertical_metrics', +# conditions = ['not remote_styles'], + rationale=""" + Based on com.google.fonts/check/vertical_metrics but with the 'not is_cjk' condition removed + """ +) +def org_sil_check_vertical_metrics(ttFont): + """Check font follows the Google Fonts vertical metric schema""" + filename = os.path.basename(ttFont.reader.file.name) + + # Check necessary tables are present. + missing_tables = False + required = ["OS/2", "hhea", "head"] + for key in required: + if key not in ttFont: + missing_tables = True + yield FAIL,\ + Message(f'lacks-{key}', + f"{filename} lacks a '{key}' table.") + + if missing_tables: + return + + font_upm = ttFont['head'].unitsPerEm + font_metrics = { + 'OS/2.sTypoAscender': ttFont['OS/2'].sTypoAscender, + 'OS/2.sTypoDescender': ttFont['OS/2'].sTypoDescender, + 'OS/2.sTypoLineGap': ttFont['OS/2'].sTypoLineGap, + 'hhea.ascent': ttFont['hhea'].ascent, + 'hhea.descent': ttFont['hhea'].descent, + 'hhea.lineGap': ttFont['hhea'].lineGap, + 'OS/2.usWinAscent': ttFont['OS/2'].usWinAscent, + 'OS/2.usWinDescent': ttFont['OS/2'].usWinDescent + } + expected_metrics = { + 'OS/2.sTypoLineGap': 0, + 'hhea.lineGap': 0, + } + + failed = False + warn = False + + # Check typo metrics and hhea lineGap match our expected values + for k in expected_metrics: + if font_metrics[k] != expected_metrics[k]: + failed = True + yield FAIL,\ + Message(f'bad-{k}', + f'{k} is "{font_metrics[k]}" it should be {expected_metrics[k]}') + + hhea_sum = (font_metrics['hhea.ascent'] + + abs(font_metrics['hhea.descent']) + + font_metrics['hhea.lineGap']) / font_upm + + # Check the sum of the hhea metrics is not below 1.2 + # (120% of upm or 1200 units for 1000 upm font) + if hhea_sum < 1.2: + failed = True + yield FAIL,\ + Message('bad-hhea-range', + 'The sum of hhea.ascender+abs(hhea.descender)+hhea.lineGap ' + f'is {int(hhea_sum*font_upm)} when it should be at least {int(font_upm*1.2)}') + + # Check the sum of the hhea metrics is below 2.0 + elif hhea_sum > 2.0: + failed = True + yield FAIL,\ + Message('bad-hhea-range', + 'The sum of hhea.ascender+abs(hhea.descender)+hhea.lineGap ' + f'is {int(hhea_sum*font_upm)} when it should be at most {int(font_upm*2.0)}') + + # Check the sum of the hhea metrics is between 1.1-1.5x of the font's upm + elif hhea_sum > 1.5: + warn = True + yield WARN,\ + Message('bad-hhea-range', + "We recommend the absolute sum of the hhea metrics should be" + f" between 1.2-1.5x of the font's upm. This font has {hhea_sum}x ({int(hhea_sum*font_upm)})") + + if not failed and not warn: + yield PASS, 'Vertical metrics are good' + diff --git a/lib/silfont/fbtests/silttfchecks.py b/lib/silfont/fbtests/silttfchecks.py new file mode 100644 index 0000000..d38ab77 --- /dev/null +++ b/lib/silfont/fbtests/silttfchecks.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python +'''Checks to be imported by ttfchecks.py +Some checks based on examples from Font Bakery, copyright 2017 The Font Bakery Authors, licensed under the Apache 2.0 license''' +__url__ = 'http://github.com/silnrsi/pysilfont' +__copyright__ = 'Copyright (c) 2022 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.constants import NameID, PlatformID, WindowsEncodingID + +@check( + id = 'org.sil/check/name/version_format', + rationale = """ + Based on com.google.fonts/check/name/version_format but: + - Checks for two valid formats: + - Production: exactly 3 digits after decimal point + + + - Allows major version to be 0 + - Allows extra info after numbers, eg for beta or dev versions + """ +) +def org_sil_version_format(ttFont): + "Version format is correct in 'name' table?" + + from fontbakery.utils import get_name_entry_strings + import re + + failed = 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}"') + if not failed: + yield PASS, "Version format in NAME table entries is correct." + +@check( + id = 'org.sil/check/whitespace_widths' +) +def org_sil_whitespace_widths(ttFont): + """Checks with widths of space characters in the font against best practice""" + from fontbakery.utils import get_glyph_name + + allok = True + space_data = { + 0x0020: ['Space'], + 0x00A0: ['No-break space'], + 0x2008: ['Punctuation space'], + 0x2003: ['Em space'], + 0x2002: ['En space'], + 0x2000: ['En quad'], + 0x2001: ['Em quad'], + 0x2004: ['Three-per-em space'], + 0x2005: ['Four-per-em space'], + 0x2006: ['Six-per-em space'], + 0x2009: ['Thin space'], + 0x200A: ['Hair space'], + 0x202F: ['Narrow no-break space'], + 0x002E: ['Full stop'], # Non-space character where the width is needed for comparison + } + for sp in space_data: + spname = get_glyph_name(ttFont, sp) + if spname is None: + spwidth = None + else: + spwidth = ttFont['hmtx'][spname][0] + space_data[sp].append(spname) + space_data[sp].append(spwidth) + + # Other width info needed from the font + upm = ttFont['head'].unitsPerEm + fullstopw = space_data[46][2] + + # Widths used for comparisons + spw = space_data[32][2] + if spw is None: + allok = False + yield WARN, "No space in the font so No-break space (if present) can't be checked" + emw = space_data[0x2003][2] + if emw is None: + allok = False + yield WARN, f'No em space in the font. Will be assumed to be units per em ({upm}) for other checking' + emw = upm + enw = space_data[0x2002][2] + if enw is None: + allok = False + yield WARN, f'No en space in the font. Will be assumed to be 1/2 em space width ({emw/2}) for checking en quad (if present)' + enw = emw/2 + + # Now check all the specific space widths. Only check if the space exists in the font + def checkspace(spacechar, minwidth, maxwidth=None): + sdata = space_data[spacechar] + if sdata[1]: # Name is set to None if not in font + # Allow for width(s) not being integer (eg em/6) so test against rounding up or down + minw = int(minwidth) + if maxwidth: + maxw = int(maxwidth) + if maxwidth > maxw: maxw += 1 # Had been rounded down, so round up + else: + maxw = minw if minw == minwidth else minw +1 # Had been rounded down, so allow rounded up as well + charw = sdata[2] + if not(minw <= charw <= maxw): + return (f'Width of {sdata[0]} ({spacechar:#04x}) is {str(charw)}: ', minw, maxw) + return (None,0,0) + + # No-break space + (message, minw, maxw) = checkspace(0x00A0, spw) + if message: allok = False; yield FAIL, message + f"Should match width of space ({spw})" + # Punctuation space + (message, minw, maxw) = checkspace(0x2008, fullstopw) + if message: allok = False; yield FAIL, message + f"Should match width of full stop ({fullstopw})" + # Em space + (message, minw, maxw) = checkspace(0x2003, upm) + if message: allok = False; yield WARN, message + f"Should match units per em ({upm})" + # En space + (message, minw, maxw) = checkspace(0x2002, emw/2) + if message: + allok = False + widths = f'{minw}' if minw == maxw else f'{minw} or {maxw}' + yield WARN, message + f"Should be half the width of em ({widths})" + # En quad + (message, minw, maxw) = checkspace(0x2000, enw) + if message: allok = False; yield WARN, message + f"Should be the same width as en ({enw})" + # Em quad + (message, minw, maxw) = checkspace(0x2001, emw) + if message: allok = False; yield WARN, message + f"Should be the same width as em ({emw})" + # Three-per-em space + (message, minw, maxw) = checkspace(0x2004, emw/3) + if message: + allok = False + widths = f'{minw}' if minw == maxw else f'{minw} or {maxw}' + yield WARN, message + f"Should be 1/3 the width of em ({widths})" + # Four-per-em space + (message, minw, maxw) = checkspace(0x2005, emw/4) + if message: + allok = False + widths = f'{minw}' if minw == maxw else f'{minw} or {maxw}' + yield WARN, message + f"Should be 1/4 the width of em ({widths})", + # Six-per-em space + (message, minw, maxw) = checkspace(0x2006, emw/6) + if message: + allok = False + widths = f'{minw}' if minw == maxw else f'{minw} or {maxw}' + yield WARN, message + f"Should be 1/6 the width of em ({widths})", + # Thin space + (message, minw, maxw) = checkspace(0x2009, emw/6, emw/5) + if message: + allok = False + yield WARN, message + f"Should be between 1/6 and 1/5 the width of em ({minw} and {maxw})" + # Hair space + (message, minw, maxw) = checkspace(0x200A, + emw/16, emw/10) + if message: + allok = False + yield WARN, message + f"Should be between 1/16 and 1/10 the width of em ({minw} and {maxw})" + # Narrow no-break space + (message, minw, maxw) = checkspace(0x202F, + emw/6, emw/5) + if message: + allok = False + yield WARN, message + f"Should be between 1/6 and 1/5 the width of em ({minw} and {maxw})" + + if allok: + yield PASS, "Space widths all match expected values" + +@check( + id = 'org.sil/check/number_widths' +) +def org_sil_number_widths(ttFont, config): + """Check widths of latin digits 0-9 are equal and match that of figure space""" + from fontbakery.utils import get_glyph_name + + num_data = { + 0x0030: ['zero'], + 0x0031: ['one'], + 0x0032: ['two'], + 0x0033: ['three'], + 0x0034: ['four'], + 0x0035: ['five'], + 0x0036: ['six'], + 0x0037: ['seven'], + 0x0038: ['eight'], + 0x0039: ['nine'], + 0x2007: ['figurespace'] # Figure space should be the same as numerals + } + + fontnames = [] + for x in (ttFont['name'].names[1].string, ttFont['name'].names[2].string): + txt="" + for i in range(1,len(x),2): txt += x.decode()[i] + fontnames.append(txt) + + for num in num_data: + name = get_glyph_name(ttFont, num) + if name is None: + width = -1 # So different from Zero! + else: + width = ttFont['hmtx'][name][0] + num_data[num].append(name) + num_data[num].append(width) + + zerowidth = num_data[48][2] + if zerowidth ==-1: + yield FAIL, "No zero in font - remainder of check not run" + return + + # Check non-zero digits are present and have same width as zero + digitsdiff = "" + digitsmissing = "" + for i in range(49,58): + ndata = num_data[i] + width = ndata[2] + if width != zerowidth: + if width == -1: + digitsmissing += ndata[1] + " " + else: + digitsdiff += ndata[1] + " " + + # Check figure space + figuremess = "" + ndata = num_data[0x2007] + width = ndata[2] + if width != zerowidth: + if width == -1: + figuremess = "No figure space in font" + else: + figuremess = f'The width of figure space ({ndata[1]}) does not match the width of zero' + if digitsmissing or digitsdiff or figuremess: + if digitsmissing: yield FAIL, f"Digits missing: {digitsmissing}" + if digitsdiff: yield WARN, f"Digits with different width from Zero: {digitsdiff}" + if figuremess: yield WARN, figuremess + else: + yield PASS, "All number widths are OK" 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) |