1*e1fe3e4aSElliott Hughes#! /usr/bin/env python3 2*e1fe3e4aSElliott Hughes 3*e1fe3e4aSElliott Hughes"""usage: ttroundtrip [options] font1 ... fontN 4*e1fe3e4aSElliott Hughes 5*e1fe3e4aSElliott Hughes Dump each TT/OT font as a TTX file, compile again to TTF or OTF 6*e1fe3e4aSElliott Hughes and dump again. Then do a diff on the two TTX files. Append problems 7*e1fe3e4aSElliott Hughes and diffs to a file called "report.txt" in the current directory. 8*e1fe3e4aSElliott Hughes This is only for testing FontTools/TTX, the resulting files are 9*e1fe3e4aSElliott Hughes deleted afterwards. 10*e1fe3e4aSElliott Hughes 11*e1fe3e4aSElliott Hughes This tool supports some of ttx's command line options (-i, -t 12*e1fe3e4aSElliott Hughes and -x). Specifying -t or -x implies ttx -m <originalfile> on 13*e1fe3e4aSElliott Hughes the way back. 14*e1fe3e4aSElliott Hughes""" 15*e1fe3e4aSElliott Hughes 16*e1fe3e4aSElliott Hughes 17*e1fe3e4aSElliott Hughesimport sys 18*e1fe3e4aSElliott Hughesimport os 19*e1fe3e4aSElliott Hughesimport tempfile 20*e1fe3e4aSElliott Hughesimport getopt 21*e1fe3e4aSElliott Hughesimport traceback 22*e1fe3e4aSElliott Hughesfrom fontTools import ttx 23*e1fe3e4aSElliott Hughes 24*e1fe3e4aSElliott Hughes 25*e1fe3e4aSElliott Hughesclass Error(Exception): 26*e1fe3e4aSElliott Hughes pass 27*e1fe3e4aSElliott Hughes 28*e1fe3e4aSElliott Hughes 29*e1fe3e4aSElliott Hughesdef usage(): 30*e1fe3e4aSElliott Hughes print(__doc__) 31*e1fe3e4aSElliott Hughes sys.exit(2) 32*e1fe3e4aSElliott Hughes 33*e1fe3e4aSElliott Hughes 34*e1fe3e4aSElliott Hughesdef roundTrip(ttFile1, options, report): 35*e1fe3e4aSElliott Hughes fn = os.path.basename(ttFile1) 36*e1fe3e4aSElliott Hughes xmlFile1 = tempfile.mkstemp(".%s.ttx1" % fn) 37*e1fe3e4aSElliott Hughes ttFile2 = tempfile.mkstemp(".%s" % fn) 38*e1fe3e4aSElliott Hughes xmlFile2 = tempfile.mkstemp(".%s.ttx2" % fn) 39*e1fe3e4aSElliott Hughes 40*e1fe3e4aSElliott Hughes try: 41*e1fe3e4aSElliott Hughes ttx.ttDump(ttFile1, xmlFile1, options) 42*e1fe3e4aSElliott Hughes if options.onlyTables or options.skipTables: 43*e1fe3e4aSElliott Hughes options.mergeFile = ttFile1 44*e1fe3e4aSElliott Hughes ttx.ttCompile(xmlFile1, ttFile2, options) 45*e1fe3e4aSElliott Hughes options.mergeFile = None 46*e1fe3e4aSElliott Hughes ttx.ttDump(ttFile2, xmlFile2, options) 47*e1fe3e4aSElliott Hughes 48*e1fe3e4aSElliott Hughes diffcmd = 'diff -U2 -I ".*modified value\|checkSumAdjustment.*" "%s" "%s"' % ( 49*e1fe3e4aSElliott Hughes xmlFile1, 50*e1fe3e4aSElliott Hughes xmlFile2, 51*e1fe3e4aSElliott Hughes ) 52*e1fe3e4aSElliott Hughes output = os.popen(diffcmd, "r", 1) 53*e1fe3e4aSElliott Hughes lines = [] 54*e1fe3e4aSElliott Hughes while True: 55*e1fe3e4aSElliott Hughes line = output.readline() 56*e1fe3e4aSElliott Hughes if not line: 57*e1fe3e4aSElliott Hughes break 58*e1fe3e4aSElliott Hughes sys.stdout.write(line) 59*e1fe3e4aSElliott Hughes lines.append(line) 60*e1fe3e4aSElliott Hughes if lines: 61*e1fe3e4aSElliott Hughes report.write( 62*e1fe3e4aSElliott Hughes "=============================================================\n" 63*e1fe3e4aSElliott Hughes ) 64*e1fe3e4aSElliott Hughes report.write(' "%s" differs after round tripping\n' % ttFile1) 65*e1fe3e4aSElliott Hughes report.write( 66*e1fe3e4aSElliott Hughes "-------------------------------------------------------------\n" 67*e1fe3e4aSElliott Hughes ) 68*e1fe3e4aSElliott Hughes report.writelines(lines) 69*e1fe3e4aSElliott Hughes else: 70*e1fe3e4aSElliott Hughes print("(TTX files are the same)") 71*e1fe3e4aSElliott Hughes finally: 72*e1fe3e4aSElliott Hughes for tmpFile in (xmlFile1, ttFile2, xmlFile2): 73*e1fe3e4aSElliott Hughes if os.path.exists(tmpFile): 74*e1fe3e4aSElliott Hughes os.remove(tmpFile) 75*e1fe3e4aSElliott Hughes 76*e1fe3e4aSElliott Hughes 77*e1fe3e4aSElliott Hughesdef main(args): 78*e1fe3e4aSElliott Hughes try: 79*e1fe3e4aSElliott Hughes rawOptions, files = getopt.getopt(args, "it:x:") 80*e1fe3e4aSElliott Hughes except getopt.GetoptError: 81*e1fe3e4aSElliott Hughes usage() 82*e1fe3e4aSElliott Hughes 83*e1fe3e4aSElliott Hughes if not files: 84*e1fe3e4aSElliott Hughes usage() 85*e1fe3e4aSElliott Hughes 86*e1fe3e4aSElliott Hughes with open("report.txt", "a+") as report: 87*e1fe3e4aSElliott Hughes options = ttx.Options(rawOptions, len(files)) 88*e1fe3e4aSElliott Hughes for ttFile in files: 89*e1fe3e4aSElliott Hughes try: 90*e1fe3e4aSElliott Hughes roundTrip(ttFile, options, report) 91*e1fe3e4aSElliott Hughes except KeyboardInterrupt: 92*e1fe3e4aSElliott Hughes print("(Cancelled)") 93*e1fe3e4aSElliott Hughes break 94*e1fe3e4aSElliott Hughes except: 95*e1fe3e4aSElliott Hughes print("*** round tripping aborted ***") 96*e1fe3e4aSElliott Hughes traceback.print_exc() 97*e1fe3e4aSElliott Hughes report.write( 98*e1fe3e4aSElliott Hughes "=============================================================\n" 99*e1fe3e4aSElliott Hughes ) 100*e1fe3e4aSElliott Hughes report.write(" An exception occurred while round tripping") 101*e1fe3e4aSElliott Hughes report.write(' "%s"\n' % ttFile) 102*e1fe3e4aSElliott Hughes traceback.print_exc(file=report) 103*e1fe3e4aSElliott Hughes report.write( 104*e1fe3e4aSElliott Hughes "-------------------------------------------------------------\n" 105*e1fe3e4aSElliott Hughes ) 106*e1fe3e4aSElliott Hughes 107*e1fe3e4aSElliott Hughes 108*e1fe3e4aSElliott Hughesmain(sys.argv[1:]) 109