Last active
November 23, 2021 22:35
-
-
Save typoman/ac5efa4e54c25de4cd9b0120522290a7 to your computer and use it in GitHub Desktop.
Append (transfer) a set of glyphs from one TTF font to another.
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
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