diff options
Diffstat (limited to 'src/silfont/scripts/psfwoffit.py')
-rw-r--r-- | src/silfont/scripts/psfwoffit.py | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/silfont/scripts/psfwoffit.py b/src/silfont/scripts/psfwoffit.py new file mode 100644 index 0000000..286133a --- /dev/null +++ b/src/silfont/scripts/psfwoffit.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +__doc__ = 'Convert font between ttf, woff, woff2' +__url__ = 'https://github.com/silnrsi/pysilfont' +__copyright__ = 'Copyright (c) 2021 SIL International (https://www.sil.org)' +__license__ = 'Released under the MIT License (https://opensource.org/licenses/MIT)' +__author__ = 'Bob Hallissy' + +from silfont.core import execute +from fontTools.ttLib import TTFont +from fontTools.ttLib.sfnt import WOFFFlavorData +from fontTools.ttLib.woff2 import WOFF2FlavorData +import os.path + +argspec = [ + ('infont', {'help': 'Source font file (can be ttf, woff, or woff2)'}, {}), + ('-m', '--metadata', {'help': 'file containing XML WOFF metadata', 'default': None}, {}), + ('--privatedata', {'help': 'file containing WOFF privatedata', 'default': None}, {}), + ('-v', '--version', {'help': 'woff font version number in major.minor', 'default': None}, {}), + ('--ttf', {'help': 'name of ttf file to be written', 'nargs': '?', 'default': None, 'const': '-'}, {}), + ('--woff', {'help': 'name of woff file to be written', 'nargs': '?', 'default': None, 'const': '-'}, {}), + ('--woff2', {'help': 'name of woff2 file to be written', 'nargs': '?', 'default': None, 'const': '-'}, {}), + ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_woffit.log'})] + +def doit(args): + logger = args.logger + infont = args.infont + font = TTFont(args.infont) + defaultpath = os.path.splitext(infont)[0] + inFlavor = font.flavor or 'ttf' + logger.log(f'input font {infont} is a {inFlavor}', 'I') + + # Read & parse version, if provided + flavorData = WOFFFlavorData() # Initializes all fields to None + + if args.version: + try: + version = float(args.version) + if version < 0: + raise ValueError('version cannot be negative') + flavorData.majorVersion, flavorData.minorVersion = map(int, format(version, '.3f').split('.')) + except: + logger.log(f'invalid version syntax "{args.version}": should be MM.mmm', 'S') + else: + try: + flavorData.majorVersion = font.flavorData.majorVersion + flavorData.minorVersion = font.flavorData.minorVersion + except: + # Pull version from head table + head = font['head'] + flavorData.majorVersion, flavorData.minorVersion =map(int, format(head.fontRevision, '.3f').split('.')) + + # Read metadata if provided, else get value from input font + if args.metadata: + try: + with open(args.metadata, 'rb') as f: + flavorData.metaData = f.read() + except: + logger.log(f'Unable to read file "{args.metadata}"', 'S') + elif inFlavor != 'ttf': + flavorData.metaData = font.flavorData.metaData + + # Same process for private data + if args.privatedata: + try: + with open(args.privatedata, 'rb') as f: + flavorData.privData = f.read() + except: + logger.log(f'Unable to read file "{args.privatedata}"', 'S') + elif inFlavor != 'ttf': + flavorData.privData = font.flavorData.privData + + if args.woff: + font.flavor = 'woff' + font.flavorData = flavorData + fname = f'{defaultpath}.{font.flavor}' if args.woff2 == '-' else args.woff + logger.log(f'Writing {font.flavor} font to "{fname}"', 'P') + font.save(fname) + + if args.woff2: + font.flavor = 'woff2' + font.flavorData = WOFF2FlavorData(data=flavorData) + fname = f'{defaultpath}.{font.flavor}' if args.woff2 == '-' else args.woff2 + logger.log(f'Writing {font.flavor} font to "{fname}"', 'P') + font.save(fname) + + if args.ttf: + font.flavor = None + font.flavorData = None + fname = f'{defaultpath}.ttf' if args.ttf == '-' else args.ttf + logger.log(f'Writing ttf font to "{fname}"', 'P') + font.save(fname) + + font.close() + +def cmd() : execute('FT',doit, argspec) +if __name__ == "__main__": cmd() + + + |