def main(args=None): """Merge multiple fonts into one""" from fontemon_blender_addon.fontTools import configLogger if args is None: args = sys.argv[1:] options = Options() args = options.parse_opts(args) if len(args) < 1: print("usage: pyftmerge font...", file=sys.stderr) return 1 configLogger(level=logging.INFO if options.verbose else logging.WARNING) if options.timing: timer.logger.setLevel(logging.DEBUG) else: timer.logger.disabled = True merger = Merger(options=options) font = merger.merge(args) outfile = 'merged.ttf' with timer("compile and save font"): font.save(outfile)
def main(args=None): """Convert OpenType fonts to XML and back""" from fontemon_blender_addon.fontTools import configLogger if args is None: args = sys.argv[1:] try: jobs, options = parseOptions(args) except getopt.GetoptError as e: print("%s\nERROR: %s" % (__doc__, e), file=sys.stderr) sys.exit(2) configLogger(level=options.logLevel) try: process(jobs, options) except KeyboardInterrupt: log.error("(Cancelled.)") sys.exit(1) except SystemExit: if sys.platform == "win32": waitForKeyPress() raise except TTLibError as e: log.error(e) sys.exit(1) except: log.exception('Unhandled exception has occurred') if sys.platform == "win32": waitForKeyPress() sys.exit(1)
def main(args=None): """Normalize locations on a given designspace""" from fontemon_blender_addon.fontTools import configLogger import argparse parser = argparse.ArgumentParser( "fontemon_blender_addon.fontTools varLib.models", description=main.__doc__, ) parser.add_argument('--loglevel', metavar='LEVEL', default="INFO", help="Logging level (defaults to INFO)") group = parser.add_mutually_exclusive_group(required=True) group.add_argument('-d', '--designspace', metavar="DESIGNSPACE", type=str) group.add_argument( '-l', '--locations', metavar='LOCATION', nargs='+', help= "Master locations as comma-separate coordinates. One must be all zeros." ) args = parser.parse_args(args) configLogger(level=args.loglevel) from pprint import pprint if args.designspace: from fontemon_blender_addon.fontTools.designspaceLib import DesignSpaceDocument doc = DesignSpaceDocument() doc.read(args.designspace) locs = [s.location for s in doc.sources] print("Original locations:") pprint(locs) doc.normalize() print("Normalized locations:") locs = [s.location for s in doc.sources] pprint(locs) else: axes = [chr(c) for c in range(ord('A'), ord('Z') + 1)] locs = [ dict(zip(axes, (float(v) for v in s.split(',')))) for s in args.locations ] model = VariationModel(locs) print("Sorted locations:") pprint(model.locations) print("Supports:") pprint(model.supports)
def main(args=None): """Interpolate GDEF/GPOS/GSUB tables for a point on a designspace""" from fontemon_blender_addon.fontTools import configLogger import argparse import sys parser = argparse.ArgumentParser( "fontemon_blender_addon.fontTools varLib.interpolate_layout", description=main.__doc__, ) parser.add_argument('designspace_filename', metavar='DESIGNSPACE', help="Input TTF files") parser.add_argument('locations', metavar='LOCATION', type=str, nargs='+', help="Axis locations (e.g. wdth=120") parser.add_argument( '-o', '--output', metavar='OUTPUT', help="Output font file (defaults to <designspacename>-instance.ttf)") parser.add_argument('-l', '--loglevel', metavar='LEVEL', default="INFO", help="Logging level (defaults to INFO)") args = parser.parse_args(args) if not args.output: args.output = os.path.splitext( args.designspace_filename)[0] + '-instance.ttf' configLogger(level=args.loglevel) finder = lambda s: s.replace('master_ufo', 'master_ttf_interpolatable' ).replace('.ufo', '.ttf') loc = {} for arg in args.locations: tag, val = arg.split('=') loc[tag] = float(val) font = interpolate_layout(args.designspace_filename, loc, finder) log.info("Saving font %s", args.output) font.save(args.output)
def main(args=None): """Optimize a font's GDEF variation store""" from argparse import ArgumentParser from fontemon_blender_addon.fontTools import configLogger from fontemon_blender_addon.fontTools.ttLib import TTFont from fontemon_blender_addon.fontTools.ttLib.tables.otBase import OTTableWriter parser = ArgumentParser(prog='varLib.varStore', description=main.__doc__) parser.add_argument('fontfile') parser.add_argument('outfile', nargs='?') options = parser.parse_args(args) # TODO: allow user to configure logging via command-line options configLogger(level="INFO") fontfile = options.fontfile outfile = options.outfile font = TTFont(fontfile) gdef = font['GDEF'] store = gdef.table.VarStore writer = OTTableWriter() store.compile(writer, font) size = len(writer.getAllData()) print("Before: %7d bytes" % size) varidx_map = store.optimize() gdef.table.remap_device_varidxes(varidx_map) if 'GPOS' in font: font['GPOS'].table.remap_device_varidxes(varidx_map) writer = OTTableWriter() store.compile(writer, font) size = len(writer.getAllData()) print("After: %7d bytes" % size) if outfile is not None: font.save(outfile)
def main(args=None): from fontemon_blender_addon.fontTools import configLogger if args is None: args = sys.argv[1:] # configure the library logger (for >= WARNING) configLogger() # comment this out to enable debug messages from logger # log.setLevel(logging.DEBUG) if len(args) < 1: print( "usage: fontemon_blender_addon.fontTools varLib.plot source.designspace", file=sys.stderr) print(" or") print( "usage: fontemon_blender_addon.fontTools varLib.plot location1 location2 ...", file=sys.stderr) sys.exit(1) fig = pyplot.figure() fig.set_tight_layout(True) if len(args) == 1 and args[0].endswith('.designspace'): doc = DesignSpaceDocument() doc.read(args[0]) plotDocument(doc, fig) else: axes = [chr(c) for c in range(ord('A'), ord('Z') + 1)] locs = [ dict(zip(axes, (float(v) for v in s.split(',')))) for s in args ] plotLocations(locs, fig) pyplot.show()
def main(args=None): """Add features from a feature file (.fea) into a OTF font""" parser = argparse.ArgumentParser( description= "Use fontemon_blender_addon.fontTools to compile OpenType feature files (*.fea)." ) parser.add_argument("input_fea", metavar="FEATURES", help="Path to the feature file") parser.add_argument("input_font", metavar="INPUT_FONT", help="Path to the input font") parser.add_argument( "-o", "--output", dest="output_font", metavar="OUTPUT_FONT", help="Path to the output font.", ) parser.add_argument( "-t", "--tables", metavar="TABLE_TAG", choices=Builder.supportedTables, nargs="+", help="Specify the table(s) to be built.", ) parser.add_argument( "-d", "--debug", action="store_true", help="Add source-level debugging information to font.", ) parser.add_argument( "-v", "--verbose", help="increase the logger verbosity. Multiple -v " "options are allowed.", action="count", default=0, ) parser.add_argument("--traceback", help="show traceback for exceptions.", action="store_true") options = parser.parse_args(args) levels = ["WARNING", "INFO", "DEBUG"] configLogger(level=levels[min(len(levels) - 1, options.verbose)]) output_font = options.output_font or makeOutputFileName(options.input_font) log.info("Compiling features to '%s'" % (output_font)) font = TTFont(options.input_font) try: addOpenTypeFeatures(font, options.input_fea, tables=options.tables, debug=options.debug) except FeatureLibError as e: if options.traceback: raise log.error(e) font.save(output_font)
def main(args=None, font=None): """Convert a FontDame OTL file to TTX XML. Writes XML output to stdout. Args: args: Command line arguments (``--font``, ``--table``, input files). """ import sys from fontemon_blender_addon.fontTools import configLogger from fontemon_blender_addon.fontTools.misc.testTools import MockFont if args is None: args = sys.argv[1:] # configure the library logger (for >= WARNING) configLogger() # comment this out to enable debug messages from mtiLib's logger # log.setLevel(logging.DEBUG) import argparse parser = argparse.ArgumentParser( "fontemon_blender_addon.fontTools mtiLib", description=main.__doc__, ) parser.add_argument( '--font', '-f', metavar='FILE', dest="font", help= "Input TTF files (used for glyph classes and sorting coverage tables)") parser.add_argument( '--table', '-t', metavar='TABLE', dest="tableTag", help="Table to fill (sniffed from input file if not provided)") parser.add_argument('inputs', metavar='FILE', type=str, nargs='+', help="Input FontDame .txt files") args = parser.parse_args(args) if font is None: if args.font: font = ttLib.TTFont(args.font) else: font = MockFont() for f in args.inputs: log.debug("Processing %s", f) with open(f, 'rt', encoding="utf-8") as f: table = build(f, font, tableTag=args.tableTag) blob = table.compile(font) # Make sure it compiles decompiled = table.__class__() decompiled.decompile(blob, font) # Make sure it decompiles! #continue from fontemon_blender_addon.fontTools.misc import xmlWriter tag = table.tableTag writer = xmlWriter.XMLWriter(sys.stdout) writer.begintag(tag) writer.newline() #table.toXML(writer, font) decompiled.toXML(writer, font) writer.endtag(tag) writer.newline()
def main(args=None): """Instantiate a variation font""" from fontemon_blender_addon.fontTools import configLogger import argparse parser = argparse.ArgumentParser( "fontemon_blender_addon.fontTools varLib.mutator", description="Instantiate a variable font") parser.add_argument("input", metavar="INPUT.ttf", help="Input variable TTF file.") parser.add_argument( "locargs", metavar="AXIS=LOC", nargs="*", help="List of space separated locations. A location consist in " "the name of a variation axis, followed by '=' and a number. E.g.: " " wght=700 wdth=80. The default is the location of the base master.") parser.add_argument( "-o", "--output", metavar="OUTPUT.ttf", default=None, help="Output instance TTF file (default: INPUT-instance.ttf).") logging_group = parser.add_mutually_exclusive_group(required=False) logging_group.add_argument("-v", "--verbose", action="store_true", help="Run more verbosely.") logging_group.add_argument("-q", "--quiet", action="store_true", help="Turn verbosity off.") parser.add_argument( "--no-overlap", dest="overlap", action="store_false", help="Don't set OVERLAP_SIMPLE/OVERLAP_COMPOUND glyf flags.") options = parser.parse_args(args) varfilename = options.input outfile = (os.path.splitext(varfilename)[0] + '-instance.ttf' if not options.output else options.output) configLogger(level=( "DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO")) loc = {} for arg in options.locargs: try: tag, val = arg.split('=') assert len(tag) <= 4 loc[tag.ljust(4)] = float(val) except (ValueError, AssertionError): parser.error("invalid location argument format: %r" % arg) log.info("Location: %s", loc) log.info("Loading variable font") varfont = TTFont(varfilename) instantiateVariableFont(varfont, loc, inplace=True, overlap=options.overlap) log.info("Saving instance font %s", outfile) varfont.save(outfile)
def main(args=None): """Build a variable font from a designspace file and masters""" from argparse import ArgumentParser from fontemon_blender_addon.fontTools import configLogger parser = ArgumentParser(prog='varLib', description = main.__doc__) parser.add_argument('designspace') parser.add_argument( '-o', metavar='OUTPUTFILE', dest='outfile', default=None, help='output file' ) parser.add_argument( '-x', metavar='TAG', dest='exclude', action='append', default=[], help='exclude table' ) parser.add_argument( '--disable-iup', dest='optimize', action='store_false', help='do not perform IUP optimization' ) parser.add_argument( '--master-finder', default='master_ttf_interpolatable/{stem}.ttf', help=( 'templated string used for finding binary font ' 'files given the source file names defined in the ' 'designspace document. The following special strings ' 'are defined: {fullname} is the absolute source file ' 'name; {basename} is the file name without its ' 'directory; {stem} is the basename without the file ' 'extension; {ext} is the source file extension; ' '{dirname} is the directory of the absolute file ' 'name. The default value is "%(default)s".' ) ) logging_group = parser.add_mutually_exclusive_group(required=False) logging_group.add_argument( "-v", "--verbose", action="store_true", help="Run more verbosely.") logging_group.add_argument( "-q", "--quiet", action="store_true", help="Turn verbosity off.") options = parser.parse_args(args) configLogger(level=( "DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO")) designspace_filename = options.designspace finder = MasterFinder(options.master_finder) vf, _, _ = build( designspace_filename, finder, exclude=options.exclude, optimize=options.optimize ) outfile = options.outfile if outfile is None: ext = "otf" if vf.sfntVersion == "OTTO" else "ttf" outfile = os.path.splitext(designspace_filename)[0] + '-VF.' + ext log.info("Saving variation font %s", outfile) vf.save(outfile)