1*e1fe3e4aSElliott Hughes#!/usr/bin/env python3 2*e1fe3e4aSElliott Hughes 3*e1fe3e4aSElliott Hughesimport argparse 4*e1fe3e4aSElliott Hughesimport logging 5*e1fe3e4aSElliott Hughesimport os 6*e1fe3e4aSElliott Hughesimport sys 7*e1fe3e4aSElliott Hughes 8*e1fe3e4aSElliott Hughesfrom fontTools.ttLib import TTFont 9*e1fe3e4aSElliott Hughes 10*e1fe3e4aSElliott Hughes 11*e1fe3e4aSElliott Hughesdef ProcessTable(table): 12*e1fe3e4aSElliott Hughes found = set() 13*e1fe3e4aSElliott Hughes 14*e1fe3e4aSElliott Hughes for rec in table.ScriptList.ScriptRecord: 15*e1fe3e4aSElliott Hughes if rec.ScriptTag == "DFLT" and rec.Script.LangSysCount != 0: 16*e1fe3e4aSElliott Hughes tags = [r.LangSysTag for r in rec.Script.LangSysRecord] 17*e1fe3e4aSElliott Hughes logging.info( 18*e1fe3e4aSElliott Hughes "Removing %d extraneous LangSys records: %s", 19*e1fe3e4aSElliott Hughes rec.Script.LangSysCount, 20*e1fe3e4aSElliott Hughes " ".join(tags), 21*e1fe3e4aSElliott Hughes ) 22*e1fe3e4aSElliott Hughes rec.Script.LangSysRecord = [] 23*e1fe3e4aSElliott Hughes rec.Script.LangSysCount = 0 24*e1fe3e4aSElliott Hughes found.update(tags) 25*e1fe3e4aSElliott Hughes 26*e1fe3e4aSElliott Hughes if not found: 27*e1fe3e4aSElliott Hughes logging.info("All fine") 28*e1fe3e4aSElliott Hughes return False 29*e1fe3e4aSElliott Hughes else: 30*e1fe3e4aSElliott Hughes for rec in table.ScriptList.ScriptRecord: 31*e1fe3e4aSElliott Hughes tags = set([r.LangSysTag for r in rec.Script.LangSysRecord]) 32*e1fe3e4aSElliott Hughes found -= tags 33*e1fe3e4aSElliott Hughes 34*e1fe3e4aSElliott Hughes if found: 35*e1fe3e4aSElliott Hughes logging.warning( 36*e1fe3e4aSElliott Hughes "Records are missing from non-DFLT scripts: %s", " ".join(found) 37*e1fe3e4aSElliott Hughes ) 38*e1fe3e4aSElliott Hughes return True 39*e1fe3e4aSElliott Hughes 40*e1fe3e4aSElliott Hughes 41*e1fe3e4aSElliott Hughesdef ProcessFont(font): 42*e1fe3e4aSElliott Hughes found = False 43*e1fe3e4aSElliott Hughes for tag in ("GSUB", "GPOS"): 44*e1fe3e4aSElliott Hughes if tag in font: 45*e1fe3e4aSElliott Hughes logging.info("Processing %s table", tag) 46*e1fe3e4aSElliott Hughes if ProcessTable(font[tag].table): 47*e1fe3e4aSElliott Hughes found = True 48*e1fe3e4aSElliott Hughes else: 49*e1fe3e4aSElliott Hughes # Unmark the table as loaded so that it is read from disk when 50*e1fe3e4aSElliott Hughes # writing the font, to avoid any unnecessary changes caused by 51*e1fe3e4aSElliott Hughes # decompiling then recompiling again. 52*e1fe3e4aSElliott Hughes del font.tables[tag] 53*e1fe3e4aSElliott Hughes 54*e1fe3e4aSElliott Hughes return found 55*e1fe3e4aSElliott Hughes 56*e1fe3e4aSElliott Hughes 57*e1fe3e4aSElliott Hughesdef ProcessFiles(filenames): 58*e1fe3e4aSElliott Hughes for filename in filenames: 59*e1fe3e4aSElliott Hughes logging.info("Processing %s", filename) 60*e1fe3e4aSElliott Hughes font = TTFont(filename) 61*e1fe3e4aSElliott Hughes name, ext = os.path.splitext(filename) 62*e1fe3e4aSElliott Hughes fixedname = name + ".fixed" + ext 63*e1fe3e4aSElliott Hughes if ProcessFont(font): 64*e1fe3e4aSElliott Hughes logging.info("Saving fixed font to %s\n", fixedname) 65*e1fe3e4aSElliott Hughes font.save(fixedname) 66*e1fe3e4aSElliott Hughes else: 67*e1fe3e4aSElliott Hughes logging.info("Font file is fine, nothing to fix\n") 68*e1fe3e4aSElliott Hughes 69*e1fe3e4aSElliott Hughes 70*e1fe3e4aSElliott Hughesdef main(): 71*e1fe3e4aSElliott Hughes parser = argparse.ArgumentParser(description="Fix LangSys records for DFLT script") 72*e1fe3e4aSElliott Hughes parser.add_argument( 73*e1fe3e4aSElliott Hughes "files", metavar="FILE", type=str, nargs="+", help="input font to process" 74*e1fe3e4aSElliott Hughes ) 75*e1fe3e4aSElliott Hughes parser.add_argument( 76*e1fe3e4aSElliott Hughes "-s", "--silent", action="store_true", help="suppress normal messages" 77*e1fe3e4aSElliott Hughes ) 78*e1fe3e4aSElliott Hughes 79*e1fe3e4aSElliott Hughes args = parser.parse_args() 80*e1fe3e4aSElliott Hughes 81*e1fe3e4aSElliott Hughes logformat = "%(levelname)s: %(message)s" 82*e1fe3e4aSElliott Hughes if args.silent: 83*e1fe3e4aSElliott Hughes logging.basicConfig(format=logformat, level=logging.DEBUG) 84*e1fe3e4aSElliott Hughes else: 85*e1fe3e4aSElliott Hughes logging.basicConfig(format=logformat, level=logging.INFO) 86*e1fe3e4aSElliott Hughes 87*e1fe3e4aSElliott Hughes ProcessFiles(args.files) 88*e1fe3e4aSElliott Hughes 89*e1fe3e4aSElliott Hughes 90*e1fe3e4aSElliott Hughesif __name__ == "__main__": 91*e1fe3e4aSElliott Hughes sys.exit(main()) 92