Source code for fontbakery.profiles.hhea

from fontbakery.callable import check
from fontbakery.status import FAIL, PASS
from fontbakery.message import Message

# used to inform get_module_profile whether and how to create a profile
from fontbakery.fonts_profile import profile_factory  # noqa:F401 pylint:disable=W0611

profile_imports = [(".shared_conditions", ("glyph_metrics_stats", "is_ttf"))]

[docs]@check(id="", proposal="legacy:check/073") def com_google_fonts_check_maxadvancewidth(ttFont): """MaxAdvanceWidth is consistent with values in the Hmtx and Hhea tables?""" required_tables = {"hhea", "hmtx"} missing_tables = sorted(required_tables - set(ttFont.keys())) if missing_tables: for table_tag in missing_tables: yield FAIL, Message("lacks-table", f"Font lacks '{table_tag}' table.") return hhea_advance_width_max = ttFont["hhea"].advanceWidthMax hmtx_advance_width_max = None for g in ttFont["hmtx"].metrics.values(): if hmtx_advance_width_max is None: hmtx_advance_width_max = max(0, g[0]) else: hmtx_advance_width_max = max(g[0], hmtx_advance_width_max) if hmtx_advance_width_max != hhea_advance_width_max: yield FAIL, Message( "mismatch", f"AdvanceWidthMax mismatch:" f" expected {hmtx_advance_width_max} (from hmtx);" f" got {hhea_advance_width_max} (from hhea)", ) else: yield PASS, ( "MaxAdvanceWidth is consistent with values in the Hmtx and Hhea tables." )
[docs]@check( id="", rationale=""" Checks whether hhea.caretSlopeRise and hhea.caretSlopeRun match with post.italicAngle. For Upright fonts, you can set hhea.caretSlopeRise to 1 and hhea.caretSlopeRun to 0. For Italic fonts, you can set hhea.caretSlopeRise to head.unitsPerEm and calculate hhea.caretSlopeRun like this: round(math.tan( math.radians(-1 * font["post"].italicAngle)) * font["head"].unitsPerEm) This check allows for a 0.1° rounding difference between the Italic angle as calculated by the caret slope and post.italicAngle """, proposal="", ) def com_google_fonts_check_caret_slope(ttFont): """Check hhea.caretSlopeRise and hhea.caretSlopeRun""" import math postItalicAngle = ttFont["post"].italicAngle upm = ttFont["head"].unitsPerEm run = ttFont["hhea"].caretSlopeRun rise = ttFont["hhea"].caretSlopeRise if rise == 0: yield FAIL, Message( "zero-rise", "caretSlopeRise must not be zero. Set it to 1 for upright fonts.", ) return hheaItalicAngle = math.degrees(math.atan(-run / rise)) expectedCaretSlopeRun = round(math.tan(math.radians(-postItalicAngle)) * upm) if expectedCaretSlopeRun == 0: expectedCaretSlopeRise = 1 else: expectedCaretSlopeRise = upm print(postItalicAngle, hheaItalicAngle) if abs(postItalicAngle - hheaItalicAngle) > 0.1: yield FAIL, Message( "caretslope-mismatch", "hhea.caretSlopeRise and hhea.caretSlopeRun" " do not match with post.italicAngle.\n" f"Got: caretSlopeRise {ttFont['hhea'].caretSlopeRise}" f" and caretSlopeRun {ttFont['hhea'].caretSlopeRun}\n" f"Expected: caretSlopeRise {expectedCaretSlopeRise}" f" and caretSlopeRun {expectedCaretSlopeRun}", ) else: yield PASS, ( "hhea.caretSlopeRise and hhea.caretSlopeRun match with post.italicAngle." )