set_overlaps.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. """Taken from https://github.com/google/fonts/issues/4405#issuecomment-1079185880"""
  2. from __future__ import annotations
  3. import argparse
  4. from typing import Any, Mapping
  5. import pathops
  6. from fontTools.ttLib import TTFont
  7. from fontTools.ttLib.removeOverlaps import componentsOverlap, skPathFromGlyph
  8. from fontTools.ttLib.tables import _g_l_y_f
  9. def set_overlap_bits_if_overlapping(varfont: TTFont) -> tuple[int, int]:
  10. glyph_set = varfont.getGlyphSet()
  11. glyf_table: _g_l_y_f.table__g_l_y_f = varfont["glyf"]
  12. flag_overlap_compound = _g_l_y_f.OVERLAP_COMPOUND
  13. flag_overlap_simple = _g_l_y_f.flagOverlapSimple
  14. overlapping_contours = 0
  15. overlapping_components = 0
  16. for glyph_name in glyf_table.keys():
  17. glyph = glyf_table[glyph_name]
  18. # Set OVERLAP_COMPOUND bit for compound glyphs
  19. if glyph.isComposite() and componentsOverlap(glyph, glyph_set):
  20. overlapping_components += 1
  21. glyph.components[0].flags |= flag_overlap_compound
  22. # Set OVERLAP_SIMPLE bit for simple glyphs
  23. elif glyph.numberOfContours > 0 and glyph_overlaps(glyph_name, glyph_set):
  24. overlapping_contours += 1
  25. glyph.flags[0] |= flag_overlap_simple
  26. return (overlapping_contours, overlapping_components)
  27. def glyph_overlaps(glyph_name: str, glyph_set: Mapping[str, Any]) -> bool:
  28. path = skPathFromGlyph(glyph_name, glyph_set)
  29. path2 = pathops.simplify(path, clockwise=path.clockwise) # remove overlaps
  30. if path != path2:
  31. return True
  32. return False
  33. parser = argparse.ArgumentParser()
  34. parser.add_argument("font", type=TTFont)
  35. parsed_args = parser.parse_args()
  36. font = parsed_args.font
  37. ocont, ocomp = set_overlap_bits_if_overlapping(font)
  38. num_glyphs = font["maxp"].numGlyphs
  39. ocont_p = ocont / num_glyphs
  40. ocomp_p = ocomp / num_glyphs
  41. print(
  42. font.reader.file.name,
  43. f"{num_glyphs} glyphs, {ocont} overlapping contours ({ocont_p:.2%}), {ocomp} overlapping components ({ocomp_p:.2%})",
  44. )
  45. font.save(font.reader.file.name)