1 2 3def lookupKerningValue(pair, kerning, groups, fallback=0, glyphToFirstGroup=None, glyphToSecondGroup=None): 4 """ 5 Note: This expects kerning to be a flat dictionary 6 of kerning pairs, not the nested structure used 7 in kerning.plist. 8 9 >>> groups = { 10 ... "public.kern1.O" : ["O", "D", "Q"], 11 ... "public.kern2.E" : ["E", "F"] 12 ... } 13 >>> kerning = { 14 ... ("public.kern1.O", "public.kern2.E") : -100, 15 ... ("public.kern1.O", "F") : -200, 16 ... ("D", "F") : -300 17 ... } 18 >>> lookupKerningValue(("D", "F"), kerning, groups) 19 -300 20 >>> lookupKerningValue(("O", "F"), kerning, groups) 21 -200 22 >>> lookupKerningValue(("O", "E"), kerning, groups) 23 -100 24 >>> lookupKerningValue(("O", "O"), kerning, groups) 25 0 26 >>> lookupKerningValue(("E", "E"), kerning, groups) 27 0 28 >>> lookupKerningValue(("E", "O"), kerning, groups) 29 0 30 >>> lookupKerningValue(("X", "X"), kerning, groups) 31 0 32 >>> lookupKerningValue(("public.kern1.O", "public.kern2.E"), 33 ... kerning, groups) 34 -100 35 >>> lookupKerningValue(("public.kern1.O", "F"), kerning, groups) 36 -200 37 >>> lookupKerningValue(("O", "public.kern2.E"), kerning, groups) 38 -100 39 >>> lookupKerningValue(("public.kern1.X", "public.kern2.X"), kerning, groups) 40 0 41 """ 42 # quickly check to see if the pair is in the kerning dictionary 43 if pair in kerning: 44 return kerning[pair] 45 # create glyph to group mapping 46 if glyphToFirstGroup is not None: 47 assert glyphToSecondGroup is not None 48 if glyphToSecondGroup is not None: 49 assert glyphToFirstGroup is not None 50 if glyphToFirstGroup is None: 51 glyphToFirstGroup = {} 52 glyphToSecondGroup = {} 53 for group, groupMembers in groups.items(): 54 if group.startswith("public.kern1."): 55 for glyph in groupMembers: 56 glyphToFirstGroup[glyph] = group 57 elif group.startswith("public.kern2."): 58 for glyph in groupMembers: 59 glyphToSecondGroup[glyph] = group 60 # get group names and make sure first and second are glyph names 61 first, second = pair 62 firstGroup = secondGroup = None 63 if first.startswith("public.kern1."): 64 firstGroup = first 65 first = None 66 else: 67 firstGroup = glyphToFirstGroup.get(first) 68 if second.startswith("public.kern2."): 69 secondGroup = second 70 second = None 71 else: 72 secondGroup = glyphToSecondGroup.get(second) 73 # make an ordered list of pairs to look up 74 pairs = [ 75 (first, second), 76 (first, secondGroup), 77 (firstGroup, second), 78 (firstGroup, secondGroup) 79 ] 80 # look up the pairs and return any matches 81 for pair in pairs: 82 if pair in kerning: 83 return kerning[pair] 84 # use the fallback value 85 return fallback 86 87if __name__ == "__main__": 88 import doctest 89 doctest.testmod() 90