diff options
Diffstat (limited to 'src/silfont/scripts/psfbuildfea.py')
-rw-r--r-- | src/silfont/scripts/psfbuildfea.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/silfont/scripts/psfbuildfea.py b/src/silfont/scripts/psfbuildfea.py new file mode 100644 index 0000000..f659315 --- /dev/null +++ b/src/silfont/scripts/psfbuildfea.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +__doc__ = 'Build features.fea file into a ttf font' +# TODO: add conditional compilation, compare to fea, compile to ttf +__url__ = 'https://github.com/silnrsi/pysilfont' +__copyright__ = 'Copyright (c) 2017 SIL International (https://www.sil.org)' +__license__ = 'Released under the MIT License (https://opensource.org/licenses/MIT)' +__author__ = 'Martin Hosken' + +from fontTools.feaLib.builder import Builder +from fontTools import configLogger +from fontTools.ttLib import TTFont +from fontTools.ttLib.tables.otTables import lookupTypes +from fontTools.feaLib.lookupDebugInfo import LookupDebugInfo + +from silfont.core import execute + +class MyBuilder(Builder): + + def __init__(self, font, featurefile, lateSortLookups=False, fronts=None): + super(MyBuilder, self).__init__(font, featurefile) + self.lateSortLookups = lateSortLookups + self.fronts = fronts if fronts is not None else [] + + def buildLookups_(self, tag): + assert tag in ('GPOS', 'GSUB'), tag + countFeatureLookups = 0 + fronts = set([l for k, l in self.named_lookups_.items() if k in self.fronts]) + for bldr in self.lookups_: + bldr.lookup_index = None + if bldr.table == tag and getattr(bldr, '_feature', "") != "": + countFeatureLookups += 1 + lookups = [] + latelookups = [] + for bldr in self.lookups_: + if bldr.table != tag: + continue + if self.lateSortLookups and getattr(bldr, '_feature', "") == "": + if bldr in fronts: + latelookups.insert(0, bldr) + else: + latelookups.append(bldr) + else: + bldr.lookup_index = len(lookups) + lookups.append(bldr) + bldr.map_index = bldr.lookup_index + numl = len(lookups) + for i, l in enumerate(latelookups): + l.lookup_index = numl + i + l.map_index = l.lookup_index + for l in lookups + latelookups: + self.lookup_locations[tag][str(l.lookup_index)] = LookupDebugInfo( + location=str(l.location), + name=self.get_lookup_name_(l), + feature=None) + return [b.build() for b in lookups + latelookups] + + def add_lookup_to_feature_(self, lookup, feature_name): + super(MyBuilder, self).add_lookup_to_feature_(lookup, feature_name) + lookup._feature = feature_name + + +#TODO: provide more argument info +argspec = [ + ('input_fea', {'help': 'Input fea file'}, {}), + ('input_font', {'help': 'Input font file'}, {}), + ('-o', '--output', {'help': 'Output font file'}, {}), + ('-v', '--verbose', {'help': 'Repeat to increase verbosity', 'action': 'count', 'default': 0}, {}), + ('-m', '--lookupmap', {'help': 'File into which place lookup map'}, {}), + ('-l','--log',{'help': 'Optional log file'}, {'type': 'outfile', 'def': '_buildfea.log', 'optlog': True}), + ('-e','--end',{'help': 'Push lookups not in features to the end', 'action': 'store_true'}, {}), + ('-F','--front',{'help': 'Pull named lookups to the front of unnamed list', 'action': 'append'}, {}), +] + +def doit(args) : + levels = ["WARNING", "INFO", "DEBUG"] + configLogger(level=levels[min(len(levels) - 1, args.verbose)]) + + font = TTFont(args.input_font) + builder = MyBuilder(font, args.input_fea, lateSortLookups=args.end, fronts=args.front) + builder.build() + if args.lookupmap: + with open(args.lookupmap, "w") as outf: + for n, l in sorted(builder.named_lookups_.items()): + if l is not None: + outf.write("{},{},{}\n".format(n, l.table, l.map_index)) + font.save(args.output) + +def cmd(): execute(None, doit, argspec) +if __name__ == '__main__': cmd() |