• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from argparse import RawTextHelpFormatter
2from textwrap import dedent
3
4from fontTools.ttLib import TTFont
5from fontTools.otlLib.optimize.gpos import compact, GPOS_COMPACT_MODE_DEFAULT
6
7def main(args=None):
8    """Optimize the layout tables of an existing font."""
9    from argparse import ArgumentParser
10    from fontTools import configLogger
11
12    parser = ArgumentParser(prog="otlLib.optimize", description=main.__doc__, formatter_class=RawTextHelpFormatter)
13    parser.add_argument("font")
14    parser.add_argument(
15        "-o", metavar="OUTPUTFILE", dest="outfile", default=None, help="output file"
16    )
17    parser.add_argument(
18        "--gpos-compact-mode",
19        help=dedent(
20            f"""\
21            GPOS Lookup type 2 (PairPos) compaction mode:
22                0 = do not attempt to compact PairPos lookups;
23                1 to 8 = create at most 1 to 8 new subtables for each existing
24                    subtable, provided that it would yield a 50%% file size saving;
25                9 = create as many new subtables as needed to yield a file size saving.
26            Default: {GPOS_COMPACT_MODE_DEFAULT}.
27
28            This compaction aims to save file size, by splitting large class
29            kerning subtables (Format 2) that contain many zero values into
30            smaller and denser subtables. It's a trade-off between the overhead
31            of several subtables versus the sparseness of one big subtable.
32
33            See the pull request: https://github.com/fonttools/fonttools/pull/2326
34            """
35        ),
36        default=int(GPOS_COMPACT_MODE_DEFAULT),
37        choices=list(range(10)),
38        type=int,
39    )
40    logging_group = parser.add_mutually_exclusive_group(required=False)
41    logging_group.add_argument(
42        "-v", "--verbose", action="store_true", help="Run more verbosely."
43    )
44    logging_group.add_argument(
45        "-q", "--quiet", action="store_true", help="Turn verbosity off."
46    )
47    options = parser.parse_args(args)
48
49    configLogger(
50        level=("DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO")
51    )
52
53    font = TTFont(options.font)
54    # TODO: switch everything to have type(mode) = int when using the Config class
55    compact(font, str(options.gpos_compact_mode))
56    font.save(options.outfile or options.font)
57
58
59
60if __name__ == "__main__":
61    import sys
62
63    if len(sys.argv) > 1:
64        sys.exit(main())
65    import doctest
66
67    sys.exit(doctest.testmod().failed)
68
69