Skip to content

Commit

Permalink
avoid using glyf __setitem__, call TTFont.setGlyphOrder at the end to…
Browse files Browse the repository at this point in the history
… rebuild gid cache
  • Loading branch information
anthrotype committed Apr 29, 2022
1 parent 1d4f01e commit d56f1b2
Showing 1 changed file with 16 additions and 13 deletions.
29 changes: 16 additions & 13 deletions src/nanoemoji/glue_together.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,20 @@ class CbdtGlyphInfo(NamedTuple):

def _copy_colr(target: ttLib.TTFont, donor: ttLib.TTFont):
# Copy all glyphs used by COLR over
_glyphs_to_copy = {
p.Glyph for p in paints_of_type(donor, ot.PaintFormat.PaintGlyph)
}

for glyph_name in sorted(_glyphs_to_copy):
target["glyf"][glyph_name] = donor["glyf"][glyph_name]
glyphs_to_copy = sorted(
{p.Glyph for p in paints_of_type(donor, ot.PaintFormat.PaintGlyph)}
)

# We avoid using the glyf table's `__setitem__` for it appends to the TTFont's
# glyphOrder list without also invalidating the {glyphNames:glyphID} cache,
# which means TTFont.getGlyphID could return incorrect result.
# Instead we set the new glyphs directly inside the glyf's `glyphs` dict and
# call TTFont.setGlyphOrder at the end, which automatically triggers a rebuild
# of glyphID cache.
# https://github.com/fonttools/fonttools/issues/2605
target_glyphs = target["glyf"].glyphs
for glyph_name in glyphs_to_copy:
target_glyphs[glyph_name] = donor["glyf"][glyph_name]

if glyph_name in target["hmtx"].metrics:
assert (
Expand All @@ -61,16 +69,11 @@ def _copy_colr(target: ttLib.TTFont, donor: ttLib.TTFont):
# new glyph, new metrics
target["hmtx"][glyph_name] = donor["hmtx"][glyph_name]

target.setGlyphOrder(target.getGlyphOrder() + glyphs_to_copy)

target["CPAL"] = donor["CPAL"]
target["COLR"] = donor["COLR"]

# Adding new glyphs to glyf table automatically appends to the TTFont's
# glyphOrder list, however the cached map from names to glyph IDs is not
# updated, so TTFont.getGlyphID will return incorrect result until
# we force it to be rebuilt, e.g. like so:
# https://github.com/fonttools/fonttools/issues/2605
target.getReverseGlyphMap(rebuild=True)


def _svg_glyphs(font: ttLib.TTFont) -> Iterable[Tuple[int, str]]:
for _, min_gid, max_gid in font["SVG "].docList:
Expand Down

0 comments on commit d56f1b2

Please sign in to comment.