Skip to content

Instantly share code, notes, and snippets.

@gferreira
Last active January 28, 2022 17:48
Show Gist options
  • Save gferreira/56e4f13b7f104ec4ff69fb90d402dfe1 to your computer and use it in GitHub Desktop.
Save gferreira/56e4f13b7f104ec4ff69fb90d402dfe1 to your computer and use it in GitHub Desktop.
fixes fonts with Italic Angle but no Italic Slant Offset
import math
### updated version of a script by Lukas Schneider, available from the RoboFont documentation:
### http://robofont.com/documentation/tutorials/making-italic-fonts/#applying-the-italic-slant-offset-after-drawing
### changes in this version:
### - handles all layers of all open fonts
### - fixed syntax for FontParts / RoboFont 3
'''
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(layer):
flippedComponents = []
for g in layer:
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):
for layerName in font.layerOrder:
layer = font.getLayer(layerName)
# calculate offset value with baseGlyph
baseLeftMargin = (layer[baseGlyph].angledLeftMargin + layer[baseGlyph].angledRightMargin) / 2.0
offset = -layer[baseGlyph].angledLeftMargin + baseLeftMargin
# round offset value
if roundOffset and offset != 0:
offset = round(offset)
# get flipped components
flippedComponents = getFlippedComponents(layer)
# apply offset to all glyphs in font
if offset and layer[baseGlyph].angledLeftMargin and len(layer.keys()):
# get reverse components dict
componentMap = layer.getReverseComponentMapping()
# apply offset to all glyphs in font
for glyphName in layer.keys():
layer[glyphName].prepareUndo()
layer[glyphName].moveBy((offset, 0))
layer[glyphName].performUndo()
# if the glyph is used as a component, revert component offset
for composedGlyph in componentMap.get(glyphName, []):
for component in layer[composedGlyph].components:
if component.baseGlyph == glyphName:
# make sure it's not a flipped component
if glyphName not in flippedComponents:
component.moveBy((-offset, 0))
# done with glyph
layer[glyphName].changed()
# fix flipped components
for glyphName in flippedComponents:
for component in layer[glyphName].components:
# offset flipped components twice:
# baseGlyph offset + offset in the wrong direction
component.moveBy((offset*2, 0))
# fix glyphs which use the flipped component as a component
for composedGlyph in componentMap.get(glyphName, []):
for component in layer[composedGlyph].components:
if component.baseGlyph == glyphName:
component.moveBy((-offset, 0))
# done with glyph
layer[glyphName].changed()
# --------------
# run the script
# --------------
for font in AllFonts():
# base glyph for offset calculation (the glyph that should be centered)
baseGlyphName = '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, baseGlyphName, roundOffset)
@LenaLP
Copy link

LenaLP commented Jan 28, 2022

on line 77 I think this sign is not supposed to be here { ?

@gferreira
Copy link
Author

fixed. thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment