1#! /usr/bin/env python3 2 3from fontTools.ttLib import TTFont 4import sys 5 6if len(sys.argv) < 2: 7 print("usage: subset-fpgm.py fontfile.ttf func-number...") 8 sys.exit(1) 9fontfile = sys.argv[1] 10func_nums = [int(x) for x in sys.argv[2:]] 11 12font = TTFont(fontfile) 13fpgm = font['fpgm'] 14 15# Parse fpgm 16asm = fpgm.program.getAssembly() 17funcs = {} 18stack = [] 19tokens = iter(asm) 20for token in tokens: 21 if token.startswith("PUSH") or token.startswith("NPUSH"): 22 for token in tokens: 23 try: 24 num = int(token) 25 stack.append(num) 26 except ValueError: 27 break 28 if token.startswith("FDEF"): 29 num = stack.pop() 30 body = [] 31 for token in tokens: 32 if token.startswith("ENDF"): 33 break 34 body.append(token) 35 funcs[num] = body 36 continue 37 assert 0, "Unexpected token in fpgm: %s" % token 38 39# Subset! 40funcs = {i:funcs[i] for i in func_nums} 41 42# Put it back together: 43asm = [] 44if funcs: 45 asm.append("PUSH[ ]") 46nums = sorted(funcs.keys()) 47asm.extend(str(i) for i in nums) 48for i in nums: 49 asm.append("FDEF[ ]") 50 asm.extend(funcs[i]) 51 asm.append("ENDF[ ]") 52 53import pprint 54pprint.pprint(asm) 55 56fpgm.program.fromAssembly(asm) 57# Make sure it compiles 58fpgm.program.getBytecode() 59