Skip to content

Instantly share code, notes, and snippets.

@frankrolf
Created July 24, 2026 15:18
Show Gist options
  • Select an option

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

Select an option

Save frankrolf/b9261aa8dda94fd2e2e0190481e1f2b5 to your computer and use it in GitHub Desktop.
Simple creation of accented glyphs in/for Fontra
'''
Command-line script to add accented glyphs to a UFO, based on glyph names and anchors existing in the font
ss_dummy.ufo
'''
from fontParts.fontshell import RFont
from fontTools import agl
def anchor_offset(base_anchor_name, base_glyph, mark_glyph):
'''
calculate the offset between anchor pairs in base- and mark glyph
'''
base_anchors = {anchor.name: anchor.position for anchor in base_glyph.anchors}
mark_anchors = {anchor.name: anchor.position for anchor in mark_glyph.anchors}
mark_anchor_name = f'_{base_anchor_name}'
if base_anchor_name in base_anchors and mark_anchor_name in mark_anchors:
base_position = base_anchors.get(base_anchor_name)
mark_position = mark_anchors.get(mark_anchor_name)
return base_position[0] - mark_position[0], base_position[1] - mark_position[1]
base_glyph_names = 'abcdefghijklmnopqrstuvwxyz'
mark_glyph_names = [
'gravecmb', 'acutecmb', 'circumflexcmb', 'tildecmb', 'macroncmb',
'brevecmb', 'dotaccentcmb', 'dieresiscmb', 'ringcmb', 'hungarumlautcmb',
'caroncmb', 'commabelowcmb', 'cedillacmb', 'ogonekcmb']
anchor_names = ['aboveLC', 'belowLC', 'ogonek']
# dictionary of glyph names to code points
agl2uv = agl.AGL2UV
f = RFont('ss_dummy.ufo')
for base_name in base_glyph_names:
base_glyph = f[base_name]
for mark_name in mark_glyph_names:
mark_glyph = f[mark_name]
g_name = f'{base_name}{mark_name.replace("cmb", "")}'
codepoint = agl2uv.get(g_name, None)
if codepoint and g_name not in f.keys():
for anchor_name in anchor_names:
offset = anchor_offset(anchor_name, base_glyph, mark_glyph)
if offset:
ng = f.newGlyph(g_name)
ng.unicode = codepoint
ng.appendComponent(base_name)
ng.appendComponent(mark_name, offset)
ng.width = base_glyph.width
# this even will refresh the open font in Fontra
f.save()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment