from time import time from defcon import Kerning, registerRepresentationFactory from mojo.subscriber import Subscriber, registerCurrentFontSubscriber FIRST_PREFIX = "public.kern1." SECOND_PREFIX = "public.kern2." class KerningGroupsWatcher(Subscriber): debug = True fontGroupsDidChangeDelay = 0 def fontGroupsDidChange(self, info): info["font"].kerning.changed() print("an edit to groups invalidates the kerning cache!") def flatKerningFactory(kerning): print("compute flat kerning!") flatK = {} font = kerning.font for pair, correction in kerning.items(): first, second = pair # both groups if first.startswith(FIRST_PREFIX) and second.startswith(SECOND_PREFIX): for firstGlyph in font.groups[first]: for secondGlyph in font.groups[second]: flatK[(firstGlyph, secondGlyph)] = correction # first group, second glyph elif first.startswith(FIRST_PREFIX): for firstGlyph in font.groups[first]: flatK[(firstGlyph, second)] = correction # first glyph, second group elif second.startswith(SECOND_PREFIX): for secondGlyph in font.groups[second]: flatK[(first, secondGlyph)] = correction # first glyph, second glyph else: flatK[(first, second)] = correction return flatK if __name__ == "__main__": registerCurrentFontSubscriber(KerningGroupsWatcher) registerRepresentationFactory(Kerning, "flatKerningRepresentation", flatKerningFactory) font = CurrentFont() # first computation start = time() flatKerning = font.kerning.getRepresentation("flatKerningRepresentation") end = time() print(end - start) print(len(flatKerning)) # retrieve the cache start = time() end = time() print(end - start) print(len(flatKerning)) # edit the groups font.groups[f"{FIRST_PREFIX}.someGroup"] = ["A", "B", "C"] # compute again start = time() flatKerning = font.kerning.getRepresentation("flatKerningRepresentation") end = time() print(end - start) print(len(flatKerning)) # remove the pseudo group del font.groups[f"{FIRST_PREFIX}.someGroup"]