Created
March 25, 2023 01:37
-
-
Save nathanielevan/72ad6df3e96d804f081ece6b65aa8f8d to your computer and use it in GitHub Desktop.
Python script to vertically center glyphs in a font
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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