summaryrefslogtreecommitdiffstats
path: root/lib/silfont/scripts/psfbuildfea.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/silfont/scripts/psfbuildfea.py')
-rwxr-xr-xlib/silfont/scripts/psfbuildfea.py89
1 files changed, 89 insertions, 0 deletions
diff --git a/lib/silfont/scripts/psfbuildfea.py b/lib/silfont/scripts/psfbuildfea.py
new file mode 100755
index 0000000..41cf099
--- /dev/null
+++ b/lib/silfont/scripts/psfbuildfea.py
@@ -0,0 +1,89 @@
+#!/usr/bin/python3
+__doc__ = 'Build features.fea file into a ttf font'
+# TODO: add conditional compilation, compare to fea, compile to ttf
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://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()