summaryrefslogtreecommitdiffstats
path: root/lib/silfont/fbtests/silnotcjk.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/silfont/fbtests/silnotcjk.py')
-rw-r--r--lib/silfont/fbtests/silnotcjk.py230
1 files changed, 230 insertions, 0 deletions
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'
+