import math ''' fixes fonts with Italic Angle but no Italic Slant Offset - calculates Italic Slant Offset based on Italic Angle and xHeight - offsets all glyphs accordingly based on a reference glyph ''' # --------- # functions # --------- def getFlippedComponents(font): flippedComponents = [] for g in font: for component in g.components: if component.naked().transformation: # flipped horizontal if component.naked().transformation[0] == -1: flippedComponents.append(g.name) # flipped vertical if component.naked().transformation[3] == -1: flippedComponents.append(g.name) return list(set(flippedComponents)) def offsetGlyphs(font, baseGlyph, roundOffset=False): # calculate offset value with baseGlyph baseLeftMargin = (font[baseGlyph].angledLeftMargin + font[baseGlyph].angledRightMargin) / 2.0 offset = -font[baseGlyph].angledLeftMargin + baseLeftMargin # round offset value if roundOffset and offset != 0: offset = round(offset) # get flipped components flippedComponents = getFlippedComponents(font) # apply offset to all glyphs in font if offset and font[baseGlyph].angledLeftMargin and len(font.keys()): # get reverse components dict componentMap = font.getReverseComponentMapping() # apply offset to all glyphs in font for glyphName in font.keys(): with font[glyphName].undo(): font[glyphName].move((offset, 0)) # if the glyph is used as a component, revert component offset for composedGlyph in componentMap.get(glyphName, []): for component in font[composedGlyph].components: if component.baseGlyph == glyphName: # make sure it's not a flipped component if glyphName not in flippedComponents: component.move((-offset, 0)) # done with glyph font[glyphName].update() # fix flipped components for glyphName in flippedComponents: for component in font[glyphName].components: # offset flipped components twice: # baseGlyph offset + offset in the wrong direction component.move((offset*2, 0)) # fix glyphs which use the flipped component as a component for composedGlyph in componentMap.get(glyphName, []): for component in font[composedGlyph].components: if component.baseGlyph == glyphName: component.move((-offset, 0)) # done with glyph font[glyphName].update() # -------------- # run the script # -------------- font = CurrentFont() # base glyph for offset calculation (the glyph that should be centered) baseGlyph = 'H' # round or not the horizontal offset roundOffset = False # calculate the italic slant offset italicSlantOffset = math.tan(font.info.italicAngle * math.pi / 180) * (font.info.xHeight * 0.5) # set the italic slant offset in font font.lib['com.typemytype.robofont.italicSlantOffset'] = round(italicSlantOffset) # offset all glyphs in font offsetGlyphs(font, baseGlyph, roundOffset)