Skip to content

Instantly share code, notes, and snippets.

@chrissimpkins
Last active November 25, 2019 22:30
Show Gist options
  • Save chrissimpkins/1376fa84162142ceeeaa2ac8bf111e30 to your computer and use it in GitHub Desktop.
Save chrissimpkins/1376fa84162142ceeeaa2ac8bf111e30 to your computer and use it in GitHub Desktop.
Check coordinates in font glyphs vs. x and y Min + Max value definitions defined in the glyph header (glyf table)
#!/usr/bin/env python3
# ---------------------------------------------------------------------------
# Copyright 2019 Christopher Simpkins
# Apache License, v2.0
#
# Portions of this source file are derived from the
#
# `com.google.fonts/check/points_out_of_bounds`
#
# check in the Font Bakery project (https://github.com/googlefonts/fontbakery/)
# and used under the Apache License, v2.0
# -----------------------------------------------------------------------------
import os
import sys
from fontTools.ttLib import TTFont
def main(argv):
for fontpath in argv:
if not os.path.isfile(fontpath):
sys.stderr.write(
f"[ERROR] {fontpath} does not appear to be a path to a valid font file"
)
sys.exit(1)
tt = TTFont(fontpath)
glyf_table = tt["glyf"]
coord_bounds_error_list = []
for gname in glyf_table.keys():
glyph = tt["glyf"][gname]
coords = glyph.getCoordinates(glyf_table)[0]
message = ""
# derived from the tests performed in the Fontbakery
# com.google.fonts/check/points_out_of_bounds check
for x, y in coords:
if round(x) < glyph.xMin:
message = f"(comp: {glyph.isComposite()}) x value {x} < glyph xMin value {glyph.xMin} @ point ({x}, {y})"
coord_bounds_error_list.append((gname, x, y, message))
elif round(x) > glyph.xMax:
message = f"(comp: {glyph.isComposite()}) x value {x} > glyph xMax value {glyph.xMax} @ point ({x}, {y})"
coord_bounds_error_list.append((gname, x, y, message))
elif round(y) < glyph.yMin:
message = f"(comp: {glyph.isComposite()}) y value {y} < glyph yMin value {glyph.yMin} @ point ({x}, {y})"
coord_bounds_error_list.append((gname, x, y, message))
elif round(y) > glyph.yMax:
message = f"(comp: {glyph.isComposite()}) y value {y} > glyph yMax value {glyph.yMax} @ point ({x}, {y})"
coord_bounds_error_list.append((gname, x, y, message))
elif abs(x) > 32766:
message = f"(comp: {glyph.isComposite()}) x value {x} > 32766 @ point ({x}, {y})"
coord_bounds_error_list.append((gname, x, y, message))
elif abs(y) > 32766:
message = f"(comp: {glyph.isComposite()}) y value {y} > 32766 @ point ({x}, {y})"
coord_bounds_error_list.append((gname, x, y, message))
else:
pass
if len(coord_bounds_error_list) == 0:
print(f"[OK] No errors identified in '{fontpath}'")
else:
print(f"[RESULT] '{fontpath}'")
for err in coord_bounds_error_list:
# print glyph name and error message
print(f"{err[0]}: {err[3]}")
print(f"[END RESULT] '{fontpath}'\n")
if __name__ == "__main__":
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment