1from argparse import RawTextHelpFormatter 2from textwrap import dedent 3 4from fontTools.ttLib import TTFont 5from fontTools.otlLib.optimize.gpos import compact, GPOS_COMPACT_MODE_DEFAULT 6 7def main(args=None): 8 """Optimize the layout tables of an existing font.""" 9 from argparse import ArgumentParser 10 from fontTools import configLogger 11 12 parser = ArgumentParser(prog="otlLib.optimize", description=main.__doc__, formatter_class=RawTextHelpFormatter) 13 parser.add_argument("font") 14 parser.add_argument( 15 "-o", metavar="OUTPUTFILE", dest="outfile", default=None, help="output file" 16 ) 17 parser.add_argument( 18 "--gpos-compact-mode", 19 help=dedent( 20 f"""\ 21 GPOS Lookup type 2 (PairPos) compaction mode: 22 0 = do not attempt to compact PairPos lookups; 23 1 to 8 = create at most 1 to 8 new subtables for each existing 24 subtable, provided that it would yield a 50%% file size saving; 25 9 = create as many new subtables as needed to yield a file size saving. 26 Default: {GPOS_COMPACT_MODE_DEFAULT}. 27 28 This compaction aims to save file size, by splitting large class 29 kerning subtables (Format 2) that contain many zero values into 30 smaller and denser subtables. It's a trade-off between the overhead 31 of several subtables versus the sparseness of one big subtable. 32 33 See the pull request: https://github.com/fonttools/fonttools/pull/2326 34 """ 35 ), 36 default=int(GPOS_COMPACT_MODE_DEFAULT), 37 choices=list(range(10)), 38 type=int, 39 ) 40 logging_group = parser.add_mutually_exclusive_group(required=False) 41 logging_group.add_argument( 42 "-v", "--verbose", action="store_true", help="Run more verbosely." 43 ) 44 logging_group.add_argument( 45 "-q", "--quiet", action="store_true", help="Turn verbosity off." 46 ) 47 options = parser.parse_args(args) 48 49 configLogger( 50 level=("DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO") 51 ) 52 53 font = TTFont(options.font) 54 # TODO: switch everything to have type(mode) = int when using the Config class 55 compact(font, str(options.gpos_compact_mode)) 56 font.save(options.outfile or options.font) 57 58 59 60if __name__ == "__main__": 61 import sys 62 63 if len(sys.argv) > 1: 64 sys.exit(main()) 65 import doctest 66 67 sys.exit(doctest.testmod().failed) 68 69