Skip to content

Instantly share code, notes, and snippets.

@nathanielevan
Created March 25, 2023 01:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nathanielevan/72ad6df3e96d804f081ece6b65aa8f8d to your computer and use it in GitHub Desktop.
Save nathanielevan/72ad6df3e96d804f081ece6b65aa8f8d to your computer and use it in GitHub Desktop.
Python script to vertically center glyphs in a font
# Python script to vertically center a set of glyphs in a font.
# Requires fontforge python module.
# Credits to u/janKeTami here: https://www.reddit.com/r/FontForge/comments/11r6x4q/vertically_centering_glyphs/
# Slightly altered to enable this script to be run straight from the terminal using ttf/otf fonts
import re
import os
import argparse
try:
import psMat
import fontforge
except ImportError:
sys.exit("FontForge module not found")
folder = "patched"
try:
os.makedirs(folder)
except FileExistsError:
pass
parser = argparse.ArgumentParser(description="Vertically center glyphs in a font.")
parser.add_argument("file", help="Filename of font to be patched")
args = parser.parse_args()
# Change the start and end glyph to those you desire
# Example provided below is for 126, corresponding to tilde
startglyph = 126
endglyph = 126
thisfont = fontforge.open(args.file)
for i in range(startglyph,endglyph+1):
ytop = thisfont[i].boundingBox()[-1] # counted from baseline, excluding descent!
ybot = thisfont[i].boundingBox()[1] # same note as above
# Calculation method:
# Midpoint of entire space = (ascent + descent) / 2
# Current midpoint of glyph (counted from baseline) = (ytop + ybot) / 2
# Current midpoint of glyph (counted with descent) = (ytop + ybot) / 2 + descent
# Vertical translation = midpoint of entire space - current midpoint of glyph (counted with descent)
# That is: (ascent + descent) / 2 - ((ytop + ybot) / 2 + descent)
# Simplified: (ascent - descent - (ytop + ybot)) / 2
translation = (thisfont.ascent - thisfont.descent - (ytop + ybot)) / 2
thisfont[i].transform( psMat.translate( 0, translation ))
# This bit for flags and bitmaps is taken from Nerd Fonts' font-patcher script
# No idea if this is necessary, but just in case
if int(fontforge.version()) >= 20201107:
gen_flags = (str('opentype'), str('no-FFTM-table'))
else:
gen_flags = (str('opentype'))
bitmaps = str()
if len(thisfont.bitmapSizes):
print("Preserving bitmaps {}".format(thisfont.bitmapSizes))
bitmaps = str('otf') # otf/ttf, both is bf_ttf
splitfilename = args.file.rsplit('/', 1)
if len(splitfilename) > 1:
filename = splitfilename[1]
else:
filename = args.file
outfont = folder + "/" + filename
thisfont.generate(outfont, bitmap_type=bitmaps, flags=gen_flags)
print("Font patched successfully! Stored at {}".format(outfont))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment