summaryrefslogtreecommitdiffstats
path: root/lib/silfont/scripts/psfcheckinterpolatable.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/silfont/scripts/psfcheckinterpolatable.py')
-rw-r--r--lib/silfont/scripts/psfcheckinterpolatable.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/silfont/scripts/psfcheckinterpolatable.py b/lib/silfont/scripts/psfcheckinterpolatable.py
new file mode 100644
index 0000000..abcf526
--- /dev/null
+++ b/lib/silfont/scripts/psfcheckinterpolatable.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+__doc__ = '''Check that the ufos in a designspace file are interpolatable'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2021 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+from fontParts.world import OpenFont
+import fontTools.designspaceLib as DSD
+
+argspec = [
+ ('designspace', {'help': 'Design space file'}, {'type': 'filename'}),
+ ('-l','--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_checkinterp.log'}),
+ ]
+
+def doit(args) :
+ logger = args.logger
+
+ ds = DSD.DesignSpaceDocument()
+ ds.read(args.designspace)
+ if len(ds.sources) == 1: logger.log("The design space file has only one source UFO", "S")
+
+ # Find all the UFOs from the DS Sources. Where there are more than 2, the primary one will be considered to be
+ # the one where info copy="1" is set (as per psfsyncmasters). If not set for any, use the first ufo.
+ pufo = None
+ otherfonts = {}
+ for source in ds.sources:
+ ufo = source.path
+ try:
+ font = OpenFont(ufo)
+ except Exception as e:
+ logger.log("Unable to open " + ufo, "S")
+ if source.copyInfo:
+ if pufo: logger.log('Multiple fonts with <info copy="1" />', "S")
+ pufo = ufo
+ pfont = font
+ else:
+ otherfonts[ufo] = font
+ if pufo is None: # If we can't identify the primary font by conyInfo, just use the first one
+ pufo = ds.sources[0].path
+ pfont = otherfonts[pufo]
+ del otherfonts[pufo]
+
+ pinventory = set(glyph.name for glyph in pfont)
+
+ for oufo in otherfonts:
+ logger.log(f'Comparing {pufo} with {oufo}', 'P')
+ ofont = otherfonts[oufo]
+ oinventory = set(glyph.name for glyph in ofont)
+
+ if pinventory != oinventory:
+ logger.log("The glyph inventories in the two UFOs differ", "E")
+ for glyphn in sorted(pinventory - oinventory):
+ logger.log(f'{glyphn} is only in {pufo}', "W")
+ for glyphn in sorted(oinventory - pinventory):
+ logger.log(f'{glyphn} is only in {oufo}', "W")
+ else:
+ logger.log("The UFOs have the same glyph inventories", "P")
+ # Are glyphs compatible for interpolation
+ incompatibles = {}
+ for glyphn in pinventory & oinventory:
+ compatible, report = pfont[glyphn].isCompatible(ofont[glyphn])
+ if not compatible: incompatibles[glyphn] = report
+ if incompatibles:
+ logger.log(f'{len(incompatibles)} glyphs are not interpolatable', 'E')
+ for glyphn in sorted(incompatibles):
+ logger.log(f'{glyphn} is not interpolatable', 'W')
+ logger.log(incompatibles[glyphn], "I")
+ if logger.scrlevel == "W": logger.log("To see detailed reports run with scrlevel and/or loglevel set to I")
+ else:
+ logger.log("All the glyphs are interpolatable", "P")
+
+def cmd() : execute(None,doit, argspec)
+if __name__ == "__main__": cmd()