11c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr"""\ 21c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrusage: ttx [options] inputfile1 [... inputfileN] 31c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 41c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr TTX %s -- From OpenType To XML And Back 51c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 61c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr If an input file is a TrueType or OpenType font file, it will be 71c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr dumped to an TTX file (an XML-based text format). 81c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr If an input file is a TTX file, it will be compiled to a TrueType 91c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr or OpenType font file. 101c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 111c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr Output files are created so they are unique: an existing file is 12ca75e43333c6e44e7732a9b2857b75adc74fff9apabs never overwritten. 131c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 141c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr General options: 151c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -h Help: print this message 161c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -d <outputfolder> Specify a directory where the output files are 171c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr to be created. 185f4193373befa02f329c0960f5167508de93d162pabs -o <outputfile> Specify a file to write the output to. 191c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -v Verbose: more messages will be written to stdout about what 201c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr is being done. 21b158597aea89fb178452da3787aacd8aa4e83d03Dave Crossland -q Quiet: No messages will be written to stdout about what 22b158597aea89fb178452da3787aacd8aa4e83d03Dave Crossland is being done. 23823f8cd15f16bb9dc3991c2672f16dd90579711bjvr -a allow virtual glyphs ID's on compile or decompile. 241c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 251c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr Dump options: 261c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -l List table info: instead of dumping to a TTX file, list some 271c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr minimal info about each table. 281c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -t <table> Specify a table to dump. Multiple -t options 291c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr are allowed. When no -t option is specified, all tables 301c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr will be dumped. 311c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -x <table> Specify a table to exclude from the dump. Multiple 321c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -x options are allowed. -t and -x are mutually exclusive. 331c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -s Split tables: save the TTX data into separate TTX files per 341c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr table and write one small TTX file that contains references 351c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr to the individual table dumps. This file can be used as 361c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr input to ttx, as long as the table files are in the 371c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr same directory. 381c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -i Do NOT disassemble TT instructions: when this option is given, 391c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr all TrueType programs (glyph programs, the font program and the 401c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr pre-program) will be written to the TTX file as hex data 411c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr instead of assembly. This saves some time and makes the TTX 421c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr file smaller. 437baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine -z <format> Specify a bitmap data export option for EBDT: 447baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine {'raw', 'row', 'bitwise', 'extfile'} or for the CBDT: 457baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine {'raw', 'extfile'} Each option does one of the following: 467baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine -z raw 477baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine * export the bitmap data as a hex dump 487baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine -z row 497baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine * export each row as hex data 507baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine -z bitwise 517baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine * export each row as binary in an ASCII art style 527baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine -z extfile 537baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine * export the data as external files with XML refences 547baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine If no export format is specified 'raw' format is used. 551bcc11dcf63e4431d1526342ecf6b70476161765jvr -e Don't ignore decompilation errors, but show a full traceback 561bcc11dcf63e4431d1526342ecf6b70476161765jvr and abort. 570a6dea0ac2125a4a26c2836a5f183fbdfbdb5e9bpabs -y <number> Select font number for TrueType Collection, 587e91e776c9d10d3b295de06ee7f665d8106306d8pabs starting from 0. 591c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 601c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr Compile options: 611c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr -m Merge with TrueType-input-file: specify a TrueType or OpenType 621c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr font file to be merged with the TTX file. This option is only 631c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr valid when at most one TTX file is specified. 64ca75e43333c6e44e7732a9b2857b75adc74fff9apabs -b Don't recalc glyph bounding boxes: use the values in the TTX 651c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr file as-is. 661c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr""" 671c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 681c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 691ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import 7030e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import * 7170343cc48edccce851026f569997d833bc5af6bfOlivier Bertenfrom fontTools.ttLib import TTFont, TTLibError 7245d1f3b3b552297484bc2b8e9a2e999630bb5e50jvrfrom fontTools.misc.macCreatorType import getMacCreatorAndType 7330e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodimport os 7430e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodimport sys 7530e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodimport getopt 7630e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodimport re 771c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 781c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef usage(): 79153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod from fontTools import version 803ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(__doc__ % version) 811c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr sys.exit(2) 821c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 832e838ce7666b9ae1d24a57d598ca4379dce90719jvr 84eac107f11fa10cabc633d703ddaa8f3ffc655cacBehdad EsfahbodnumberAddedRE = re.compile("#\d+$") 85278d4d8ceab8b7833831c18007cfdc32b9501bbcpabsopentypeheaderRE = re.compile('''sfntVersion=['"]OTTO["']''') 861c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 871c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef makeOutputFileName(input, outputDir, extension): 88153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod dirName, fileName = os.path.split(input) 89153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod fileName, ext = os.path.splitext(fileName) 901c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if outputDir: 91153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod dirName = outputDir 92153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod fileName = numberAddedRE.split(fileName)[0] 93153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod output = os.path.join(dirName, fileName + extension) 941c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr n = 1 951c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr while os.path.exists(output): 96153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod output = os.path.join(dirName, fileName + "#" + repr(n) + extension) 971c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr n = n + 1 981c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr return output 991c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 1001c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 101e388db566b9ba42669c7e353db4293cf27bc2a5bBehdad Esfahbodclass Options(object): 1021c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 10338fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod listTables = False 1041c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr outputDir = None 105fb37a24708fbd6065ce40d563837759076fd5206pabs outputFile = None 10638fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod verbose = False 10738fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod quiet = False 10838fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod splitTables = False 10938fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod disassembleInstructions = True 1101c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr mergeFile = None 11138fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod recalcBBoxes = True 11238fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod allowVID = False 1131bcc11dcf63e4431d1526342ecf6b70476161765jvr ignoreDecompileErrors = True 1147baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine bitmapGlyphDataFormat = 'raw' 1151bcc11dcf63e4431d1526342ecf6b70476161765jvr 1161c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr def __init__(self, rawOptions, numFiles): 1171c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr self.onlyTables = [] 1181c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr self.skipTables = [] 1197e91e776c9d10d3b295de06ee7f665d8106306d8pabs self.fontNumber = -1 1201c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr for option, value in rawOptions: 1211c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr # general options 1221c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if option == "-h": 123153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod from fontTools import version 1243ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(__doc__ % version) 1251c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr sys.exit(0) 1261c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif option == "-d": 1271c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if not os.path.isdir(value): 1283ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print("The -d option value must be an existing directory") 1291c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr sys.exit(2) 1301c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr self.outputDir = value 131fb37a24708fbd6065ce40d563837759076fd5206pabs elif option == "-o": 132fb37a24708fbd6065ce40d563837759076fd5206pabs self.outputFile = value 1331c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif option == "-v": 13438fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod self.verbose = True 135b158597aea89fb178452da3787aacd8aa4e83d03Dave Crossland elif option == "-q": 13638fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod self.quiet = True 1371c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr # dump options 1381c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif option == "-l": 13938fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod self.listTables = True 1401c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif option == "-t": 1411c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr self.onlyTables.append(value) 1421c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif option == "-x": 1431c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr self.skipTables.append(value) 1441c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif option == "-s": 14538fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod self.splitTables = True 1461c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif option == "-i": 14738fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod self.disassembleInstructions = False 1487baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine elif option == "-z": 1497baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine validOptions = ('raw', 'row', 'bitwise', 'extfile') 1507baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine if value not in validOptions: 1513ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print("-z does not allow %s as a format. Use %s" % (option, validOptions)) 1527baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine sys.exit(2) 1537baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine self.bitmapGlyphDataFormat = value 1547e91e776c9d10d3b295de06ee7f665d8106306d8pabs elif option == "-y": 1557e91e776c9d10d3b295de06ee7f665d8106306d8pabs self.fontNumber = int(value) 1561c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr # compile options 1571c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif option == "-m": 1581c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr self.mergeFile = value 1591c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif option == "-b": 16038fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod self.recalcBBoxes = False 161823f8cd15f16bb9dc3991c2672f16dd90579711bjvr elif option == "-a": 16238fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod self.allowVID = True 1631bcc11dcf63e4431d1526342ecf6b70476161765jvr elif option == "-e": 1641bcc11dcf63e4431d1526342ecf6b70476161765jvr self.ignoreDecompileErrors = False 1651c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if self.onlyTables and self.skipTables: 1663ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print("-t and -x options are mutually exclusive") 1671c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr sys.exit(2) 1681c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if self.mergeFile and numFiles > 1: 1693ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print("Must specify exactly one TTX source file when using -m") 1701c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr sys.exit(2) 1711c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 1721c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 1731c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef ttList(input, output, options): 174188f2a398a8b50f1656a099f6a609a085c60eaabBehdad Esfahbod ttf = TTFont(input, fontNumber=options.fontNumber, lazy=True) 1751c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr reader = ttf.reader 176ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod tags = sorted(reader.keys()) 1773ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print('Listing table info for "%s":' % input) 1781c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr format = " %4s %10s %7s %7s" 1793ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(format % ("tag ", " checksum", " length", " offset")) 1803ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(format % ("----", "----------", "-------", "-------")) 1811c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr for tag in tags: 1821c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr entry = reader.tables[tag] 1837cc6d271ac955782d730161b27e728001fb5f347Behdad Esfahbod checkSum = int(entry.checkSum) 184e0912bb8197237fbfb926fdef042c198c58c2d72jvr if checkSum < 0: 185ecbe4c87b5b4b57ee965c3f9c0302cb4044a6875Behdad Esfahbod checkSum = checkSum + 0x100000000 18614fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod checksum = "0x%08X" % checkSum 1873ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(format % (tag, checksum, entry.length, entry.offset)) 1883ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print() 1891c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr ttf.close() 1901c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 1911c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 1921c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef ttDump(input, output, options): 193b158597aea89fb178452da3787aacd8aa4e83d03Dave Crossland if not options.quiet: 1943ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print('Dumping "%s" to "%s"...' % (input, output)) 1951bcc11dcf63e4431d1526342ecf6b70476161765jvr ttf = TTFont(input, 0, verbose=options.verbose, allowVID=options.allowVID, 196d7efd5692cac74702d487e641ca7ddf9c6cfececDave Crossland quiet=options.quiet, 1977e91e776c9d10d3b295de06ee7f665d8106306d8pabs ignoreDecompileErrors=options.ignoreDecompileErrors, 1987e91e776c9d10d3b295de06ee7f665d8106306d8pabs fontNumber=options.fontNumber) 1991c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr ttf.saveXML(output, 20038fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod quiet=options.quiet, 2011c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr tables=options.onlyTables, 20238fdae6342ae5339fbd148ef920f16291aa1e259Behdad Esfahbod skipTables=options.skipTables, 2031c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr splitTables=options.splitTables, 2047baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine disassembleInstructions=options.disassembleInstructions, 2057baa13689c6263f3ab152f77ab2c9f9c83398dc4Matt Fontaine bitmapGlyphDataFormat=options.bitmapGlyphDataFormat) 2061c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr ttf.close() 2071c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2081c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2091c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef ttCompile(input, output, options): 21085af40e7d8c4f4f4a3df3562a5ec9e5731cfe43fDave Crossland if not options.quiet: 2113ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print('Compiling "%s" to "%s"...' % (input, output)) 2121c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr ttf = TTFont(options.mergeFile, 2131c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr recalcBBoxes=options.recalcBBoxes, 214823f8cd15f16bb9dc3991c2672f16dd90579711bjvr verbose=options.verbose, allowVID=options.allowVID) 21585af40e7d8c4f4f4a3df3562a5ec9e5731cfe43fDave Crossland ttf.importXML(input, quiet=options.quiet) 21695f795f40a5d75c2c14c03c1b74cf1ee8816dbf8Behdad Esfahbod ttf.save(output) 2171c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2181c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if options.verbose: 2191c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr import time 2203ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print("finished at", time.strftime("%H:%M:%S", time.localtime(time.time()))) 2211c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2221c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2231c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef guessFileType(fileName): 2242e838ce7666b9ae1d24a57d598ca4379dce90719jvr base, ext = os.path.splitext(fileName) 2251c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr try: 2261c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr f = open(fileName, "rb") 2271c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr except IOError: 2281c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr return None 22945d1f3b3b552297484bc2b8e9a2e999630bb5e50jvr cr, tp = getMacCreatorAndType(fileName) 23045d1f3b3b552297484bc2b8e9a2e999630bb5e50jvr if tp in ("sfnt", "FFIL"): 23145d1f3b3b552297484bc2b8e9a2e999630bb5e50jvr return "TTF" 23245d1f3b3b552297484bc2b8e9a2e999630bb5e50jvr if ext == ".dfont": 23345d1f3b3b552297484bc2b8e9a2e999630bb5e50jvr return "TTF" 2341c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr header = f.read(256) 235ac4672e4510a79a56c4983ad28b42724c30ea9d1Behdad Esfahbod head = Tag(header[:4]) 2361c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if head == "OTTO": 2371c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr return "OTF" 2387e91e776c9d10d3b295de06ee7f665d8106306d8pabs elif head == "ttcf": 2397e91e776c9d10d3b295de06ee7f665d8106306d8pabs return "TTC" 2401c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif head in ("\0\1\0\0", "true"): 2411c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr return "TTF" 242ac4672e4510a79a56c4983ad28b42724c30ea9d1Behdad Esfahbod elif head == "wOFF": 2438c352398538a366c28c3d36c2395b855b421e633Behdad Esfahbod return "WOFF" 2441c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif head.lower() == "<?xm": 245c076261598611984c44ba3346c8aa5bf140dfce9Behdad Esfahbod # Use 'latin1' because that can't fail. 246c076261598611984c44ba3346c8aa5bf140dfce9Behdad Esfahbod header = tostr(header, 'latin1') 247eac107f11fa10cabc633d703ddaa8f3ffc655cacBehdad Esfahbod if opentypeheaderRE.search(header): 2481c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr return "OTX" 2491c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr else: 2501c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr return "TTX" 2511c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr return None 2521c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2531c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2541c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef parseOptions(args): 2551c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr try: 2565ffb91eb8c7e4350eb76409d29c8a3e6a24cdfbfDave Crossland rawOptions, files = getopt.getopt(args, "ld:o:vqht:x:sim:z:baey:") 2571c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr except getopt.GetoptError: 2581c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr usage() 2591c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2601c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if not files: 2611c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr usage() 2621c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2631c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr options = Options(rawOptions, len(files)) 2641c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr jobs = [] 2651c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2661c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr for input in files: 2671c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr tp = guessFileType(input) 2688c352398538a366c28c3d36c2395b855b421e633Behdad Esfahbod if tp in ("OTF", "TTF", "TTC", "WOFF"): 2691c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr extension = ".ttx" 2701c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if options.listTables: 2711c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr action = ttList 2721c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr else: 2731c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr action = ttDump 2741c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif tp == "TTX": 2751c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr extension = ".ttf" 2761c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr action = ttCompile 2771c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr elif tp == "OTX": 2781c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr extension = ".otf" 2791c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr action = ttCompile 2801c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr else: 2813ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print('Unknown file type: "%s"' % input) 2821c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr continue 2831c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 284fb37a24708fbd6065ce40d563837759076fd5206pabs if options.outputFile: 285fb37a24708fbd6065ce40d563837759076fd5206pabs output = options.outputFile 286fb37a24708fbd6065ce40d563837759076fd5206pabs else: 287fb37a24708fbd6065ce40d563837759076fd5206pabs output = makeOutputFileName(input, options.outputDir, extension) 2881c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr jobs.append((action, input, output)) 2892921bb25cd89f665bafb166b38b83baab5c1bd38jvr return jobs, options 2901c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2911c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2921c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef process(jobs, options): 2931c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr for action, input, output in jobs: 2941c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr action(input, output, options) 2951c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2961c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 2971c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef waitForKeyPress(): 2981c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr """Force the DOS Prompt window to stay open so the user gets 2991c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr a chance to see what's wrong.""" 3001c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr import msvcrt 3013ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print('(Hit any key to exit)') 3021c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr while not msvcrt.kbhit(): 3031c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr pass 3041c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 3051c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 3061c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrdef main(args): 3071c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr jobs, options = parseOptions(args) 3081c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr try: 3091c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr process(jobs, options) 3101c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr except KeyboardInterrupt: 3113ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print("(Cancelled.)") 3121c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr except SystemExit: 3131c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if sys.platform == "win32": 3141c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr waitForKeyPress() 3151c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr else: 3161c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr raise 317223273f7923ef25e8b697b378a4b89ab1f88674fBehdad Esfahbod except TTLibError as e: 3183ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print("Error:",e) 3191c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr except: 3201c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr if sys.platform == "win32": 3211c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr import traceback 3221c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr traceback.print_exc() 3231c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr waitForKeyPress() 3241c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr else: 3251c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr raise 3261c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 3271c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr 3281c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvrif __name__ == "__main__": 3291c803b6988cf7d93a5fbf9de3c90917cf315e1dbjvr main(sys.argv[1:]) 330