1from fontTools.ttLib import TTFont 2from fontTools.feaLib.builder import addOpenTypeFeatures, Builder 3from fontTools.feaLib.error import FeatureLibError 4from fontTools import configLogger 5from fontTools.misc.cliTools import makeOutputFileName 6import sys 7import argparse 8import logging 9 10 11log = logging.getLogger("fontTools.feaLib") 12 13 14def main(args=None): 15 """Add features from a feature file (.fea) into an OTF font""" 16 parser = argparse.ArgumentParser( 17 description="Use fontTools to compile OpenType feature files (*.fea)." 18 ) 19 parser.add_argument( 20 "input_fea", metavar="FEATURES", help="Path to the feature file" 21 ) 22 parser.add_argument( 23 "input_font", metavar="INPUT_FONT", help="Path to the input font" 24 ) 25 parser.add_argument( 26 "-o", 27 "--output", 28 dest="output_font", 29 metavar="OUTPUT_FONT", 30 help="Path to the output font.", 31 ) 32 parser.add_argument( 33 "-t", 34 "--tables", 35 metavar="TABLE_TAG", 36 choices=Builder.supportedTables, 37 nargs="+", 38 help="Specify the table(s) to be built.", 39 ) 40 parser.add_argument( 41 "-d", 42 "--debug", 43 action="store_true", 44 help="Add source-level debugging information to font.", 45 ) 46 parser.add_argument( 47 "-v", 48 "--verbose", 49 help="Increase the logger verbosity. Multiple -v " "options are allowed.", 50 action="count", 51 default=0, 52 ) 53 parser.add_argument( 54 "--traceback", help="show traceback for exceptions.", action="store_true" 55 ) 56 options = parser.parse_args(args) 57 58 levels = ["WARNING", "INFO", "DEBUG"] 59 configLogger(level=levels[min(len(levels) - 1, options.verbose)]) 60 61 output_font = options.output_font or makeOutputFileName(options.input_font) 62 log.info("Compiling features to '%s'" % (output_font)) 63 64 font = TTFont(options.input_font) 65 try: 66 addOpenTypeFeatures( 67 font, options.input_fea, tables=options.tables, debug=options.debug 68 ) 69 except FeatureLibError as e: 70 if options.traceback: 71 raise 72 log.error(e) 73 sys.exit(1) 74 font.save(output_font) 75 76 77if __name__ == "__main__": 78 sys.exit(main()) 79