123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- """Taken from https://github.com/google/fonts/issues/4405#issuecomment-1079185880"""
- from __future__ import annotations
- import argparse
- from typing import Any, Mapping
- import pathops
- from fontTools.ttLib import TTFont
- from fontTools.ttLib.removeOverlaps import componentsOverlap, skPathFromGlyph
- from fontTools.ttLib.tables import _g_l_y_f
- def set_overlap_bits_if_overlapping(varfont: TTFont) -> tuple[int, int]:
- glyph_set = varfont.getGlyphSet()
- glyf_table: _g_l_y_f.table__g_l_y_f = varfont["glyf"]
- flag_overlap_compound = _g_l_y_f.OVERLAP_COMPOUND
- flag_overlap_simple = _g_l_y_f.flagOverlapSimple
- overlapping_contours = 0
- overlapping_components = 0
- for glyph_name in glyf_table.keys():
- glyph = glyf_table[glyph_name]
- # Set OVERLAP_COMPOUND bit for compound glyphs
- if glyph.isComposite() and componentsOverlap(glyph, glyph_set):
- overlapping_components += 1
- glyph.components[0].flags |= flag_overlap_compound
- # Set OVERLAP_SIMPLE bit for simple glyphs
- elif glyph.numberOfContours > 0 and glyph_overlaps(glyph_name, glyph_set):
- overlapping_contours += 1
- glyph.flags[0] |= flag_overlap_simple
- return (overlapping_contours, overlapping_components)
- def glyph_overlaps(glyph_name: str, glyph_set: Mapping[str, Any]) -> bool:
- path = skPathFromGlyph(glyph_name, glyph_set)
- path2 = pathops.simplify(path, clockwise=path.clockwise) # remove overlaps
- if path != path2:
- return True
- return False
- parser = argparse.ArgumentParser()
- parser.add_argument("font", type=TTFont)
- parsed_args = parser.parse_args()
- font = parsed_args.font
- ocont, ocomp = set_overlap_bits_if_overlapping(font)
- num_glyphs = font["maxp"].numGlyphs
- ocont_p = ocont / num_glyphs
- ocomp_p = ocomp / num_glyphs
- print(
- font.reader.file.name,
- f"{num_glyphs} glyphs, {ocont} overlapping contours ({ocont_p:.2%}), {ocomp} overlapping components ({ocomp_p:.2%})",
- )
- font.save(font.reader.file.name)
|