# Copyright 2013 Google, Inc. All Rights Reserved. # # Google Author(s): Behdad Esfahbod from fontTools import config from fontTools.misc.roundTools import otRound from fontTools import ttLib from fontTools.ttLib.tables import otTables from fontTools.ttLib.tables.otBase import USE_HARFBUZZ_REPACKER from fontTools.otlLib.maxContextCalc import maxCtxFont from fontTools.pens.basePen import NullPen from fontTools.misc.loggingTools import Timer from fontTools.misc.cliTools import makeOutputFileName from fontTools.subset.util import _add_method, _uniq_sort from fontTools.subset.cff import * from fontTools.subset.svg import * from fontTools.varLib import varStore # for subset_varidxes from fontTools.ttLib.tables._n_a_m_e import NameRecordVisitor import sys import struct import array import logging from collections import Counter, defaultdict from functools import reduce from types import MethodType __usage__ = "pyftsubset font-file [glyph...] [--option=value]..." __doc__ = ( """\ pyftsubset -- OpenType font subsetter and optimizer pyftsubset is an OpenType font subsetter and optimizer, based on fontTools. It accepts any TT- or CFF-flavored OpenType (.otf or .ttf) or WOFF (.woff) font file. The subsetted glyph set is based on the specified glyphs or characters, and specified OpenType layout features. The tool also performs some size-reducing optimizations, aimed for using subset fonts as webfonts. Individual optimizations can be enabled or disabled, and are enabled by default when they are safe. Usage: """ + __usage__ + """ At least one glyph or one of --gids, --gids-file, --glyphs, --glyphs-file, --text, --text-file, --unicodes, or --unicodes-file, must be specified. Args: font-file The input font file. glyph Specify one or more glyph identifiers to include in the subset. Must be PS glyph names, or the special string '*' to keep the entire glyph set. Initial glyph set specification ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ These options populate the initial glyph set. Same option can appear multiple times, and the results are accummulated. --gids=[,...] Specify comma/whitespace-separated list of glyph IDs or ranges as decimal numbers. For example, --gids=10-12,14 adds glyphs with numbers 10, 11, 12, and 14. --gids-file= Like --gids but reads from a file. Anything after a '#' on any line is ignored as comments. --glyphs=[,...] Specify comma/whitespace-separated PS glyph names to add to the subset. Note that only PS glyph names are accepted, not gidNNN, U+XXXX, etc that are accepted on the command line. The special string '*' will keep the entire glyph set. --glyphs-file= Like --glyphs but reads from a file. Anything after a '#' on any line is ignored as comments. --text= Specify characters to include in the subset, as UTF-8 string. --text-file= Like --text but reads from a file. Newline character are not added to the subset. --unicodes=[,...] Specify comma/whitespace-separated list of Unicode codepoints or ranges as hex numbers, optionally prefixed with 'U+', 'u', etc. For example, --unicodes=41-5a,61-7a adds ASCII letters, so does the more verbose --unicodes=U+0041-005A,U+0061-007A. The special strings '*' will choose all Unicode characters mapped by the font. --unicodes-file= Like --unicodes, but reads from a file. Anything after a '#' on any line in the file is ignored as comments. --ignore-missing-glyphs Do not fail if some requested glyphs or gids are not available in the font. --no-ignore-missing-glyphs Stop and fail if some requested glyphs or gids are not available in the font. [default] --ignore-missing-unicodes [default] Do not fail if some requested Unicode characters (including those indirectly specified using --text or --text-file) are not available in the font. --no-ignore-missing-unicodes Stop and fail if some requested Unicode characters are not available in the font. Note the default discrepancy between ignoring missing glyphs versus unicodes. This is for historical reasons and in the future --no-ignore-missing-unicodes might become default. Other options ^^^^^^^^^^^^^ For the other options listed below, to see the current value of the option, pass a value of '?' to it, with or without a '='. Examples:: $ pyftsubset --glyph-names? Current setting for 'glyph-names' is: False $ ./pyftsubset --name-IDs=? Current setting for 'name-IDs' is: [0, 1, 2, 3, 4, 5, 6] $ ./pyftsubset --hinting? --no-hinting --hinting? Current setting for 'hinting' is: True Current setting for 'hinting' is: False Output options ^^^^^^^^^^^^^^ --output-file= The output font file. If not specified, the subsetted font will be saved in as font-file.subset. --flavor= Specify flavor of output font file. May be 'woff' or 'woff2'. Note that WOFF2 requires the Brotli Python extension, available at https://github.com/google/brotli --with-zopfli Use the Google Zopfli algorithm to compress WOFF. The output is 3-8 % smaller than pure zlib, but the compression speed is much slower. The Zopfli Python bindings are available at: https://pypi.python.org/pypi/zopfli --harfbuzz-repacker By default, we serialize GPOS/GSUB using the HarfBuzz Repacker when uharfbuzz can be imported and is successful, otherwise fall back to the pure-python serializer. Set the option to force using the HarfBuzz Repacker (raises an error if uharfbuzz can't be found or fails). --no-harfbuzz-repacker Always use the pure-python serializer even if uharfbuzz is available. Glyph set expansion ^^^^^^^^^^^^^^^^^^^ These options control how additional glyphs are added to the subset. --retain-gids Retain glyph indices; just empty glyphs not needed in-place. --notdef-glyph Add the '.notdef' glyph to the subset (ie, keep it). [default] --no-notdef-glyph Drop the '.notdef' glyph unless specified in the glyph set. This saves a few bytes, but is not possible for Postscript-flavored fonts, as those require '.notdef'. For TrueType-flavored fonts, this works fine as long as no unsupported glyphs are requested from the font. --notdef-outline Keep the outline of '.notdef' glyph. The '.notdef' glyph outline is used when glyphs not supported by the font are to be shown. It is not needed otherwise. --no-notdef-outline When including a '.notdef' glyph, remove its outline. This saves a few bytes. [default] --recommended-glyphs Add glyphs 0, 1, 2, and 3 to the subset, as recommended for TrueType-flavored fonts: '.notdef', 'NULL' or '.null', 'CR', 'space'. Some legacy software might require this, but no modern system does. --no-recommended-glyphs Do not add glyphs 0, 1, 2, and 3 to the subset, unless specified in glyph set. [default] --no-layout-closure Do not expand glyph set to add glyphs produced by OpenType layout features. Instead, OpenType layout features will be subset to only rules that are relevant to the otherwise-specified glyph set. --layout-features[+|-]=[,...] Specify (=), add to (+=) or exclude from (-=) the comma-separated set of OpenType layout feature tags that will be preserved. Glyph variants used by the preserved features are added to the specified subset glyph set. By default, 'calt', 'ccmp', 'clig', 'curs', 'dnom', 'frac', 'kern', 'liga', 'locl', 'mark', 'mkmk', 'numr', 'rclt', 'rlig', 'rvrn', and all features required for script shaping are preserved. To see the full list, try '--layout-features=?'. Use '*' to keep all features. Multiple --layout-features options can be provided if necessary. Examples: --layout-features+=onum,pnum,ss01 * Keep the default set of features and 'onum', 'pnum', 'ss01'. --layout-features-='mark','mkmk' * Keep the default set of features but drop 'mark' and 'mkmk'. --layout-features='kern' * Only keep the 'kern' feature, drop all others. --layout-features='' * Drop all features. --layout-features='*' * Keep all features. --layout-features+=aalt --layout-features-=vrt2 * Keep default set of features plus 'aalt', but drop 'vrt2'. --layout-scripts[+|-]=