summaryrefslogtreecommitdiffstats
path: root/lib/silfont/scripts/psfufo2ttf.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/silfont/scripts/psfufo2ttf.py')
-rw-r--r--lib/silfont/scripts/psfufo2ttf.py108
1 files changed, 108 insertions, 0 deletions
diff --git a/lib/silfont/scripts/psfufo2ttf.py b/lib/silfont/scripts/psfufo2ttf.py
new file mode 100644
index 0000000..832ef88
--- /dev/null
+++ b/lib/silfont/scripts/psfufo2ttf.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+__doc__ = 'Generate a ttf file without OpenType tables from a UFO'
+__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__ = 'Alan Ward'
+
+# Compared to fontmake it does not decompose glyphs or remove overlaps
+# and curve conversion seems to happen in a different way.
+
+from silfont.core import execute
+import defcon, ufo2ft.outlineCompiler, ufo2ft.preProcessor, ufo2ft.filters
+
+argspec = [
+ ('iufo', {'help': 'Input UFO folder'}, {}),
+ ('ottf', {'help': 'Output ttf file name'}, {}),
+ ('--removeOverlaps', {'help': 'Merge overlapping contours', 'action': 'store_true'}, {}),
+ ('--decomposeComponents', {'help': 'Decompose componenets', 'action': 'store_true'}, {}),
+ ('-l', '--log', {'help': 'Optional log file'}, {'type': 'outfile', 'def': '_ufo2ttf.log', 'optlog': True})]
+
+PUBLIC_PREFIX = 'public.'
+
+def doit(args):
+ ufo = defcon.Font(args.iufo)
+
+ # if style is Regular and there are no openTypeNameRecords defining the full name (ID=4), then
+ # add one so that "Regular" is omitted from the fullname
+ if ufo.info.styleName == 'Regular':
+ if ufo.info.openTypeNameRecords is None:
+ ufo.info.openTypeNameRecords = []
+ fullNameRecords = [ nr for nr in ufo.info.openTypeNameRecords if nr['nameID'] == 4]
+ if not len(fullNameRecords):
+ ufo.info.openTypeNameRecords.append( { 'nameID': 4, 'platformID': 3, 'encodingID': 1, 'languageID': 1033, 'string': ufo.info.familyName } )
+
+# args.logger.log('Converting UFO to ttf and compiling fea')
+# font = ufo2ft.compileTTF(ufo,
+# glyphOrder = ufo.lib.get(PUBLIC_PREFIX + 'glyphOrder'),
+# useProductionNames = False)
+
+ args.logger.log('Converting UFO to ttf without OT', 'P')
+
+ # default arg value for TTFPreProcessor class: removeOverlaps = False, convertCubics = True
+ preProcessor = ufo2ft.preProcessor.TTFPreProcessor(ufo, removeOverlaps = args.removeOverlaps, convertCubics=True,
+ flattenComponents = True,
+ skipExportGlyphs = ufo.lib.get("public.skipExportGlyphs", []))
+
+ # Need to handle cases if filters that are used are set in com.github.googlei18n.ufo2ft.filters with lib.plist
+ dc = dtc = ftpos = None
+ for (i,filter) in enumerate(preProcessor.preFilters):
+ if isinstance(filter, ufo2ft.filters.decomposeComponents.DecomposeComponentsFilter):
+ dc = True
+ if isinstance(filter, ufo2ft.filters.decomposeTransformedComponents.DecomposeTransformedComponentsFilter):
+ dtc = True
+ if isinstance(filter, ufo2ft.filters.flattenComponents.FlattenComponentsFilter):
+ ftpos = i
+ # Add decomposeComponents if --decomposeComponents is used
+ if args.decomposeComponents and not dc: preProcessor.preFilters.append(
+ ufo2ft.filters.decomposeComponents.DecomposeComponentsFilter())
+ # Add decomposeTransformedComponents if not already set via lib.plist
+ if not dtc: preProcessor.preFilters.append(ufo2ft.filters.decomposeTransformedComponents.DecomposeTransformedComponentsFilter())
+ # Remove flattenComponents if set via lib.plist since we set it via flattenComponents = True when setting up the preprocessor
+ if ftpos: preProcessor.preFilters.pop(ftpos)
+
+ glyphSet = preProcessor.process()
+ outlineCompiler = ufo2ft.outlineCompiler.OutlineTTFCompiler(ufo,
+ glyphSet=glyphSet,
+ glyphOrder=ufo.lib.get(PUBLIC_PREFIX + 'glyphOrder'))
+ font = outlineCompiler.compile()
+
+ # handle uvs glyphs until ufo2ft does it for us.
+ uvsdict = getuvss(ufo)
+ if len(uvsdict):
+ from fontTools.ttLib.tables._c_m_a_p import cmap_format_14
+ cmap_uvs = cmap_format_14(14)
+ cmap_uvs.platformID = 0
+ cmap_uvs.platEncID = 5
+ cmap_uvs.cmap = {}
+ cmap_uvs.uvsDict = uvsdict
+ font['cmap'].tables.append(cmap_uvs)
+
+ args.logger.log('Saving ttf file', 'P')
+ font.save(args.ottf)
+
+ args.logger.log('Done', 'P')
+
+def getuvss(ufo):
+ uvsdict = {}
+ uvs = ufo.lib.get('org.sil.variationSequences', None)
+ if uvs is not None:
+ for usv, dat in uvs.items():
+ usvc = int(usv, 16)
+ pairs = []
+ uvsdict[usvc] = pairs
+ for k, v in dat.items():
+ pairs.append((int(k, 16), v))
+ return uvsdict
+ for g in ufo:
+ uvs = getattr(g, 'lib', {}).get("org.sil.uvs", None)
+ if uvs is None:
+ continue
+ codes = [int(x, 16) for x in uvs.split()]
+ if codes[1] not in uvsdict:
+ uvsdict[codes[1]] = []
+ uvsdict[codes[1]].append((codes[0], (g.name if codes[0] not in g.unicodes else None)))
+ return uvsdict
+
+def cmd(): execute(None, doit, argspec)
+if __name__ == '__main__': cmd()