Skip to content

Instantly share code, notes, and snippets.

@frankrolf
Last active October 29, 2025 14:56
Show Gist options
  • Select an option

  • Save frankrolf/2c1c51ce2921c379667ed59df3dbd394 to your computer and use it in GitHub Desktop.

Select an option

Save frankrolf/2c1c51ce2921c379667ed59df3dbd394 to your computer and use it in GitHub Desktop.
'''
I never understand affine transformations, which is why I made this little
script here.
basic docs:
https://fonttools.readthedocs.io/en/latest/misc/transform.html
rf docs (explains how to convert normal operations (rotate, scale) to
affine transformations):
https://doc.robofont.com/documentation/topics/transformations/
great interactive visualization (use the slider):
https://bossmaths.com/matrices-4/
'''
f = CurrentFont()
g = CurrentGlyph()
transformations = [
# horizontal scale
# vertical shear
# horizontal shear
# vertical scale
# x translate
# y translate
(1, 0, 0, 1, 0, 0), # does nothing (100% scale)
(2, 0, 0, 2, 0, 0), # double size
(1, 0, 0, 1, 100, 50), # move by 100, 50
(.5, 0, 0, .5, 0, 0), # 50% proportional scale
(0, 1, -1, 0, 0, 0), # 90 degree rotation
(1, 0, 0, .25, 0, 0), # squooshed to 1/4 height
(1, 0, 0, -1, 0, 0), # mirrored on the x-axis
(0, 1, 1, 0, 0, 0), # diagonal flip
(-1, 0, 0, -1, 0, 0), # 180° rotation
(0, 1, -1, 0, 0, 0), # 270° rotation
(1, 0, 0.2, 1, 0, 0), # shear by 20% -- a kinda strong Italic
(1, 1, 0, 1, 0, 0), # vertical shear, horizontal handles turned 45°
]
if not g:
print('please select a glyph')
else:
for transformation in transformations:
# give the transformed glyph a reasonable name, and insert it
tr_name = repr(transformation).replace(' ', '')
gname = f'{g.name}_{tr_name}'
ng = g.copy()
ng.name = gname
ng.transformBy(transformation)
f.insertGlyph(ng)
# put the base glyph in the background
background = f.getLayer('background')
bg = g.copy()
bg.name = gname
background.insertGlyph(bg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment