diff options
author | Daniel Baumann <daniel@debian.org> | 2024-11-21 15:00:40 +0100 |
---|---|---|
committer | Daniel Baumann <daniel@debian.org> | 2024-11-21 15:00:40 +0100 |
commit | 012d9cb5faed22cb9b4151569d30cc08563b02d1 (patch) | |
tree | fd901b9c231aeb8afa713851f23369fa4a1af2b3 /src/silfont/scripts/psffixfontlab.py | |
parent | Initial commit. (diff) | |
download | pysilfont-012d9cb5faed22cb9b4151569d30cc08563b02d1.tar.xz pysilfont-012d9cb5faed22cb9b4151569d30cc08563b02d1.zip |
Adding upstream version 1.8.0.upstream/1.8.0upstream
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'src/silfont/scripts/psffixfontlab.py')
-rw-r--r-- | src/silfont/scripts/psffixfontlab.py | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/silfont/scripts/psffixfontlab.py b/src/silfont/scripts/psffixfontlab.py new file mode 100644 index 0000000..70c823e --- /dev/null +++ b/src/silfont/scripts/psffixfontlab.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +__doc__ = '''Make changes needed to a UFO following processing by FontLab 7. +Various items are reset using the backup of the original font that Fontlab creates +''' +__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__ = 'David Raymond' + +from silfont.core import execute, splitfn +from silfont.ufo import Ufont +import os, shutil, glob + +argspec = [ + ('ifont',{'help': 'Input font file'}, {'type': 'filename'}), + ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_fixfontlab.log'})] + +def doit(args) : + + fontname = args.ifont + logger = args.logger + params = args.paramsobj + + # Locate the oldest backup + (path, base, ext) = splitfn(fontname) + backuppath = os.path.join(path, base + ".*-*" + ext) # Backup has date/time added in format .yymmdd-hhmm + backups = glob.glob(backuppath) + if len(backups) == 0: + logger.log("No backups found matching %s so no changes made to the font" % backuppath, "P") + return + backupname = sorted(backups)[0] # Choose the oldest backup - date/time format sorts alphabetically + + # Reset groups.plist, kerning.plist and any layerinfo.plist(s) from backup ufo + for filename in ["groups.plist", "kerning.plist"]: + bufullname = os.path.join(backupname, filename) + ufofullname = os.path.join(fontname, filename) + if os.path.exists(bufullname): + try: + shutil.copy(bufullname, fontname) + logger.log(filename + " restored from backup", "P") + except Exception as e: + logger.log("Failed to copy %s to %s: %s" % (bufullname, fontname, str(e)), "S") + elif os.path.exists(ufofullname): + os.remove(ufofullname) + logger.log(filename + " removed from ufo", "P") + lifolders = [] + for ufoname in (fontname, backupname): # Find any layerinfo files in either ufo + lis = glob.glob(os.path.join(ufoname, "*/layerinfo.plist")) + for li in lis: + (lifolder, dummy) = os.path.split(li) # Get full path name for folder + (dummy, lifolder) = os.path.split(lifolder) # Now take ufo name off the front + if lifolder not in lifolders: lifolders.append(lifolder) + for folder in lifolders: + filename = os.path.join(folder, "layerinfo.plist") + bufullname = os.path.join(backupname, filename) + ufofullname = os.path.join(fontname, filename) + if os.path.exists(bufullname): + try: + shutil.copy(bufullname, os.path.join(fontname, folder)) + logger.log(filename + " restored from backup", "P") + except Exception as e: + logger.log("Failed to copy %s to %s: %s" % (bufullname, fontname, str(e)), "S") + elif os.path.exists(ufofullname): + os.remove(ufofullname) + logger.log(filename + " removed from ufo", "P") + + # Now open the fonts + font = Ufont(fontname, params = params) + backupfont = Ufont(backupname, params = params) + + fidel = ("openTypeGaspRangeRecords", "openTypeHheaCaretOffset", + "postscriptBlueFuzz", "postscriptBlueScale", "postscriptBlueShift", "postscriptForceBold", + "postscriptIsFixedPitch", "postscriptWeightName") + libdel = ("com.fontlab.v2.tth", "com.typemytype.robofont.italicSlantOffset") + fontinfo = font.fontinfo + libplist = font.lib + backupfi = backupfont.fontinfo + backuplib = backupfont.lib + + # Delete keys that are not needed + for key in fidel: + if key in fontinfo: + old = fontinfo.getval(key) + fontinfo.remove(key) + logchange(logger, " removed from fontinfo.plist. ", key, old, None) + for key in libdel: + if key in libplist: + old = libplist.getval(key) + libplist.remove(key) + logchange(logger, " removed from lib.plist. ", key, old, None) + + # Correct other metadata: + if "guidelines" in backupfi: + fontinfo.setelem("guidelines",backupfi["guidelines"][1]) + logger.log("fontinfo guidelines copied from backup ufo", "I") + elif "guidelines" in fontinfo: + fontinfo.remove("guidelines") + logger.log("fontinfo guidelines deleted - not in backup ufo", "I") + if "italicAngle" in fontinfo and fontinfo.getval("italicAngle") == 0: + fontinfo.remove("italicAngle") + logger.log("fontinfo italicAngle removed since it was 0", "I") + if "openTypeOS2VendorID" in fontinfo: + old = fontinfo.getval("openTypeOS2VendorID") + if len(old) < 4: + new = "%-4s" % (old,) + fontinfo.setval("openTypeOS2VendorID", "string", new) + logchange(logger, " padded to 4 characters ", "openTypeOS2VendorID", "'%s'" % (old,) , "'%s'" % (new,)) + if "woffMetadataCredits" in backupfi: + fontinfo.setelem("woffMetadataCredits",backupfi["woffMetadataCredits"][1]) + logger.log("fontinfo woffMetadataCredits copied from backup ufo", "I") + elif "woffMetadataCredits" in fontinfo: + fontinfo.remove("woffMetadataCredits") + logger.log("fontinfo woffMetadataCredits deleted - not in backup ufo", "I") + if "woffMetadataDescription" in backupfi: + fontinfo.setelem("woffMetadataDescription",backupfi["woffMetadataDescription"][1]) + logger.log("fontinfo woffMetadataDescription copied from backup ufo", "I") + elif "woffMetadataDescription" in fontinfo: + fontinfo.remove("woffMetadataDescription") + logger.log("fontinfo woffMetadataDescription deleted - not in backup ufo", "I") + if "public.glyphOrder" in backuplib: + libplist.setelem("public.glyphOrder",backuplib["public.glyphOrder"][1]) + logger.log("lib.plist public.glyphOrder copied from backup ufo", "I") + elif "public.glyphOrder" in libplist: + libplist.remove("public.glyphOrder") + logger.log("libplist public.glyphOrder deleted - not in backup ufo", "I") + + + + # Now process glif level data + updates = False + for gname in font.deflayer: + glyph = font.deflayer[gname] + glines = glyph["guideline"] + if glines: + for gl in list(glines): glines.remove(gl) # Remove any existing glines + updates = True + buglines = backupfont.deflayer[gname]["guideline"] if gname in backupfont.deflayer else [] + if buglines: + for gl in buglines: glines.append(gl) # Add in those from backup + updates = True + if updates: + logger.log("Some updates to glif guidelines may have been made", "I") + updates = False + for layer in font.layers: + if layer.layername == "public.background": + for gname in layer: + glyph = layer[gname] + if glyph["advance"] is not None: + glyph.remove("advance") + updates = True + if updates: logger.log("Some advance elements removed from public.background glifs", "I") + font.write(fontname) + return + +def logchange(logger, logmess, key, old, new): + oldstr = str(old) if len(str(old)) < 22 else str(old)[0:20] + "..." + newstr = str(new) if len(str(new)) < 22 else str(new)[0:20] + "..." + logmess = key + logmess + if old is None: + logmess = logmess + " New value: " + newstr + else: + if new is None: + logmess = logmess + " Old value: " + oldstr + else: + logmess = logmess + " Old value: " + oldstr + ", new value: " + newstr + logger.log(logmess, "I") + +def cmd() : execute(None,doit, argspec) +if __name__ == "__main__": cmd() |