Skip to content

Instantly share code, notes, and snippets.

@typoman
Last active November 23, 2021 22:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save typoman/ac5efa4e54c25de4cd9b0120522290a7 to your computer and use it in GitHub Desktop.
Save typoman/ac5efa4e54c25de4cd9b0120522290a7 to your computer and use it in GitHub Desktop.
Append (transfer) a set of glyphs from one TTF font to another.
from fontTools.ttLib import TTFont
import argparse
import os
import sys
"""
Transfer glyphs from one set of fonts from soucre dir to target dir.
The file names should match and fonts should be ttf. This script does
not transfer kerning, marks or substitutions in the features. Usage:
python append_glyphs.py -h
"""
def transferGlyphs(source_dir, target_dir, new_glyphs):
source_paths = {}
for e in os.scandir(source_dir):
if e.is_file() and e.path.endswith(".ttf"):
source_paths[e.name] = e.path
transfer_font_dic = {} # source -> target
for e in os.scandir(target_dir):
if e.is_file() and e.path.endswith(".ttf") and e.name in source_paths:
source_path = source_paths[e.name]
transfer_font_dic[source_path] = e
target_save_folder = target_dir+'/'+'glyphs_added'
if not os.path.exists(target_save_folder):
os.makedirs(target_save_folder)
for sp, tp in transfer_font_dic.items():
sf = TTFont(sp)
tf = TTFont(tp.path)
tgt_glyphOrder = tf.getGlyphOrder()
src_glyphOrder = sf.getGlyphOrder()
for g in new_glyphs:
if g not in src_glyphOrder:
print(f"{g} not in in the source font:\n{sp}")
tgt_glyphOrder.append(g)
tf.setGlyphOrder(src_glyphOrder)
src_reversedCmap = sf["cmap"].buildReversed()
for g in new_glyphs:
tf["hmtx"].metrics[g] = sf["hmtx"].metrics[g]
for subtable in tf["cmap"].tables:
if subtable.isUnicode():
for codepoint in src_reversedCmap[g]:
subtable.cmap[codepoint] = g
tf["glyf"][g] = sf["glyf"][g]
name = tp.name
tf.save(target_save_folder+"/"+name)
def main(args=None):
if args is None:
args = sys.argv[1:]
parser = argparse.ArgumentParser(description="Transfer glyphs from one set of fonts (TTFs) from soucre dir to target dir. The file names of every pair font should match in the soruce and target dir. This script might not work as expected if the fonts contain hinting. This script does not transfer kerning, marks or substitutions in the features. The result will be saved in the target folder in sub dir folder named 'glyphs_added'.\nFor example: python3 append_glyphs.py Changed Original 'Udieresis udieresis'")
parser.add_argument("Source", help="Path to the dir which contains the font(s) you want to extract the glyphs from (enclosed in '').", default=os.getcwd(), type=str)
parser.add_argument("Target", help="Path to the dir which contains the font(s) you want to append the glyphs to (enclosed in '').", type=str)
parser.add_argument("Glyphs", help="Glyph names you want to transfer seperated by space and enclosed in ''", type=str)
args = parser.parse_args(args)
transferGlyphs(args.Source, args.Target, args.Glyphs.split(" "))
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment