1#!/usr/bin/env python3
2
3import argparse
4import logging
5import os
6import sys
7
8from fontTools.ttLib import TTFont
9
10
11def ProcessTable(table):
12    found = set()
13
14    for rec in table.ScriptList.ScriptRecord:
15        if rec.ScriptTag == "DFLT" and rec.Script.LangSysCount != 0:
16            tags = [r.LangSysTag for r in rec.Script.LangSysRecord]
17            logging.info("Removing %d extraneous LangSys records: %s",
18                         rec.Script.LangSysCount, " ".join(tags))
19            rec.Script.LangSysRecord = []
20            rec.Script.LangSysCount = 0
21            found.update(tags)
22
23    if not found:
24        logging.info("All fine")
25        return False
26    else:
27        for rec in table.ScriptList.ScriptRecord:
28            tags = set([r.LangSysTag for r in rec.Script.LangSysRecord])
29            found -= tags
30
31        if found:
32            logging.warning("Records are missing from non-DFLT scripts: %s",
33                            " ".join(found))
34        return True
35
36
37def ProcessFont(font):
38    found = False
39    for tag in ("GSUB", "GPOS"):
40        if tag in font:
41            logging.info("Processing %s table", tag)
42            if ProcessTable(font[tag].table):
43                found = True
44            else:
45                # Unmark the table as loaded so that it is read from disk when
46                # writing the font, to avoid any unnecessary changes caused by
47                # decompiling then recompiling again.
48                del font.tables[tag]
49
50    return found
51
52
53def ProcessFiles(filenames):
54    for filename in filenames:
55        logging.info("Processing %s", filename)
56        font = TTFont(filename)
57        name, ext = os.path.splitext(filename)
58        fixedname = name + ".fixed" + ext
59        if ProcessFont(font):
60            logging.info("Saving fixed font to %s\n", fixedname)
61            font.save(fixedname)
62        else:
63            logging.info("Font file is fine, nothing to fix\n")
64
65
66def main():
67    parser = argparse.ArgumentParser(
68            description="Fix LangSys records for DFLT script")
69    parser.add_argument("files", metavar="FILE", type=str, nargs="+",
70                        help="input font to process")
71    parser.add_argument("-s", "--silent", action='store_true',
72                        help="suppress normal messages")
73
74    args = parser.parse_args()
75
76    logformat = "%(levelname)s: %(message)s"
77    if args.silent:
78        logging.basicConfig(format=logformat, level=logging.DEBUG)
79    else:
80        logging.basicConfig(format=logformat, level=logging.INFO)
81
82    ProcessFiles(args.files)
83
84if __name__ == "__main__":
85    sys.exit(main())
86