# Copyright 2013 Google, Inc. All Rights Reserved.
#
# Google Author(s): Behdad Esfahbod

from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.misc.fixedTools import otRound
from fontTools import ttLib
from fontTools.ttLib.tables import otTables
from fontTools.otlLib.maxContextCalc import maxCtxFont
from fontTools.pens.basePen import NullPen
from fontTools.misc.loggingTools import Timer
from fontTools.subset.cff import *
from fontTools.varLib import varStore
import sys
import struct
import array
import logging
from collections import Counter
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.

Arguments:
  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=<NNN>[,<NNN>...]
      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=<path>
      Like --gids but reads from a file. Anything after a '#' on any line
      is ignored as comments.
  --glyphs=<glyphname>[,<glyphname>...]
      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=<path>
      Like --glyphs but reads from a file. Anything after a '#' on any line
      is ignored as comments.
  --text=<text>
      Specify characters to include in the subset, as UTF-8 string.
  --text-file=<path>
      Like --text but reads from a file. Newline character are not added to
      the subset.
  --unicodes=<XXXX>[,<XXXX>...]
      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=<path>
      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=<path>
      The output font file. If not specified, the subsetted font
      will be saved in as font-file.subset.
  --flavor=<type>
      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

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[+|-]=<feature>[,<feature>...]
      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[+|-]=<script>[,<script>...]
      Specify (=), add to (+=) or exclude from (-=) the comma-separated
      set of OpenType layout script tags that will be preserved.  By
      default all scripts are retained ('*').

Hinting options:
  --hinting
      Keep hinting [default]
  --no-hinting
      Drop glyph-specific hinting and font-wide hinting tables, as well
      as remove hinting-related bits and pieces from other tables (eg. GPOS).
      See --hinting-tables for list of tables that are dropped by default.
      Instructions and hints are stripped from 'glyf' and 'CFF ' tables
      respectively. This produces (sometimes up to 30%) smaller fonts that
      are suitable for extremely high-resolution systems, like high-end
      mobile devices and retina displays.

Optimization options:
  --desubroutinize
      Remove CFF use of subroutinizes.  Subroutinization is a way to make CFF
      fonts smaller.  For small subsets however, desubroutinizing might make
      the font smaller.  It has even been reported that desubroutinized CFF
      fonts compress better (produce smaller output) WOFF and WOFF2 fonts.
      Also see note under --no-hinting.
  --no-desubroutinize [default]
      Leave CFF subroutinizes as is, only throw away unused subroutinizes.

Font table options:
  --drop-tables[+|-]=<table>[,<table>...]
      Specify (=), add to (+=) or exclude from (-=) the comma-separated
      set of tables that will be be dropped.
      By default, the following tables are dropped:
      'BASE', 'JSTF', 'DSIG', 'EBDT', 'EBLC', 'EBSC', 'SVG ', 'PCLT', 'LTSH'
      and Graphite tables: 'Feat', 'Glat', 'Gloc', 'Silf', 'Sill'
      and color tables: 'sbix'.
      The tool will attempt to subset the remaining tables.
      Examples:
        --drop-tables-='SVG '
            * Drop the default set of tables but keep 'SVG '.
        --drop-tables+=GSUB
            * Drop the default set of tables and 'GSUB'.
        --drop-tables=DSIG
            * Only drop the 'DSIG' table, keep all others.
        --drop-tables=
            * Keep all tables.
  --no-subset-tables+=<table>[,<table>...]
      Add to the set of tables that will not be subsetted.
      By default, the following tables are included in this list, as
      they do not need subsetting (ignore the fact that 'loca' is listed
      here): 'gasp', 'head', 'hhea', 'maxp', 'vhea', 'OS/2', 'loca', 'name',
      'cvt ', 'fpgm', 'prep', 'VMDX', 'DSIG', 'CPAL', 'MVAR', 'cvar', 'STAT'.
      By default, tables that the tool does not know how to subset and are not
      specified here will be dropped from the font, unless --passthrough-tables
      option is passed.
      Example:
         --no-subset-tables+=FFTM
            * Keep 'FFTM' table in the font by preventing subsetting.
  --passthrough-tables
      Do not drop tables that the tool does not know how to subset.
  --no-passthrough-tables
      Tables that the tool does not know how to subset and are not specified
      in --no-subset-tables will be dropped from the font. [default]
  --hinting-tables[-]=<table>[,<table>...]
      Specify (=), add to (+=) or exclude from (-=) the list of font-wide
      hinting tables that will be dropped if --no-hinting is specified,
      Examples:
        --hinting-tables-='VDMX'
            * Drop font-wide hinting tables except 'VDMX'.
        --hinting-tables=''
            * Keep all font-wide hinting tables (but strip hints from glyphs).
  --legacy-kern
      Keep TrueType 'kern' table even when OpenType 'GPOS' is available.
  --no-legacy-kern
      Drop TrueType 'kern' table if OpenType 'GPOS' is available. [default]

Font naming options:
  These options control what is retained in the 'name' table. For numerical
  codes, see: http://www.microsoft.com/typography/otspec/name.htm
  --name-IDs[+|-]=<nameID>[,<nameID>...]
      Specify (=), add to (+=) or exclude from (-=) the set of 'name' table
      entry nameIDs that will be preserved. By default, only nameIDs between 0
      and 6 are preserved, the rest are dropped. Use '*' to keep all entries.
      Examples:
        --name-IDs+=7,8,9
            * Also keep Trademark, Manufacturer and Designer name entries.
        --name-IDs=''
            * Drop all 'name' table entries.
        --name-IDs='*'
            * keep all 'name' table entries
  --name-legacy
      Keep legacy (non-Unicode) 'name' table entries (0.x, 1.x etc.).
      XXX Note: This might be needed for some fonts that have no Unicode name
      entires for English. See: https://github.com/fonttools/fonttools/issues/146
  --no-name-legacy
      Drop legacy (non-Unicode) 'name' table entries [default]
  --name-languages[+|-]=<langID>[,<langID>]
      Specify (=), add to (+=) or exclude from (-=) the set of 'name' table
      langIDs that will be preserved. By default only records with langID
      0x0409 (English) are preserved. Use '*' to keep all langIDs.
  --obfuscate-names
      Make the font unusable as a system font by replacing name IDs 1, 2, 3, 4,
      and 6 with dummy strings (it is still fully functional as webfont).

Glyph naming and encoding options:
  --glyph-names
      Keep PS glyph names in TT-flavored fonts. In general glyph names are
      not needed for correct use of the font. However, some PDF generators
      and PDF viewers might rely on glyph names to extract Unicode text
      from PDF documents.
  --no-glyph-names
      Drop PS glyph names in TT-flavored fonts, by using 'post' table
      version 3.0. [default]
  --legacy-cmap
      Keep the legacy 'cmap' subtables (0.x, 1.x, 4.x etc.).
  --no-legacy-cmap
      Drop the legacy 'cmap' subtables. [default]
  --symbol-cmap
      Keep the 3.0 symbol 'cmap'.
  --no-symbol-cmap
      Drop the 3.0 symbol 'cmap'. [default]

Other font-specific options:
  --recalc-bounds
      Recalculate font bounding boxes.
  --no-recalc-bounds
      Keep original font bounding boxes. This is faster and still safe
      for all practical purposes. [default]
  --recalc-timestamp
      Set font 'modified' timestamp to current time.
  --no-recalc-timestamp
      Do not modify font 'modified' timestamp. [default]
  --canonical-order
      Order tables as recommended in the OpenType standard. This is not
      required by the standard, nor by any known implementation.
  --no-canonical-order
      Keep original order of font tables. This is faster. [default]
  --prune-unicode-ranges
      Update the 'OS/2 ulUnicodeRange*' bits after subsetting. The Unicode
      ranges defined in the OpenType specification v1.7 are intersected with
      the Unicode codepoints specified in the font's Unicode 'cmap' subtables:
      when no overlap is found, the bit will be switched off. However, it will
      *not* be switched on if an intersection is found.  [default]
  --no-prune-unicode-ranges
      Don't change the 'OS/2 ulUnicodeRange*' bits.
  --recalc-average-width
      Update the 'OS/2 xAvgCharWidth' field after subsetting.
  --no-recalc-average-width
      Don't change the 'OS/2 xAvgCharWidth' field. [default]
  --recalc-max-context
      Update the 'OS/2 usMaxContext' field after subsetting.
  --no-recalc-max-context
      Don't change the 'OS/2 usMaxContext' field. [default]
  --font-number=<number>
      Select font number for TrueType Collection (.ttc/.otc), starting from 0.

Application options:
  --verbose
      Display verbose information of the subsetting process.
  --timing
      Display detailed timing information of the subsetting process.
  --xml
      Display the TTX XML representation of subsetted font.

Example:
  Produce a subset containing the characters ' !"#$%' without performing
  size-reducing optimizations:

  $ pyftsubset font.ttf --unicodes="U+0020-0025" \\
    --layout-features='*' --glyph-names --symbol-cmap --legacy-cmap \\
    --notdef-glyph --notdef-outline --recommended-glyphs \\
    --name-IDs='*' --name-legacy --name-languages='*'
"""


log = logging.getLogger("fontTools.subset")

def _log_glyphs(self, glyphs, font=None):
	self.info("Glyph names: %s", sorted(glyphs))
	if font:
		reverseGlyphMap = font.getReverseGlyphMap()
		self.info("Glyph IDs:   %s", sorted(reverseGlyphMap[g] for g in glyphs))

# bind "glyphs" function to 'log' object
log.glyphs = MethodType(_log_glyphs, log)

# I use a different timing channel so I can configure it separately from the
# main module's logger
timer = Timer(logger=logging.getLogger("fontTools.subset.timer"))


def _add_method(*clazzes):
	"""Returns a decorator function that adds a new method to one or
	more classes."""
	def wrapper(method):
		done = []
		for clazz in clazzes:
			if clazz in done: continue # Support multiple names of a clazz
			done.append(clazz)
			assert clazz.__name__ != 'DefaultTable', \
					'Oops, table class not found.'
			assert not hasattr(clazz, method.__name__), \
					"Oops, class '%s' has method '%s'." % (clazz.__name__,
									       method.__name__)
			setattr(clazz, method.__name__, method)
		return None
	return wrapper

def _uniq_sort(l):
	return sorted(set(l))

def _dict_subset(d, glyphs):
	return {g:d[g] for g in glyphs}


@_add_method(otTables.Coverage)
def intersect(self, glyphs):
	"""Returns ascending list of matching coverage values."""
	return [i for i,g in enumerate(self.glyphs) if g in glyphs]

@_add_method(otTables.Coverage)
def intersect_glyphs(self, glyphs):
	"""Returns set of intersecting glyphs."""
	return set(g for g in self.glyphs if g in glyphs)

@_add_method(otTables.Coverage)
def subset(self, glyphs):
	"""Returns ascending list of remaining coverage values."""
	indices = self.intersect(glyphs)
	self.glyphs = [g for g in self.glyphs if g in glyphs]
	return indices

@_add_method(otTables.Coverage)
def remap(self, coverage_map):
	"""Remaps coverage."""
	self.glyphs = [self.glyphs[i] for i in coverage_map]

@_add_method(otTables.ClassDef)
def intersect(self, glyphs):
	"""Returns ascending list of matching class values."""
	return _uniq_sort(
		 ([0] if any(g not in self.classDefs for g in glyphs) else []) +
			[v for g,v in self.classDefs.items() if g in glyphs])

@_add_method(otTables.ClassDef)
def intersect_class(self, glyphs, klass):
	"""Returns set of glyphs matching class."""
	if klass == 0:
		return set(g for g in glyphs if g not in self.classDefs)
	return set(g for g,v in self.classDefs.items()
		     if v == klass and g in glyphs)

@_add_method(otTables.ClassDef)
def subset(self, glyphs, remap=False):
	"""Returns ascending list of remaining classes."""
	self.classDefs = {g:v for g,v in self.classDefs.items() if g in glyphs}
	# Note: while class 0 has the special meaning of "not matched",
	# if no glyph will ever /not match/, we can optimize class 0 out too.
	indices = _uniq_sort(
		 ([0] if any(g not in self.classDefs for g in glyphs) else []) +
			list(self.classDefs.values()))
	if remap:
		self.remap(indices)
	return indices

@_add_method(otTables.ClassDef)
def remap(self, class_map):
	"""Remaps classes."""
	self.classDefs = {g:class_map.index(v) for g,v in self.classDefs.items()}

@_add_method(otTables.SingleSubst)
def closure_glyphs(self, s, cur_glyphs):
	s.glyphs.update(v for g,v in self.mapping.items() if g in cur_glyphs)

@_add_method(otTables.SingleSubst)
def subset_glyphs(self, s):
	self.mapping = {g:v for g,v in self.mapping.items()
					if g in s.glyphs and v in s.glyphs}
	return bool(self.mapping)

@_add_method(otTables.MultipleSubst)
def closure_glyphs(self, s, cur_glyphs):
	for glyph, subst in self.mapping.items():
		if glyph in cur_glyphs:
			s.glyphs.update(subst)

@_add_method(otTables.MultipleSubst)
def subset_glyphs(self, s):
	self.mapping = {g:v for g,v in self.mapping.items()
					if g in s.glyphs and all(sub in s.glyphs for sub in v)}
	return bool(self.mapping)

@_add_method(otTables.AlternateSubst)
def closure_glyphs(self, s, cur_glyphs):
	s.glyphs.update(*(vlist for g,vlist in self.alternates.items()
				if g in cur_glyphs))

@_add_method(otTables.AlternateSubst)
def subset_glyphs(self, s):
	self.alternates = {g:[v for v in vlist if v in s.glyphs]
					   for g,vlist in self.alternates.items()
					   if g in s.glyphs and
					   any(v in s.glyphs for v in vlist)}
	return bool(self.alternates)

@_add_method(otTables.LigatureSubst)
def closure_glyphs(self, s, cur_glyphs):
	s.glyphs.update(*([seq.LigGlyph for seq in seqs
					if all(c in s.glyphs for c in seq.Component)]
			  for g,seqs in self.ligatures.items()
			  if g in cur_glyphs))

@_add_method(otTables.LigatureSubst)
def subset_glyphs(self, s):
	self.ligatures = {g:v for g,v in self.ligatures.items()
					  if g in s.glyphs}
	self.ligatures = {g:[seq for seq in seqs
				 if seq.LigGlyph in s.glyphs and
					all(c in s.glyphs for c in seq.Component)]
			  for g,seqs in self.ligatures.items()}
	self.ligatures = {g:v for g,v in self.ligatures.items() if v}
	return bool(self.ligatures)

@_add_method(otTables.ReverseChainSingleSubst)
def closure_glyphs(self, s, cur_glyphs):
	if self.Format == 1:
		indices = self.Coverage.intersect(cur_glyphs)
		if(not indices or
		   not all(c.intersect(s.glyphs)
				   for c in self.LookAheadCoverage + self.BacktrackCoverage)):
			return
		s.glyphs.update(self.Substitute[i] for i in indices)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ReverseChainSingleSubst)
def subset_glyphs(self, s):
	if self.Format == 1:
		indices = self.Coverage.subset(s.glyphs)
		self.Substitute = [self.Substitute[i] for i in indices]
		# Now drop rules generating glyphs we don't want
		indices = [i for i,sub in enumerate(self.Substitute)
				 if sub in s.glyphs]
		self.Substitute = [self.Substitute[i] for i in indices]
		self.Coverage.remap(indices)
		self.GlyphCount = len(self.Substitute)
		return bool(self.GlyphCount and
			    all(c.subset(s.glyphs)
				for c in self.LookAheadCoverage+self.BacktrackCoverage))
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.SinglePos)
def subset_glyphs(self, s):
	if self.Format == 1:
		return len(self.Coverage.subset(s.glyphs))
	elif self.Format == 2:
		indices = self.Coverage.subset(s.glyphs)
		values = self.Value
		count = len(values)
		self.Value = [values[i] for i in indices if i < count]
		self.ValueCount = len(self.Value)
		return bool(self.ValueCount)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.SinglePos)
def prune_post_subset(self, font, options):
	if not options.hinting:
		# Drop device tables
		self.ValueFormat &= ~0x00F0
	return True

@_add_method(otTables.PairPos)
def subset_glyphs(self, s):
	if self.Format == 1:
		indices = self.Coverage.subset(s.glyphs)
		pairs = self.PairSet
		count = len(pairs)
		self.PairSet = [pairs[i] for i in indices if i < count]
		for p in self.PairSet:
			p.PairValueRecord = [r for r in p.PairValueRecord if r.SecondGlyph in s.glyphs]
			p.PairValueCount = len(p.PairValueRecord)
		# Remove empty pairsets
		indices = [i for i,p in enumerate(self.PairSet) if p.PairValueCount]
		self.Coverage.remap(indices)
		self.PairSet = [self.PairSet[i] for i in indices]
		self.PairSetCount = len(self.PairSet)
		return bool(self.PairSetCount)
	elif self.Format == 2:
		class1_map = [c for c in self.ClassDef1.subset(s.glyphs, remap=True) if c < self.Class1Count]
		class2_map = [c for c in self.ClassDef2.subset(s.glyphs, remap=True) if c < self.Class2Count]
		self.Class1Record = [self.Class1Record[i] for i in class1_map]
		for c in self.Class1Record:
			c.Class2Record = [c.Class2Record[i] for i in class2_map]
		self.Class1Count = len(class1_map)
		self.Class2Count = len(class2_map)
		return bool(self.Class1Count and
					self.Class2Count and
					self.Coverage.subset(s.glyphs))
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.PairPos)
def prune_post_subset(self, font, options):
	if not options.hinting:
		# Drop device tables
		self.ValueFormat1 &= ~0x00F0
		self.ValueFormat2 &= ~0x00F0
	return True

@_add_method(otTables.CursivePos)
def subset_glyphs(self, s):
	if self.Format == 1:
		indices = self.Coverage.subset(s.glyphs)
		records = self.EntryExitRecord
		count = len(records)
		self.EntryExitRecord = [records[i] for i in indices if i < count]
		self.EntryExitCount = len(self.EntryExitRecord)
		return bool(self.EntryExitCount)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.Anchor)
def prune_hints(self):
	# Drop device tables / contour anchor point
	self.ensureDecompiled()
	self.Format = 1

@_add_method(otTables.CursivePos)
def prune_post_subset(self, font, options):
	if not options.hinting:
		for rec in self.EntryExitRecord:
			if rec.EntryAnchor: rec.EntryAnchor.prune_hints()
			if rec.ExitAnchor: rec.ExitAnchor.prune_hints()
	return True

@_add_method(otTables.MarkBasePos)
def subset_glyphs(self, s):
	if self.Format == 1:
		mark_indices = self.MarkCoverage.subset(s.glyphs)
		self.MarkArray.MarkRecord = [self.MarkArray.MarkRecord[i] for i in mark_indices]
		self.MarkArray.MarkCount = len(self.MarkArray.MarkRecord)
		base_indices = self.BaseCoverage.subset(s.glyphs)
		self.BaseArray.BaseRecord = [self.BaseArray.BaseRecord[i] for i in base_indices]
		self.BaseArray.BaseCount = len(self.BaseArray.BaseRecord)
		# Prune empty classes
		class_indices = _uniq_sort(v.Class for v in self.MarkArray.MarkRecord)
		self.ClassCount = len(class_indices)
		for m in self.MarkArray.MarkRecord:
			m.Class = class_indices.index(m.Class)
		for b in self.BaseArray.BaseRecord:
			b.BaseAnchor = [b.BaseAnchor[i] for i in class_indices]
		return bool(self.ClassCount and
			    self.MarkArray.MarkCount and
			    self.BaseArray.BaseCount)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.MarkBasePos)
def prune_post_subset(self, font, options):
		if not options.hinting:
			for m in self.MarkArray.MarkRecord:
				if m.MarkAnchor:
					m.MarkAnchor.prune_hints()
			for b in self.BaseArray.BaseRecord:
				for a in b.BaseAnchor:
					if a:
						a.prune_hints()
		return True

@_add_method(otTables.MarkLigPos)
def subset_glyphs(self, s):
	if self.Format == 1:
		mark_indices = self.MarkCoverage.subset(s.glyphs)
		self.MarkArray.MarkRecord = [self.MarkArray.MarkRecord[i] for i in mark_indices]
		self.MarkArray.MarkCount = len(self.MarkArray.MarkRecord)
		ligature_indices = self.LigatureCoverage.subset(s.glyphs)
		self.LigatureArray.LigatureAttach = [self.LigatureArray.LigatureAttach[i] for i in ligature_indices]
		self.LigatureArray.LigatureCount = len(self.LigatureArray.LigatureAttach)
		# Prune empty classes
		class_indices = _uniq_sort(v.Class for v in self.MarkArray.MarkRecord)
		self.ClassCount = len(class_indices)
		for m in self.MarkArray.MarkRecord:
			m.Class = class_indices.index(m.Class)
		for l in self.LigatureArray.LigatureAttach:
			for c in l.ComponentRecord:
				c.LigatureAnchor = [c.LigatureAnchor[i] for i in class_indices]
		return bool(self.ClassCount and
			    self.MarkArray.MarkCount and
			    self.LigatureArray.LigatureCount)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.MarkLigPos)
def prune_post_subset(self, font, options):
		if not options.hinting:
			for m in self.MarkArray.MarkRecord:
				if m.MarkAnchor:
					m.MarkAnchor.prune_hints()
			for l in self.LigatureArray.LigatureAttach:
				for c in l.ComponentRecord:
					for a in c.LigatureAnchor:
						if a:
							a.prune_hints()
		return True

@_add_method(otTables.MarkMarkPos)
def subset_glyphs(self, s):
	if self.Format == 1:
		mark1_indices = self.Mark1Coverage.subset(s.glyphs)
		self.Mark1Array.MarkRecord = [self.Mark1Array.MarkRecord[i] for i in mark1_indices]
		self.Mark1Array.MarkCount = len(self.Mark1Array.MarkRecord)
		mark2_indices = self.Mark2Coverage.subset(s.glyphs)
		self.Mark2Array.Mark2Record = [self.Mark2Array.Mark2Record[i] for i in mark2_indices]
		self.Mark2Array.MarkCount = len(self.Mark2Array.Mark2Record)
		# Prune empty classes
		class_indices = _uniq_sort(v.Class for v in self.Mark1Array.MarkRecord)
		self.ClassCount = len(class_indices)
		for m in self.Mark1Array.MarkRecord:
			m.Class = class_indices.index(m.Class)
		for b in self.Mark2Array.Mark2Record:
			b.Mark2Anchor = [b.Mark2Anchor[i] for i in class_indices]
		return bool(self.ClassCount and
			    self.Mark1Array.MarkCount and
			    self.Mark2Array.MarkCount)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.MarkMarkPos)
def prune_post_subset(self, font, options):
		if not options.hinting:
			# Drop device tables or contour anchor point
			for m in self.Mark1Array.MarkRecord:
				if m.MarkAnchor:
					m.MarkAnchor.prune_hints()
			for b in self.Mark2Array.Mark2Record:
				for m in b.Mark2Anchor:
					if m:
						m.prune_hints()
		return True

@_add_method(otTables.SingleSubst,
			 otTables.MultipleSubst,
			 otTables.AlternateSubst,
			 otTables.LigatureSubst,
			 otTables.ReverseChainSingleSubst,
			 otTables.SinglePos,
			 otTables.PairPos,
			 otTables.CursivePos,
			 otTables.MarkBasePos,
			 otTables.MarkLigPos,
			 otTables.MarkMarkPos)
def subset_lookups(self, lookup_indices):
	pass

@_add_method(otTables.SingleSubst,
			 otTables.MultipleSubst,
			 otTables.AlternateSubst,
			 otTables.LigatureSubst,
			 otTables.ReverseChainSingleSubst,
			 otTables.SinglePos,
			 otTables.PairPos,
			 otTables.CursivePos,
			 otTables.MarkBasePos,
			 otTables.MarkLigPos,
			 otTables.MarkMarkPos)
def collect_lookups(self):
	return []

@_add_method(otTables.SingleSubst,
			 otTables.MultipleSubst,
			 otTables.AlternateSubst,
			 otTables.LigatureSubst,
			 otTables.ReverseChainSingleSubst,
			 otTables.ContextSubst,
			 otTables.ChainContextSubst,
			 otTables.ContextPos,
			 otTables.ChainContextPos)
def prune_post_subset(self, font, options):
	return True

@_add_method(otTables.SingleSubst,
			 otTables.AlternateSubst,
			 otTables.ReverseChainSingleSubst)
def may_have_non_1to1(self):
	return False

@_add_method(otTables.MultipleSubst,
			 otTables.LigatureSubst,
			 otTables.ContextSubst,
			 otTables.ChainContextSubst)
def may_have_non_1to1(self):
	return True

@_add_method(otTables.ContextSubst,
			 otTables.ChainContextSubst,
			 otTables.ContextPos,
			 otTables.ChainContextPos)
def __subset_classify_context(self):

	class ContextHelper(object):
		def __init__(self, klass, Format):
			if klass.__name__.endswith('Subst'):
				Typ = 'Sub'
				Type = 'Subst'
			else:
				Typ = 'Pos'
				Type = 'Pos'
			if klass.__name__.startswith('Chain'):
				Chain = 'Chain'
				InputIdx = 1
				DataLen = 3
			else:
				Chain = ''
				InputIdx = 0
				DataLen = 1
			ChainTyp = Chain+Typ

			self.Typ = Typ
			self.Type = Type
			self.Chain = Chain
			self.ChainTyp = ChainTyp
			self.InputIdx = InputIdx
			self.DataLen = DataLen

			self.LookupRecord = Type+'LookupRecord'

			if Format == 1:
				Coverage = lambda r: r.Coverage
				ChainCoverage = lambda r: r.Coverage
				ContextData = lambda r:(None,)
				ChainContextData = lambda r:(None, None, None)
				SetContextData = None
				SetChainContextData = None
				RuleData = lambda r:(r.Input,)
				ChainRuleData = lambda r:(r.Backtrack, r.Input, r.LookAhead)
				def SetRuleData(r, d):
					(r.Input,) = d
					(r.GlyphCount,) = (len(x)+1 for x in d)
				def ChainSetRuleData(r, d):
					(r.Backtrack, r.Input, r.LookAhead) = d
					(r.BacktrackGlyphCount,r.InputGlyphCount,r.LookAheadGlyphCount,) = (len(d[0]),len(d[1])+1,len(d[2]))
			elif Format == 2:
				Coverage = lambda r: r.Coverage
				ChainCoverage = lambda r: r.Coverage
				ContextData = lambda r:(r.ClassDef,)
				ChainContextData = lambda r:(r.BacktrackClassDef,
							     r.InputClassDef,
							     r.LookAheadClassDef)
				def SetContextData(r, d):
					(r.ClassDef,) = d
				def SetChainContextData(r, d):
					(r.BacktrackClassDef,
					 r.InputClassDef,
					 r.LookAheadClassDef) = d
				RuleData = lambda r:(r.Class,)
				ChainRuleData = lambda r:(r.Backtrack, r.Input, r.LookAhead)
				def SetRuleData(r, d):
					(r.Class,) = d
					(r.GlyphCount,) = (len(x)+1 for x in d)
				def ChainSetRuleData(r, d):
					(r.Backtrack, r.Input, r.LookAhead) = d
					(r.BacktrackGlyphCount,r.InputGlyphCount,r.LookAheadGlyphCount,) = (len(d[0]),len(d[1])+1,len(d[2]))
			elif Format == 3:
				Coverage = lambda r: r.Coverage[0]
				ChainCoverage = lambda r: r.InputCoverage[0]
				ContextData = None
				ChainContextData = None
				SetContextData = None
				SetChainContextData = None
				RuleData = lambda r: r.Coverage
				ChainRuleData = lambda r:(r.BacktrackCoverage +
							  r.InputCoverage +
							  r.LookAheadCoverage)
				def SetRuleData(r, d):
					(r.Coverage,) = d
					(r.GlyphCount,) = (len(x) for x in d)
				def ChainSetRuleData(r, d):
					(r.BacktrackCoverage, r.InputCoverage, r.LookAheadCoverage) = d
					(r.BacktrackGlyphCount,r.InputGlyphCount,r.LookAheadGlyphCount,) = (len(x) for x in d)
			else:
				assert 0, "unknown format: %s" % Format

			if Chain:
				self.Coverage = ChainCoverage
				self.ContextData = ChainContextData
				self.SetContextData = SetChainContextData
				self.RuleData = ChainRuleData
				self.SetRuleData = ChainSetRuleData
			else:
				self.Coverage = Coverage
				self.ContextData = ContextData
				self.SetContextData = SetContextData
				self.RuleData = RuleData
				self.SetRuleData = SetRuleData

			if Format == 1:
				self.Rule = ChainTyp+'Rule'
				self.RuleCount = ChainTyp+'RuleCount'
				self.RuleSet = ChainTyp+'RuleSet'
				self.RuleSetCount = ChainTyp+'RuleSetCount'
				self.Intersect = lambda glyphs, c, r: [r] if r in glyphs else []
			elif Format == 2:
				self.Rule = ChainTyp+'ClassRule'
				self.RuleCount = ChainTyp+'ClassRuleCount'
				self.RuleSet = ChainTyp+'ClassSet'
				self.RuleSetCount = ChainTyp+'ClassSetCount'
				self.Intersect = lambda glyphs, c, r: (c.intersect_class(glyphs, r) if c
								       else (set(glyphs) if r == 0 else set()))

				self.ClassDef = 'InputClassDef' if Chain else 'ClassDef'
				self.ClassDefIndex = 1 if Chain else 0
				self.Input = 'Input' if Chain else 'Class'

	if self.Format not in [1, 2, 3]:
		return None	# Don't shoot the messenger; let it go
	if not hasattr(self.__class__, "__ContextHelpers"):
		self.__class__.__ContextHelpers = {}
	if self.Format not in self.__class__.__ContextHelpers:
		helper = ContextHelper(self.__class__, self.Format)
		self.__class__.__ContextHelpers[self.Format] = helper
	return self.__class__.__ContextHelpers[self.Format]

@_add_method(otTables.ContextSubst,
			 otTables.ChainContextSubst)
def closure_glyphs(self, s, cur_glyphs):
	c = self.__subset_classify_context()

	indices = c.Coverage(self).intersect(cur_glyphs)
	if not indices:
		return []
	cur_glyphs = c.Coverage(self).intersect_glyphs(cur_glyphs)

	if self.Format == 1:
		ContextData = c.ContextData(self)
		rss = getattr(self, c.RuleSet)
		rssCount = getattr(self, c.RuleSetCount)
		for i in indices:
			if i >= rssCount or not rss[i]: continue
			for r in getattr(rss[i], c.Rule):
				if not r: continue
				if not all(all(c.Intersect(s.glyphs, cd, k) for k in klist)
					   for cd,klist in zip(ContextData, c.RuleData(r))):
					continue
				chaos = set()
				for ll in getattr(r, c.LookupRecord):
					if not ll: continue
					seqi = ll.SequenceIndex
					if seqi in chaos:
						# TODO Can we improve this?
						pos_glyphs = None
					else:
						if seqi == 0:
							pos_glyphs = frozenset([c.Coverage(self).glyphs[i]])
						else:
							pos_glyphs = frozenset([r.Input[seqi - 1]])
					lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
					chaos.add(seqi)
					if lookup.may_have_non_1to1():
						chaos.update(range(seqi, len(r.Input)+2))
					lookup.closure_glyphs(s, cur_glyphs=pos_glyphs)
	elif self.Format == 2:
		ClassDef = getattr(self, c.ClassDef)
		indices = ClassDef.intersect(cur_glyphs)
		ContextData = c.ContextData(self)
		rss = getattr(self, c.RuleSet)
		rssCount = getattr(self, c.RuleSetCount)
		for i in indices:
			if i >= rssCount or not rss[i]: continue
			for r in getattr(rss[i], c.Rule):
				if not r: continue
				if not all(all(c.Intersect(s.glyphs, cd, k) for k in klist)
						   for cd,klist in zip(ContextData, c.RuleData(r))):
					continue
				chaos = set()
				for ll in getattr(r, c.LookupRecord):
					if not ll: continue
					seqi = ll.SequenceIndex
					if seqi in chaos:
						# TODO Can we improve this?
						pos_glyphs = None
					else:
						if seqi == 0:
							pos_glyphs = frozenset(ClassDef.intersect_class(cur_glyphs, i))
						else:
							pos_glyphs = frozenset(ClassDef.intersect_class(s.glyphs, getattr(r, c.Input)[seqi - 1]))
					lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
					chaos.add(seqi)
					if lookup.may_have_non_1to1():
						chaos.update(range(seqi, len(getattr(r, c.Input))+2))
					lookup.closure_glyphs(s, cur_glyphs=pos_glyphs)
	elif self.Format == 3:
		if not all(x.intersect(s.glyphs) for x in c.RuleData(self)):
			return []
		r = self
		chaos = set()
		for ll in getattr(r, c.LookupRecord):
			if not ll: continue
			seqi = ll.SequenceIndex
			if seqi in chaos:
				# TODO Can we improve this?
				pos_glyphs = None
			else:
				if seqi == 0:
					pos_glyphs = frozenset(cur_glyphs)
				else:
					pos_glyphs = frozenset(r.InputCoverage[seqi].intersect_glyphs(s.glyphs))
			lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
			chaos.add(seqi)
			if lookup.may_have_non_1to1():
				chaos.update(range(seqi, len(r.InputCoverage)+1))
			lookup.closure_glyphs(s, cur_glyphs=pos_glyphs)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ContextSubst,
			 otTables.ContextPos,
			 otTables.ChainContextSubst,
			 otTables.ChainContextPos)
def subset_glyphs(self, s):
	c = self.__subset_classify_context()

	if self.Format == 1:
		indices = self.Coverage.subset(s.glyphs)
		rss = getattr(self, c.RuleSet)
		rssCount = getattr(self, c.RuleSetCount)
		rss = [rss[i] for i in indices if i < rssCount]
		for rs in rss:
			if not rs: continue
			ss = getattr(rs, c.Rule)
			ss = [r for r in ss
				  if r and all(all(g in s.glyphs for g in glist)
					       for glist in c.RuleData(r))]
			setattr(rs, c.Rule, ss)
			setattr(rs, c.RuleCount, len(ss))
		# Prune empty rulesets
		indices = [i for i,rs in enumerate(rss) if rs and getattr(rs, c.Rule)]
		self.Coverage.remap(indices)
		rss = [rss[i] for i in indices]
		setattr(self, c.RuleSet, rss)
		setattr(self, c.RuleSetCount, len(rss))
		return bool(rss)
	elif self.Format == 2:
		if not self.Coverage.subset(s.glyphs):
			return False
		ContextData = c.ContextData(self)
		klass_maps = [x.subset(s.glyphs, remap=True) if x else None for x in ContextData]

		# Keep rulesets for class numbers that survived.
		indices = klass_maps[c.ClassDefIndex]
		rss = getattr(self, c.RuleSet)
		rssCount = getattr(self, c.RuleSetCount)
		rss = [rss[i] for i in indices if i < rssCount]
		del rssCount
		# Delete, but not renumber, unreachable rulesets.
		indices = getattr(self, c.ClassDef).intersect(self.Coverage.glyphs)
		rss = [rss if i in indices else None for i,rss in enumerate(rss)]

		for rs in rss:
			if not rs: continue
			ss = getattr(rs, c.Rule)
			ss = [r for r in ss
				  if r and all(all(k in klass_map for k in klist)
					       for klass_map,klist in zip(klass_maps, c.RuleData(r)))]
			setattr(rs, c.Rule, ss)
			setattr(rs, c.RuleCount, len(ss))

			# Remap rule classes
			for r in ss:
				c.SetRuleData(r, [[klass_map.index(k) for k in klist]
						  for klass_map,klist in zip(klass_maps, c.RuleData(r))])

		# Prune empty rulesets
		rss = [rs if rs and getattr(rs, c.Rule) else None for rs in rss]
		while rss and rss[-1] is None:
			del rss[-1]
		setattr(self, c.RuleSet, rss)
		setattr(self, c.RuleSetCount, len(rss))

		# TODO: We can do a second round of remapping class values based
		# on classes that are actually used in at least one rule.	Right
		# now we subset classes to c.glyphs only.	Or better, rewrite
		# the above to do that.

		return bool(rss)
	elif self.Format == 3:
		return all(x.subset(s.glyphs) for x in c.RuleData(self))
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ContextSubst,
			 otTables.ChainContextSubst,
			 otTables.ContextPos,
			 otTables.ChainContextPos)
def subset_lookups(self, lookup_indices):
	c = self.__subset_classify_context()

	if self.Format in [1, 2]:
		for rs in getattr(self, c.RuleSet):
			if not rs: continue
			for r in getattr(rs, c.Rule):
				if not r: continue
				setattr(r, c.LookupRecord,
					[ll for ll in getattr(r, c.LookupRecord)
					 if ll and ll.LookupListIndex in lookup_indices])
				for ll in getattr(r, c.LookupRecord):
					if not ll: continue
					ll.LookupListIndex = lookup_indices.index(ll.LookupListIndex)
	elif self.Format == 3:
		setattr(self, c.LookupRecord,
				[ll for ll in getattr(self, c.LookupRecord)
				 if ll and ll.LookupListIndex in lookup_indices])
		for ll in getattr(self, c.LookupRecord):
			if not ll: continue
			ll.LookupListIndex = lookup_indices.index(ll.LookupListIndex)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ContextSubst,
			 otTables.ChainContextSubst,
			 otTables.ContextPos,
			 otTables.ChainContextPos)
def collect_lookups(self):
	c = self.__subset_classify_context()

	if self.Format in [1, 2]:
		return [ll.LookupListIndex
			for rs in getattr(self, c.RuleSet) if rs
			for r in getattr(rs, c.Rule) if r
			for ll in getattr(r, c.LookupRecord) if ll]
	elif self.Format == 3:
		return [ll.LookupListIndex
			for ll in getattr(self, c.LookupRecord) if ll]
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ExtensionSubst)
def closure_glyphs(self, s, cur_glyphs):
	if self.Format == 1:
		self.ExtSubTable.closure_glyphs(s, cur_glyphs)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ExtensionSubst)
def may_have_non_1to1(self):
	if self.Format == 1:
		return self.ExtSubTable.may_have_non_1to1()
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ExtensionSubst,
			 otTables.ExtensionPos)
def subset_glyphs(self, s):
	if self.Format == 1:
		return self.ExtSubTable.subset_glyphs(s)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ExtensionSubst,
			 otTables.ExtensionPos)
def prune_post_subset(self, font, options):
	if self.Format == 1:
		return self.ExtSubTable.prune_post_subset(font, options)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ExtensionSubst,
			 otTables.ExtensionPos)
def subset_lookups(self, lookup_indices):
	if self.Format == 1:
		return self.ExtSubTable.subset_lookups(lookup_indices)
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ExtensionSubst,
			 otTables.ExtensionPos)
def collect_lookups(self):
	if self.Format == 1:
		return self.ExtSubTable.collect_lookups()
	else:
		assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.Lookup)
def closure_glyphs(self, s, cur_glyphs=None):
	if cur_glyphs is None:
		cur_glyphs = frozenset(s.glyphs)

	# Memoize
	key = id(self)
	doneLookups = s._doneLookups
	count,covered = doneLookups.get(key, (0, None))
	if count != len(s.glyphs):
		count,covered = doneLookups[key] = (len(s.glyphs), set())
	if cur_glyphs.issubset(covered):
		return
	covered.update(cur_glyphs)

	for st in self.SubTable:
		if not st: continue
		st.closure_glyphs(s, cur_glyphs)

@_add_method(otTables.Lookup)
def subset_glyphs(self, s):
	self.SubTable = [st for st in self.SubTable if st and st.subset_glyphs(s)]
	self.SubTableCount = len(self.SubTable)
	return bool(self.SubTableCount)

@_add_method(otTables.Lookup)
def prune_post_subset(self, font, options):
	ret = False
	for st in self.SubTable:
		if not st: continue
		if st.prune_post_subset(font, options): ret = True
	return ret

@_add_method(otTables.Lookup)
def subset_lookups(self, lookup_indices):
	for s in self.SubTable:
		s.subset_lookups(lookup_indices)

@_add_method(otTables.Lookup)
def collect_lookups(self):
	return sum((st.collect_lookups() for st in self.SubTable if st), [])

@_add_method(otTables.Lookup)
def may_have_non_1to1(self):
	return any(st.may_have_non_1to1() for st in self.SubTable if st)

@_add_method(otTables.LookupList)
def subset_glyphs(self, s):
	"""Returns the indices of nonempty lookups."""
	return [i for i,l in enumerate(self.Lookup) if l and l.subset_glyphs(s)]

@_add_method(otTables.LookupList)
def prune_post_subset(self, font, options):
	ret = False
	for l in self.Lookup:
		if not l: continue
		if l.prune_post_subset(font, options): ret = True
	return ret

@_add_method(otTables.LookupList)
def subset_lookups(self, lookup_indices):
	self.ensureDecompiled()
	self.Lookup = [self.Lookup[i] for i in lookup_indices
				   if i < self.LookupCount]
	self.LookupCount = len(self.Lookup)
	for l in self.Lookup:
		l.subset_lookups(lookup_indices)

@_add_method(otTables.LookupList)
def neuter_lookups(self, lookup_indices):
	"""Sets lookups not in lookup_indices to None."""
	self.ensureDecompiled()
	self.Lookup = [l if i in lookup_indices else None for i,l in enumerate(self.Lookup)]

@_add_method(otTables.LookupList)
def closure_lookups(self, lookup_indices):
	"""Returns sorted index of all lookups reachable from lookup_indices."""
	lookup_indices = _uniq_sort(lookup_indices)
	recurse = lookup_indices
	while True:
		recurse_lookups = sum((self.Lookup[i].collect_lookups()
				       for i in recurse if i < self.LookupCount), [])
		recurse_lookups = [l for l in recurse_lookups
				     if l not in lookup_indices and l < self.LookupCount]
		if not recurse_lookups:
			return _uniq_sort(lookup_indices)
		recurse_lookups = _uniq_sort(recurse_lookups)
		lookup_indices.extend(recurse_lookups)
		recurse = recurse_lookups

@_add_method(otTables.Feature)
def subset_lookups(self, lookup_indices):
	""""Returns True if feature is non-empty afterwards."""
	self.LookupListIndex = [l for l in self.LookupListIndex
				  if l in lookup_indices]
	# Now map them.
	self.LookupListIndex = [lookup_indices.index(l)
				for l in self.LookupListIndex]
	self.LookupCount = len(self.LookupListIndex)
	return self.LookupCount or self.FeatureParams

@_add_method(otTables.FeatureList)
def subset_lookups(self, lookup_indices):
	"""Returns the indices of nonempty features."""
	# Note: Never ever drop feature 'pref', even if it's empty.
	# HarfBuzz chooses shaper for Khmer based on presence of this
	# feature.	See thread at:
	# http://lists.freedesktop.org/archives/harfbuzz/2012-November/002660.html
	return [i for i,f in enumerate(self.FeatureRecord)
			if (f.Feature.subset_lookups(lookup_indices) or
				f.FeatureTag == 'pref')]

@_add_method(otTables.FeatureList)
def collect_lookups(self, feature_indices):
	return sum((self.FeatureRecord[i].Feature.LookupListIndex
				for i in feature_indices
				if i < self.FeatureCount), [])

@_add_method(otTables.FeatureList)
def subset_features(self, feature_indices):
	self.ensureDecompiled()
	self.FeatureRecord = [self.FeatureRecord[i] for i in feature_indices]
	self.FeatureCount = len(self.FeatureRecord)
	return bool(self.FeatureCount)

@_add_method(otTables.FeatureTableSubstitution)
def subset_lookups(self, lookup_indices):
	"""Returns the indices of nonempty features."""
	return [r.FeatureIndex for r in self.SubstitutionRecord
			if r.Feature.subset_lookups(lookup_indices)]

@_add_method(otTables.FeatureVariations)
def subset_lookups(self, lookup_indices):
	"""Returns the indices of nonempty features."""
	return sum((f.FeatureTableSubstitution.subset_lookups(lookup_indices)
				for f in self.FeatureVariationRecord), [])

@_add_method(otTables.FeatureVariations)
def collect_lookups(self, feature_indices):
	return sum((r.Feature.LookupListIndex
				for vr in self.FeatureVariationRecord
				for r in vr.FeatureTableSubstitution.SubstitutionRecord
				if r.FeatureIndex in feature_indices), [])

@_add_method(otTables.FeatureTableSubstitution)
def subset_features(self, feature_indices):
	self.ensureDecompiled()
	self.SubstitutionRecord = [r for r in self.SubstitutionRecord
				     if r.FeatureIndex in feature_indices]
	self.SubstitutionCount = len(self.SubstitutionRecord)
	return bool(self.SubstitutionCount)

@_add_method(otTables.FeatureVariations)
def subset_features(self, feature_indices):
	self.ensureDecompiled()
	self.FeaturVariationRecord = [r for r in self.FeatureVariationRecord
					if r.FeatureTableSubstitution.subset_features(feature_indices)]
	self.FeatureVariationCount = len(self.FeatureVariationRecord)
	return bool(self.FeatureVariationCount)

@_add_method(otTables.DefaultLangSys,
			 otTables.LangSys)
def subset_features(self, feature_indices):
	if self.ReqFeatureIndex in feature_indices:
		self.ReqFeatureIndex = feature_indices.index(self.ReqFeatureIndex)
	else:
		self.ReqFeatureIndex = 65535
	self.FeatureIndex = [f for f in self.FeatureIndex if f in feature_indices]
	# Now map them.
	self.FeatureIndex = [feature_indices.index(f) for f in self.FeatureIndex
						      if f in feature_indices]
	self.FeatureCount = len(self.FeatureIndex)
	return bool(self.FeatureCount or self.ReqFeatureIndex != 65535)

@_add_method(otTables.DefaultLangSys,
			 otTables.LangSys)
def collect_features(self):
	feature_indices = self.FeatureIndex[:]
	if self.ReqFeatureIndex != 65535:
		feature_indices.append(self.ReqFeatureIndex)
	return _uniq_sort(feature_indices)

@_add_method(otTables.Script)
def subset_features(self, feature_indices, keepEmptyDefaultLangSys=False):
	if(self.DefaultLangSys and
	   not self.DefaultLangSys.subset_features(feature_indices) and
	   not keepEmptyDefaultLangSys):
		self.DefaultLangSys = None
	self.LangSysRecord = [l for l in self.LangSysRecord
				if l.LangSys.subset_features(feature_indices)]
	self.LangSysCount = len(self.LangSysRecord)
	return bool(self.LangSysCount or self.DefaultLangSys)

@_add_method(otTables.Script)
def collect_features(self):
	feature_indices = [l.LangSys.collect_features() for l in self.LangSysRecord]
	if self.DefaultLangSys:
		feature_indices.append(self.DefaultLangSys.collect_features())
	return _uniq_sort(sum(feature_indices, []))

@_add_method(otTables.ScriptList)
def subset_features(self, feature_indices, retain_empty):
	# https://bugzilla.mozilla.org/show_bug.cgi?id=1331737#c32
	self.ScriptRecord = [s for s in self.ScriptRecord
			       if s.Script.subset_features(feature_indices, s.ScriptTag=='DFLT') or
				  retain_empty]
	self.ScriptCount = len(self.ScriptRecord)
	return bool(self.ScriptCount)

@_add_method(otTables.ScriptList)
def collect_features(self):
	return _uniq_sort(sum((s.Script.collect_features()
			       for s in self.ScriptRecord), []))

# CBLC will inherit it
@_add_method(ttLib.getTableClass('EBLC'))
def subset_glyphs(self, s):
	for strike in self.strikes:
		for indexSubTable in strike.indexSubTables:
			indexSubTable.names = [n for n in indexSubTable.names if n in s.glyphs]
		strike.indexSubTables = [i for i in strike.indexSubTables if i.names]
	self.strikes = [s for s in self.strikes if s.indexSubTables]

	return True

# CBDT will inherit it
@_add_method(ttLib.getTableClass('EBDT'))
def subset_glyphs(self, s):
  self.strikeData = [{g: strike[g] for g in s.glyphs if g in strike}
					 for strike in self.strikeData]
  return True

@_add_method(ttLib.getTableClass('GSUB'))
def closure_glyphs(self, s):
	s.table = self.table
	if self.table.ScriptList:
		feature_indices = self.table.ScriptList.collect_features()
	else:
		feature_indices = []
	if self.table.FeatureList:
		lookup_indices = self.table.FeatureList.collect_lookups(feature_indices)
	else:
		lookup_indices = []
	if getattr(self.table, 'FeatureVariations', None):
		lookup_indices += self.table.FeatureVariations.collect_lookups(feature_indices)
	lookup_indices = _uniq_sort(lookup_indices)
	if self.table.LookupList:
		s._doneLookups = {}
		while True:
			orig_glyphs = frozenset(s.glyphs)
			for i in lookup_indices:
				if i >= self.table.LookupList.LookupCount: continue
				if not self.table.LookupList.Lookup[i]: continue
				self.table.LookupList.Lookup[i].closure_glyphs(s)
			if orig_glyphs == s.glyphs:
				break
		del s._doneLookups
	del s.table

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def subset_glyphs(self, s):
	s.glyphs = s.glyphs_gsubed
	if self.table.LookupList:
		lookup_indices = self.table.LookupList.subset_glyphs(s)
	else:
		lookup_indices = []
	self.subset_lookups(lookup_indices)
	return True

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def retain_empty_scripts(self):
	# https://github.com/fonttools/fonttools/issues/518
	# https://bugzilla.mozilla.org/show_bug.cgi?id=1080739#c15
	return self.__class__ == ttLib.getTableClass('GSUB')

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def subset_lookups(self, lookup_indices):
	"""Retains specified lookups, then removes empty features, language
	systems, and scripts."""
	if self.table.LookupList:
		self.table.LookupList.subset_lookups(lookup_indices)
	if self.table.FeatureList:
		feature_indices = self.table.FeatureList.subset_lookups(lookup_indices)
	else:
		feature_indices = []
	if getattr(self.table, 'FeatureVariations', None):
		feature_indices += self.table.FeatureVariations.subset_lookups(lookup_indices)
	feature_indices = _uniq_sort(feature_indices)
	if self.table.FeatureList:
		self.table.FeatureList.subset_features(feature_indices)
	if getattr(self.table, 'FeatureVariations', None):
		self.table.FeatureVariations.subset_features(feature_indices)
	if self.table.ScriptList:
		self.table.ScriptList.subset_features(feature_indices, self.retain_empty_scripts())

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def neuter_lookups(self, lookup_indices):
	"""Sets lookups not in lookup_indices to None."""
	if self.table.LookupList:
		self.table.LookupList.neuter_lookups(lookup_indices)

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def prune_lookups(self, remap=True):
	"""Remove (default) or neuter unreferenced lookups"""
	if self.table.ScriptList:
		feature_indices = self.table.ScriptList.collect_features()
	else:
		feature_indices = []
	if self.table.FeatureList:
		lookup_indices = self.table.FeatureList.collect_lookups(feature_indices)
	else:
		lookup_indices = []
	if getattr(self.table, 'FeatureVariations', None):
		lookup_indices += self.table.FeatureVariations.collect_lookups(feature_indices)
	lookup_indices = _uniq_sort(lookup_indices)
	if self.table.LookupList:
		lookup_indices = self.table.LookupList.closure_lookups(lookup_indices)
	else:
		lookup_indices = []
	if remap:
		self.subset_lookups(lookup_indices)
	else:
		self.neuter_lookups(lookup_indices)

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def subset_feature_tags(self, feature_tags):
	if self.table.FeatureList:
		feature_indices = \
			[i for i,f in enumerate(self.table.FeatureList.FeatureRecord)
			 if f.FeatureTag in feature_tags]
		self.table.FeatureList.subset_features(feature_indices)
		if getattr(self.table, 'FeatureVariations', None):
			self.table.FeatureVariations.subset_features(feature_indices)
	else:
		feature_indices = []
	if self.table.ScriptList:
		self.table.ScriptList.subset_features(feature_indices, self.retain_empty_scripts())

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def subset_script_tags(self, script_tags):
	if self.table.ScriptList:
		self.table.ScriptList.ScriptRecord = \
			[s for s in self.table.ScriptList.ScriptRecord
			 if s.ScriptTag in script_tags]
		self.table.ScriptList.ScriptCount = len(self.table.ScriptList.ScriptRecord)

@_add_method(ttLib.getTableClass('GSUB'),
			 ttLib.getTableClass('GPOS'))
def prune_features(self):
	"""Remove unreferenced features"""
	if self.table.ScriptList:
		feature_indices = self.table.ScriptList.collect_features()
	else:
		feature_indices = []
	if self.table.FeatureList:
		self.table.FeatureList.subset_features(feature_indices)
	if getattr(self.table, 'FeatureVariations', None):
		self.table.FeatureVariations.subset_features(feature_indices)
	if self.table.ScriptList:
		self.table.ScriptList.subset_features(feature_indices, self.retain_empty_scripts())

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def prune_pre_subset(self, font, options):
	# Drop undesired features
	if '*' not in options.layout_scripts:
		self.subset_script_tags(options.layout_scripts)
	if '*' not in options.layout_features:
		self.subset_feature_tags(options.layout_features)
	# Neuter unreferenced lookups
	self.prune_lookups(remap=False)
	return True

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def remove_redundant_langsys(self):
	table = self.table
	if not table.ScriptList or not table.FeatureList:
		return

	features = table.FeatureList.FeatureRecord

	for s in table.ScriptList.ScriptRecord:
		d = s.Script.DefaultLangSys
		if not d:
			continue
		for lr in s.Script.LangSysRecord[:]:
			l = lr.LangSys
			# Compare d and l
			if len(d.FeatureIndex) != len(l.FeatureIndex):
				continue
			if (d.ReqFeatureIndex == 65535) != (l.ReqFeatureIndex == 65535):
				continue

			if d.ReqFeatureIndex != 65535:
				if features[d.ReqFeatureIndex] != features[l.ReqFeatureIndex]:
					continue

			for i in range(len(d.FeatureIndex)):
				if features[d.FeatureIndex[i]] != features[l.FeatureIndex[i]]:
					break
			else:
				# LangSys and default are equal; delete LangSys
				s.Script.LangSysRecord.remove(lr)

@_add_method(ttLib.getTableClass('GSUB'),
	     ttLib.getTableClass('GPOS'))
def prune_post_subset(self, font, options):
	table = self.table

	self.prune_lookups() # XXX Is this actually needed?!

	if table.LookupList:
		table.LookupList.prune_post_subset(font, options)
		# XXX Next two lines disabled because OTS is stupid and
		# doesn't like NULL offsets here.
		#if not table.LookupList.Lookup:
		#	table.LookupList = None

	if not table.LookupList:
		table.FeatureList = None


	if table.FeatureList:
		self.remove_redundant_langsys()
		# Remove unreferenced features
		self.prune_features()

	# XXX Next two lines disabled because OTS is stupid and
	# doesn't like NULL offsets here.
	#if table.FeatureList and not table.FeatureList.FeatureRecord:
	#	table.FeatureList = None

	# Never drop scripts themselves as them just being available
	# holds semantic significance.
	# XXX Next two lines disabled because OTS is stupid and
	# doesn't like NULL offsets here.
	#if table.ScriptList and not table.ScriptList.ScriptRecord:
	#	table.ScriptList = None

	if not table.FeatureList and hasattr(table, 'FeatureVariations'):
		table.FeatureVariations = None

	if hasattr(table, 'FeatureVariations') and not table.FeatureVariations:
		if table.Version == 0x00010001:
			table.Version = 0x00010000

	return True

@_add_method(ttLib.getTableClass('GDEF'))
def subset_glyphs(self, s):
	glyphs = s.glyphs_gsubed
	table = self.table
	if table.LigCaretList:
		indices = table.LigCaretList.Coverage.subset(glyphs)
		table.LigCaretList.LigGlyph = [table.LigCaretList.LigGlyph[i] for i in indices]
		table.LigCaretList.LigGlyphCount = len(table.LigCaretList.LigGlyph)
	if table.MarkAttachClassDef:
		table.MarkAttachClassDef.classDefs = \
			{g:v for g,v in table.MarkAttachClassDef.classDefs.items()
			 if g in glyphs}
	if table.GlyphClassDef:
		table.GlyphClassDef.classDefs = \
			{g:v for g,v in table.GlyphClassDef.classDefs.items()
			 if g in glyphs}
	if table.AttachList:
		indices = table.AttachList.Coverage.subset(glyphs)
		GlyphCount = table.AttachList.GlyphCount
		table.AttachList.AttachPoint = [table.AttachList.AttachPoint[i]
						for i in indices if i < GlyphCount]
		table.AttachList.GlyphCount = len(table.AttachList.AttachPoint)
	if hasattr(table, "MarkGlyphSetsDef") and table.MarkGlyphSetsDef:
		for coverage in table.MarkGlyphSetsDef.Coverage:
			if coverage:
				coverage.subset(glyphs)

		# TODO: The following is disabled. If enabling, we need to go fixup all
		# lookups that use MarkFilteringSet and map their set.
		# indices = table.MarkGlyphSetsDef.Coverage = \
		#   [c for c in table.MarkGlyphSetsDef.Coverage if c.glyphs]
		# TODO: The following is disabled, as ots doesn't like it. Phew...
		# https://github.com/khaledhosny/ots/issues/172
		# table.MarkGlyphSetsDef.Coverage = [c if c.glyphs else None for c in table.MarkGlyphSetsDef.Coverage]
	return True


def _pruneGDEF(font):
	if 'GDEF' not in font: return
	gdef = font['GDEF']
	table = gdef.table
	if not hasattr(table, 'VarStore'): return

	store = table.VarStore

	usedVarIdxes = set()

	# Collect.
	table.collect_device_varidxes(usedVarIdxes)
	if 'GPOS' in font:
		font['GPOS'].table.collect_device_varidxes(usedVarIdxes)

	# Subset.
	varidx_map = store.subset_varidxes(usedVarIdxes)

	# Map.
	table.remap_device_varidxes(varidx_map)
	if 'GPOS' in font:
		font['GPOS'].table.remap_device_varidxes(varidx_map)

@_add_method(ttLib.getTableClass('GDEF'))
def prune_post_subset(self, font, options):
	table = self.table
	# XXX check these against OTS
	if table.LigCaretList and not table.LigCaretList.LigGlyphCount:
		table.LigCaretList = None
	if table.MarkAttachClassDef and not table.MarkAttachClassDef.classDefs:
		table.MarkAttachClassDef = None
	if table.GlyphClassDef and not table.GlyphClassDef.classDefs:
		table.GlyphClassDef = None
	if table.AttachList and not table.AttachList.GlyphCount:
		table.AttachList = None
	if hasattr(table, "VarStore"):
		_pruneGDEF(font)
		if table.VarStore.VarDataCount == 0:
			if table.Version == 0x00010003:
				table.Version = 0x00010002
	if (not hasattr(table, "MarkGlyphSetsDef") or
		not table.MarkGlyphSetsDef or
		not table.MarkGlyphSetsDef.Coverage):
		table.MarkGlyphSetsDef = None
		if table.Version == 0x00010002:
			table.Version = 0x00010000
	return bool(table.LigCaretList or
		    table.MarkAttachClassDef or
		    table.GlyphClassDef or
		    table.AttachList or
		    (table.Version >= 0x00010002 and table.MarkGlyphSetsDef) or
		    (table.Version >= 0x00010003 and table.VarStore))

@_add_method(ttLib.getTableClass('kern'))
def prune_pre_subset(self, font, options):
	# Prune unknown kern table types
	self.kernTables = [t for t in self.kernTables if hasattr(t, 'kernTable')]
	return bool(self.kernTables)

@_add_method(ttLib.getTableClass('kern'))
def subset_glyphs(self, s):
	glyphs = s.glyphs_gsubed
	for t in self.kernTables:
		t.kernTable = {(a,b):v for (a,b),v in t.kernTable.items()
				       if a in glyphs and b in glyphs}
	self.kernTables = [t for t in self.kernTables if t.kernTable]
	return bool(self.kernTables)

@_add_method(ttLib.getTableClass('vmtx'))
def subset_glyphs(self, s):
	self.metrics = _dict_subset(self.metrics, s.glyphs)
	for g in s.glyphs_emptied:
		self.metrics[g] = (0,0)
	return bool(self.metrics)

@_add_method(ttLib.getTableClass('hmtx'))
def subset_glyphs(self, s):
	self.metrics = _dict_subset(self.metrics, s.glyphs)
	for g in s.glyphs_emptied:
		self.metrics[g] = (0,0)
	return True # Required table

@_add_method(ttLib.getTableClass('hdmx'))
def subset_glyphs(self, s):
	self.hdmx = {sz:_dict_subset(l, s.glyphs) for sz,l in self.hdmx.items()}
	for sz in self.hdmx:
		for g in s.glyphs_emptied:
			self.hdmx[sz][g] = 0
	return bool(self.hdmx)

@_add_method(ttLib.getTableClass('ankr'))
def subset_glyphs(self, s):
	table = self.table.AnchorPoints
	assert table.Format == 0, "unknown 'ankr' format %s" % table.Format
	table.Anchors = {glyph: table.Anchors[glyph] for glyph in s.glyphs
					 if glyph in table.Anchors}
	return len(table.Anchors) > 0

@_add_method(ttLib.getTableClass('bsln'))
def closure_glyphs(self, s):
	table = self.table.Baseline
	if table.Format in (2, 3):
		s.glyphs.add(table.StandardGlyph)

@_add_method(ttLib.getTableClass('bsln'))
def subset_glyphs(self, s):
	table = self.table.Baseline
	if table.Format in (1, 3):
		baselines = {glyph: table.BaselineValues.get(glyph, table.DefaultBaseline)
					 for glyph in s.glyphs}
		if len(baselines) > 0:
			mostCommon, _cnt = Counter(baselines.values()).most_common(1)[0]
			table.DefaultBaseline = mostCommon
			baselines = {glyph: b for glyph, b in baselines.items()
					      if b != mostCommon}
		if len(baselines) > 0:
			table.BaselineValues = baselines
		else:
			table.Format = {1: 0, 3: 2}[table.Format]
			del table.BaselineValues
	return True

@_add_method(ttLib.getTableClass('lcar'))
def subset_glyphs(self, s):
	table = self.table.LigatureCarets
	if table.Format in (0, 1):
		table.Carets = {glyph: table.Carets[glyph] for glyph in s.glyphs
							   if glyph in table.Carets}
		return len(table.Carets) > 0
	else:
		assert False, "unknown 'lcar' format %s" % table.Format

@_add_method(ttLib.getTableClass('gvar'))
def prune_pre_subset(self, font, options):
	if options.notdef_glyph and not options.notdef_outline:
		self.variations[font.glyphOrder[0]] = []
	return True

@_add_method(ttLib.getTableClass('gvar'))
def subset_glyphs(self, s):
	self.variations = _dict_subset(self.variations, s.glyphs)
	self.glyphCount = len(self.variations)
	return bool(self.variations)

def _remap_index_map(s, varidx_map, table_map):
	map_ = {k:varidx_map[v] for k,v in table_map.mapping.items()}
	# Emptied glyphs are remapped to:
	# if GID <= last retained GID, 0/0: delta set for 0/0 is expected to exist & zeros compress well
	# if GID > last retained GID, major/minor of the last retained glyph: will be optimized out by table compiler
	last_idx = varidx_map[table_map.mapping[s.last_retained_glyph]]
	for g,i in s.reverseEmptiedGlyphMap.items():
		map_[g] = last_idx if i > s.last_retained_order else 0
	return map_

@_add_method(ttLib.getTableClass('HVAR'))
def subset_glyphs(self, s):
	table = self.table

	used = set()
	advIdxes_ = set()
	retainAdvMap = False

	if table.AdvWidthMap:
		table.AdvWidthMap.mapping = _dict_subset(table.AdvWidthMap.mapping, s.glyphs)
		used.update(table.AdvWidthMap.mapping.values())
	else:
		used.update(s.reverseOrigGlyphMap.values())
		advIdxes_ = used.copy()
		retainAdvMap = s.options.retain_gids

	if table.LsbMap:
		table.LsbMap.mapping = _dict_subset(table.LsbMap.mapping, s.glyphs)
		used.update(table.LsbMap.mapping.values())
	if table.RsbMap:
		table.RsbMap.mapping = _dict_subset(table.RsbMap.mapping, s.glyphs)
		used.update(table.RsbMap.mapping.values())

	varidx_map = varStore.VarStore_subset_varidxes(table.VarStore, used, retainFirstMap=retainAdvMap, advIdxes=advIdxes_)

	if table.AdvWidthMap:
		table.AdvWidthMap.mapping = _remap_index_map(s, varidx_map, table.AdvWidthMap)
	if table.LsbMap:
		table.LsbMap.mapping = _remap_index_map(s, varidx_map, table.LsbMap)
	if table.RsbMap:
		table.RsbMap.mapping = _remap_index_map(s, varidx_map, table.RsbMap)

	# TODO Return emptiness...
	return True

@_add_method(ttLib.getTableClass('VVAR'))
def subset_glyphs(self, s):
	table = self.table

	used = set()
	advIdxes_ = set()
	retainAdvMap = False

	if table.AdvHeightMap:
		table.AdvHeightMap.mapping = _dict_subset(table.AdvHeightMap.mapping, s.glyphs)
		used.update(table.AdvHeightMap.mapping.values())
	else:
		used.update(s.reverseOrigGlyphMap.values())
		advIdxes_ = used.copy()
		retainAdvMap = s.options.retain_gids

	if table.TsbMap:
		table.TsbMap.mapping = _dict_subset(table.TsbMap.mapping, s.glyphs)
		used.update(table.TsbMap.mapping.values())
	if table.BsbMap:
		table.BsbMap.mapping = _dict_subset(table.BsbMap.mapping, s.glyphs)
		used.update(table.BsbMap.mapping.values())
	if table.VOrgMap:
		table.VOrgMap.mapping = _dict_subset(table.VOrgMap.mapping, s.glyphs)
		used.update(table.VOrgMap.mapping.values())

	varidx_map = varStore.VarStore_subset_varidxes(table.VarStore, used, retainFirstMap=retainAdvMap, advIdxes=advIdxes_)

	if table.AdvHeightMap:
		table.AdvHeightMap.mapping = _remap_index_map(s, varidx_map, table.AdvHeightMap)
	if table.TsbMap:
		table.TsbMap.mapping = _remap_index_map(s, varidx_map, table.TsbMap)
	if table.BsbMap:
		table.BsbMap.mapping = _remap_index_map(s, varidx_map, table.BsbMap)
	if table.VOrgMap:
		table.VOrgMap.mapping = _remap_index_map(s, varidx_map, table.VOrgMap)

	# TODO Return emptiness...
	return True

@_add_method(ttLib.getTableClass('VORG'))
def subset_glyphs(self, s):
	self.VOriginRecords = {g:v for g,v in self.VOriginRecords.items()
				   if g in s.glyphs}
	self.numVertOriginYMetrics = len(self.VOriginRecords)
	return True	# Never drop; has default metrics

@_add_method(ttLib.getTableClass('opbd'))
def subset_glyphs(self, s):
	table = self.table.OpticalBounds
	if table.Format == 0:
		table.OpticalBoundsDeltas = {glyph: table.OpticalBoundsDeltas[glyph]
					     for glyph in s.glyphs
					     if glyph in table.OpticalBoundsDeltas}
		return len(table.OpticalBoundsDeltas) > 0
	elif table.Format == 1:
		table.OpticalBoundsPoints = {glyph: table.OpticalBoundsPoints[glyph]
					     for glyph in s.glyphs
					     if glyph in table.OpticalBoundsPoints}
		return len(table.OpticalBoundsPoints) > 0
	else:
		assert False, "unknown 'opbd' format %s" % table.Format

@_add_method(ttLib.getTableClass('post'))
def prune_pre_subset(self, font, options):
	if not options.glyph_names:
		self.formatType = 3.0
	return True # Required table

@_add_method(ttLib.getTableClass('post'))
def subset_glyphs(self, s):
	self.extraNames = []	# This seems to do it
	return True # Required table

@_add_method(ttLib.getTableClass('prop'))
def subset_glyphs(self, s):
	prop = self.table.GlyphProperties
	if prop.Format == 0:
		return prop.DefaultProperties != 0
	elif prop.Format == 1:
		prop.Properties = {g: prop.Properties.get(g, prop.DefaultProperties)
				   for g in s.glyphs}
		mostCommon, _cnt = Counter(prop.Properties.values()).most_common(1)[0]
		prop.DefaultProperties = mostCommon
		prop.Properties = {g: prop for g, prop in prop.Properties.items()
				   if prop != mostCommon}
		if len(prop.Properties) == 0:
			del prop.Properties
			prop.Format = 0
			return prop.DefaultProperties != 0
		return True
	else:
		assert False, "unknown 'prop' format %s" % prop.Format

@_add_method(ttLib.getTableClass('COLR'))
def closure_glyphs(self, s):
	decompose = s.glyphs
	while decompose:
		layers = set()
		for g in decompose:
			for l in self.ColorLayers.get(g, []):
				layers.add(l.name)
		layers -= s.glyphs
		s.glyphs.update(layers)
		decompose = layers

@_add_method(ttLib.getTableClass('COLR'))
def subset_glyphs(self, s):
	self.ColorLayers = {g: self.ColorLayers[g] for g in s.glyphs if g in self.ColorLayers}
	return bool(self.ColorLayers)

# TODO: prune unused palettes
@_add_method(ttLib.getTableClass('CPAL'))
def prune_post_subset(self, font, options):
	return True

@_add_method(otTables.MathGlyphConstruction)
def closure_glyphs(self, glyphs):
	variants = set()
	for v in self.MathGlyphVariantRecord:
		variants.add(v.VariantGlyph)
	if self.GlyphAssembly:
		for p in self.GlyphAssembly.PartRecords:
			variants.add(p.glyph)
	return variants

@_add_method(otTables.MathVariants)
def closure_glyphs(self, s):
	glyphs = frozenset(s.glyphs)
	variants = set()

	if self.VertGlyphCoverage:
		indices = self.VertGlyphCoverage.intersect(glyphs)
		for i in indices:
			variants.update(self.VertGlyphConstruction[i].closure_glyphs(glyphs))

	if self.HorizGlyphCoverage:
		indices = self.HorizGlyphCoverage.intersect(glyphs)
		for i in indices:
			variants.update(self.HorizGlyphConstruction[i].closure_glyphs(glyphs))

	s.glyphs.update(variants)

@_add_method(ttLib.getTableClass('MATH'))
def closure_glyphs(self, s):
	self.table.MathVariants.closure_glyphs(s)

@_add_method(otTables.MathItalicsCorrectionInfo)
def subset_glyphs(self, s):
	indices = self.Coverage.subset(s.glyphs)
	self.ItalicsCorrection = [self.ItalicsCorrection[i] for i in indices]
	self.ItalicsCorrectionCount = len(self.ItalicsCorrection)
	return bool(self.ItalicsCorrectionCount)

@_add_method(otTables.MathTopAccentAttachment)
def subset_glyphs(self, s):
	indices = self.TopAccentCoverage.subset(s.glyphs)
	self.TopAccentAttachment = [self.TopAccentAttachment[i] for i in indices]
	self.TopAccentAttachmentCount = len(self.TopAccentAttachment)
	return bool(self.TopAccentAttachmentCount)

@_add_method(otTables.MathKernInfo)
def subset_glyphs(self, s):
	indices = self.MathKernCoverage.subset(s.glyphs)
	self.MathKernInfoRecords = [self.MathKernInfoRecords[i] for i in indices]
	self.MathKernCount = len(self.MathKernInfoRecords)
	return bool(self.MathKernCount)

@_add_method(otTables.MathGlyphInfo)
def subset_glyphs(self, s):
	if self.MathItalicsCorrectionInfo:
		self.MathItalicsCorrectionInfo.subset_glyphs(s)
	if self.MathTopAccentAttachment:
		self.MathTopAccentAttachment.subset_glyphs(s)
	if self.MathKernInfo:
		self.MathKernInfo.subset_glyphs(s)
	if self.ExtendedShapeCoverage:
		self.ExtendedShapeCoverage.subset(s.glyphs)
	return True

@_add_method(otTables.MathVariants)
def subset_glyphs(self, s):
	if self.VertGlyphCoverage:
		indices = self.VertGlyphCoverage.subset(s.glyphs)
		self.VertGlyphConstruction = [self.VertGlyphConstruction[i] for i in indices]
		self.VertGlyphCount = len(self.VertGlyphConstruction)

	if self.HorizGlyphCoverage:
		indices = self.HorizGlyphCoverage.subset(s.glyphs)
		self.HorizGlyphConstruction = [self.HorizGlyphConstruction[i] for i in indices]
		self.HorizGlyphCount = len(self.HorizGlyphConstruction)

	return True

@_add_method(ttLib.getTableClass('MATH'))
def subset_glyphs(self, s):
	s.glyphs = s.glyphs_mathed
	self.table.MathGlyphInfo.subset_glyphs(s)
	self.table.MathVariants.subset_glyphs(s)
	return True

@_add_method(ttLib.getTableModule('glyf').Glyph)
def remapComponentsFast(self, glyphidmap):
	if not self.data or struct.unpack(">h", self.data[:2])[0] >= 0:
		return	# Not composite
	data = array.array("B", self.data)
	i = 10
	more = 1
	while more:
		flags =(data[i] << 8) | data[i+1]
		glyphID =(data[i+2] << 8) | data[i+3]
		# Remap
		glyphID = glyphidmap[glyphID]
		data[i+2] = glyphID >> 8
		data[i+3] = glyphID & 0xFF
		i += 4
		flags = int(flags)

		if flags & 0x0001: i += 4	# ARG_1_AND_2_ARE_WORDS
		else: i += 2
		if flags & 0x0008: i += 2	# WE_HAVE_A_SCALE
		elif flags & 0x0040: i += 4	# WE_HAVE_AN_X_AND_Y_SCALE
		elif flags & 0x0080: i += 8	# WE_HAVE_A_TWO_BY_TWO
		more = flags & 0x0020	# MORE_COMPONENTS

	self.data = data.tostring()

@_add_method(ttLib.getTableClass('glyf'))
def closure_glyphs(self, s):
	glyphSet = self.glyphs
	decompose = s.glyphs
	while decompose:
		components = set()
		for g in decompose:
			if g not in glyphSet:
				continue
			gl = glyphSet[g]
			for c in gl.getComponentNames(self):
				components.add(c)
		components -= s.glyphs
		s.glyphs.update(components)
		decompose = components

@_add_method(ttLib.getTableClass('glyf'))
def prune_pre_subset(self, font, options):
	if options.notdef_glyph and not options.notdef_outline:
		g = self[self.glyphOrder[0]]
		# Yay, easy!
		g.__dict__.clear()
		g.data = ""
	return True

@_add_method(ttLib.getTableClass('glyf'))
def subset_glyphs(self, s):
	self.glyphs = _dict_subset(self.glyphs, s.glyphs)
	if not s.options.retain_gids:
		indices = [i for i,g in enumerate(self.glyphOrder) if g in s.glyphs]
		glyphmap = {o:n for n,o in enumerate(indices)}
		for v in self.glyphs.values():
			if hasattr(v, "data"):
				v.remapComponentsFast(glyphmap)
	Glyph = ttLib.getTableModule('glyf').Glyph
	for g in s.glyphs_emptied:
		self.glyphs[g] = Glyph()
		self.glyphs[g].data = ''
	self.glyphOrder = [g for g in self.glyphOrder if g in s.glyphs or g in s.glyphs_emptied]
	# Don't drop empty 'glyf' tables, otherwise 'loca' doesn't get subset.
	return True

@_add_method(ttLib.getTableClass('glyf'))
def prune_post_subset(self, font, options):
	remove_hinting = not options.hinting
	for v in self.glyphs.values():
		v.trim(remove_hinting=remove_hinting)
	return True


@_add_method(ttLib.getTableClass('cmap'))
def closure_glyphs(self, s):
	tables = [t for t in self.tables if t.isUnicode()]

	# Close glyphs
	for table in tables:
		if table.format == 14:
			for cmap in table.uvsDict.values():
				glyphs = {g for u,g in cmap if u in s.unicodes_requested}
				if None in glyphs:
					glyphs.remove(None)
				s.glyphs.update(glyphs)
		else:
			cmap = table.cmap
			intersection = s.unicodes_requested.intersection(cmap.keys())
			s.glyphs.update(cmap[u] for u in intersection)

	# Calculate unicodes_missing
	s.unicodes_missing = s.unicodes_requested.copy()
	for table in tables:
		s.unicodes_missing.difference_update(table.cmap)

@_add_method(ttLib.getTableClass('cmap'))
def prune_pre_subset(self, font, options):
	if not options.legacy_cmap:
		# Drop non-Unicode / non-Symbol cmaps
		self.tables = [t for t in self.tables if t.isUnicode() or t.isSymbol()]
	if not options.symbol_cmap:
		self.tables = [t for t in self.tables if not t.isSymbol()]
	# TODO(behdad) Only keep one subtable?
	# For now, drop format=0 which can't be subset_glyphs easily?
	self.tables = [t for t in self.tables if t.format != 0]
	self.numSubTables = len(self.tables)
	return True # Required table

@_add_method(ttLib.getTableClass('cmap'))
def subset_glyphs(self, s):
	s.glyphs = None # We use s.glyphs_requested and s.unicodes_requested only
	for t in self.tables:
		if t.format == 14:
			# TODO(behdad) We drop all the default-UVS mappings
			# for glyphs_requested.  So it's the caller's responsibility to make
			# sure those are included.
			t.uvsDict = {v:[(u,g) for u,g in l
					      if g in s.glyphs_requested or u in s.unicodes_requested]
				     for v,l in t.uvsDict.items()}
			t.uvsDict = {v:l for v,l in t.uvsDict.items() if l}
		elif t.isUnicode():
			t.cmap = {u:g for u,g in t.cmap.items()
				      if g in s.glyphs_requested or u in s.unicodes_requested}
		else:
			t.cmap = {u:g for u,g in t.cmap.items()
				      if g in s.glyphs_requested}
	self.tables = [t for t in self.tables
			 if (t.cmap if t.format != 14 else t.uvsDict)]
	self.numSubTables = len(self.tables)
	# TODO(behdad) Convert formats when needed.
	# In particular, if we have a format=12 without non-BMP
	# characters, either drop format=12 one or convert it
	# to format=4 if there's not one.
	return True # Required table

@_add_method(ttLib.getTableClass('DSIG'))
def prune_pre_subset(self, font, options):
	# Drop all signatures since they will be invalid
	self.usNumSigs = 0
	self.signatureRecords = []
	return True

@_add_method(ttLib.getTableClass('maxp'))
def prune_pre_subset(self, font, options):
	if not options.hinting:
		if self.tableVersion == 0x00010000:
			self.maxZones = 1
			self.maxTwilightPoints = 0
			self.maxStorage = 0
			self.maxFunctionDefs = 0
			self.maxInstructionDefs = 0
			self.maxStackElements = 0
			self.maxSizeOfInstructions = 0
	return True

@_add_method(ttLib.getTableClass('name'))
def prune_pre_subset(self, font, options):
	nameIDs = set(options.name_IDs)
	fvar = font.get('fvar')
	if fvar:
		nameIDs.update([axis.axisNameID for axis in fvar.axes])
		nameIDs.update([inst.subfamilyNameID for inst in fvar.instances])
		nameIDs.update([inst.postscriptNameID for inst in fvar.instances
				if inst.postscriptNameID != 0xFFFF])
	stat = font.get('STAT')
	if stat:
		if stat.table.AxisValueArray:
			nameIDs.update([val_rec.ValueNameID for val_rec in stat.table.AxisValueArray.AxisValue])
		nameIDs.update([axis_rec.AxisNameID for axis_rec in stat.table.DesignAxisRecord.Axis])
	if '*' not in options.name_IDs:
		self.names = [n for n in self.names if n.nameID in nameIDs]
	if not options.name_legacy:
		# TODO(behdad) Sometimes (eg Apple Color Emoji) there's only a macroman
		# entry for Latin and no Unicode names.
		self.names = [n for n in self.names if n.isUnicode()]
	# TODO(behdad) Option to keep only one platform's
	if '*' not in options.name_languages:
		# TODO(behdad) This is Windows-platform specific!
		self.names = [n for n in self.names
				if n.langID in options.name_languages]
	if options.obfuscate_names:
		namerecs = []
		for n in self.names:
			if n.nameID in [1, 4]:
				n.string = ".\x7f".encode('utf_16_be') if n.isUnicode() else ".\x7f"
			elif n.nameID in [2, 6]:
				n.string = "\x7f".encode('utf_16_be') if n.isUnicode() else "\x7f"
			elif n.nameID == 3:
				n.string = ""
			elif n.nameID in [16, 17, 18]:
				continue
			namerecs.append(n)
		self.names = namerecs
	return True	# Required table


@_add_method(ttLib.getTableClass('head'))
def prune_post_subset(self, font, options):
	# Force re-compiling head table, to update any recalculated values.
	return True


# TODO(behdad) OS/2 ulCodePageRange?
# TODO(behdad) Drop AAT tables.
# TODO(behdad) Drop unneeded GSUB/GPOS Script/LangSys entries.
# TODO(behdad) Drop empty GSUB/GPOS, and GDEF if no GSUB/GPOS left
# TODO(behdad) Drop GDEF subitems if unused by lookups
# TODO(behdad) Avoid recursing too much (in GSUB/GPOS and in CFF)
# TODO(behdad) Text direction considerations.
# TODO(behdad) Text script / language considerations.
# TODO(behdad) Optionally drop 'kern' table if GPOS available
# TODO(behdad) Implement --unicode='*' to choose all cmap'ed
# TODO(behdad) Drop old-spec Indic scripts


class Options(object):

	class OptionError(Exception): pass
	class UnknownOptionError(OptionError): pass

	# spaces in tag names (e.g. "SVG ", "cvt ") are stripped by the argument parser
	_drop_tables_default = ['BASE', 'JSTF', 'DSIG', 'EBDT', 'EBLC',
				'EBSC', 'SVG', 'PCLT', 'LTSH']
	_drop_tables_default += ['Feat', 'Glat', 'Gloc', 'Silf', 'Sill']  # Graphite
	_drop_tables_default += ['sbix']  # Color
	_no_subset_tables_default = ['avar', 'fvar',
				     'gasp', 'head', 'hhea', 'maxp',
				     'vhea', 'OS/2', 'loca', 'name', 'cvt',
				     'fpgm', 'prep', 'VDMX', 'DSIG', 'CPAL',
				     'MVAR', 'cvar', 'STAT']
	_hinting_tables_default = ['cvt', 'cvar', 'fpgm', 'prep', 'hdmx', 'VDMX']

	# Based on HarfBuzz shapers
	_layout_features_groups = {
		# Default shaper
		'common': ['rvrn', 'ccmp', 'liga', 'locl', 'mark', 'mkmk', 'rlig'],
		'fractions': ['frac', 'numr', 'dnom'],
		'horizontal': ['calt', 'clig', 'curs', 'kern', 'rclt'],
		'vertical': ['valt', 'vert', 'vkrn', 'vpal', 'vrt2'],
		'ltr': ['ltra', 'ltrm'],
		'rtl': ['rtla', 'rtlm'],
		# Complex shapers
		'arabic': ['init', 'medi', 'fina', 'isol', 'med2', 'fin2', 'fin3',
			   'cswh', 'mset', 'stch'],
		'hangul': ['ljmo', 'vjmo', 'tjmo'],
		'tibetan': ['abvs', 'blws', 'abvm', 'blwm'],
		'indic': ['nukt', 'akhn', 'rphf', 'rkrf', 'pref', 'blwf', 'half',
			  'abvf', 'pstf', 'cfar', 'vatu', 'cjct', 'init', 'pres',
			  'abvs', 'blws', 'psts', 'haln', 'dist', 'abvm', 'blwm'],
	}
	_layout_features_default = _uniq_sort(sum(
			iter(_layout_features_groups.values()), []))

	def __init__(self, **kwargs):

		self.drop_tables = self._drop_tables_default[:]
		self.no_subset_tables = self._no_subset_tables_default[:]
		self.passthrough_tables = False  # keep/drop tables we can't subset
		self.hinting_tables = self._hinting_tables_default[:]
		self.legacy_kern = False # drop 'kern' table if GPOS available
		self.layout_closure = True
		self.layout_features = self._layout_features_default[:]
		self.layout_scripts = ['*']
		self.ignore_missing_glyphs = False
		self.ignore_missing_unicodes = True
		self.hinting = True
		self.glyph_names = False
		self.legacy_cmap = False
		self.symbol_cmap = False
		self.name_IDs = [0, 1, 2, 3, 4, 5, 6] # https://github.com/fonttools/fonttools/issues/1170#issuecomment-364631225
		self.name_legacy = False
		self.name_languages = [0x0409] # English
		self.obfuscate_names = False # to make webfont unusable as a system font
		self.retain_gids = False
		self.notdef_glyph = True # gid0 for TrueType / .notdef for CFF
		self.notdef_outline = False # No need for notdef to have an outline really
		self.recommended_glyphs = False # gid1, gid2, gid3 for TrueType
		self.recalc_bounds = False # Recalculate font bounding boxes
		self.recalc_timestamp = False # Recalculate font modified timestamp
		self.prune_unicode_ranges = True # Clear unused 'ulUnicodeRange' bits
		self.recalc_average_width = False # update 'xAvgCharWidth'
		self.recalc_max_context = False # update 'usMaxContext'
		self.canonical_order = None # Order tables as recommended
		self.flavor = None  # May be 'woff' or 'woff2'
		self.with_zopfli = False  # use zopfli instead of zlib for WOFF 1.0
		self.desubroutinize = False # Desubroutinize CFF CharStrings
		self.verbose = False
		self.timing = False
		self.xml = False
		self.font_number = -1

		self.set(**kwargs)

	def set(self, **kwargs):
		for k,v in kwargs.items():
			if not hasattr(self, k):
				raise self.UnknownOptionError("Unknown option '%s'" % k)
			setattr(self, k, v)

	def parse_opts(self, argv, ignore_unknown=[]):
		posargs = []
		passthru_options = []
		for a in argv:
			orig_a = a
			if not a.startswith('--'):
				posargs.append(a)
				continue
			a = a[2:]
			i = a.find('=')
			op = '='
			if i == -1:
				if a.startswith("no-"):
					k = a[3:]
					if k == "canonical-order":
						# reorderTables=None is faster than False (the latter
						# still reorders to "keep" the original table order)
						v = None
					else:
						v = False
				else:
					k = a
					v = True
				if k.endswith("?"):
					k = k[:-1]
					v = '?'
			else:
				k = a[:i]
				if k[-1] in "-+":
					op = k[-1]+'='	# Op is '-=' or '+=' now.
					k = k[:-1]
				v = a[i+1:]
			ok = k
			k = k.replace('-', '_')
			if not hasattr(self, k):
				if ignore_unknown is True or ok in ignore_unknown:
					passthru_options.append(orig_a)
					continue
				else:
					raise self.UnknownOptionError("Unknown option '%s'" % a)

			ov = getattr(self, k)
			if v == '?':
					print("Current setting for '%s' is: %s" % (ok, ov))
					continue
			if isinstance(ov, bool):
				v = bool(v)
			elif isinstance(ov, int):
				v = int(v)
			elif isinstance(ov, str):
				v = str(v) # redundant
			elif isinstance(ov, list):
				if isinstance(v, bool):
					raise self.OptionError("Option '%s' requires values to be specified using '='" % a)
				vv = v.replace(',', ' ').split()
				if vv == ['']:
					vv = []
				vv = [int(x, 0) if len(x) and x[0] in "0123456789" else x for x in vv]
				if op == '=':
					v = vv
				elif op == '+=':
					v = ov
					v.extend(vv)
				elif op == '-=':
					v = ov
					for x in vv:
						if x in v:
							v.remove(x)
				else:
					assert False

			setattr(self, k, v)

		return posargs + passthru_options


class Subsetter(object):

	class SubsettingError(Exception): pass
	class MissingGlyphsSubsettingError(SubsettingError): pass
	class MissingUnicodesSubsettingError(SubsettingError): pass

	def __init__(self, options=None):

		if not options:
			options = Options()

		self.options = options
		self.unicodes_requested = set()
		self.glyph_names_requested = set()
		self.glyph_ids_requested = set()

	def populate(self, glyphs=[], gids=[], unicodes=[], text=""):
		self.unicodes_requested.update(unicodes)
		if isinstance(text, bytes):
			text = text.decode("utf_8")
		text_utf32 = text.encode("utf-32-be")
		nchars = len(text_utf32)//4
		for u in struct.unpack('>%dL' % nchars, text_utf32):
			self.unicodes_requested.add(u)
		self.glyph_names_requested.update(glyphs)
		self.glyph_ids_requested.update(gids)

	def _prune_pre_subset(self, font):
		for tag in self._sort_tables(font):
			if (tag.strip() in self.options.drop_tables or
			    (tag.strip() in self.options.hinting_tables and not self.options.hinting) or
			    (tag == 'kern' and (not self.options.legacy_kern and 'GPOS' in font))):
				log.info("%s dropped", tag)
				del font[tag]
				continue

			clazz = ttLib.getTableClass(tag)

			if hasattr(clazz, 'prune_pre_subset'):
				with timer("load '%s'" % tag):
					table = font[tag]
				with timer("prune '%s'" % tag):
					retain = table.prune_pre_subset(font, self.options)
				if not retain:
					log.info("%s pruned to empty; dropped", tag)
					del font[tag]
					continue
				else:
					log.info("%s pruned", tag)

	def _closure_glyphs(self, font):

		realGlyphs = set(font.getGlyphOrder())
		glyph_order = font.getGlyphOrder()

		self.glyphs_requested = set()
		self.glyphs_requested.update(self.glyph_names_requested)
		self.glyphs_requested.update(glyph_order[i]
					     for i in self.glyph_ids_requested
					     if i < len(glyph_order))

		self.glyphs_missing = set()
		self.glyphs_missing.update(self.glyphs_requested.difference(realGlyphs))
		self.glyphs_missing.update(i for i in self.glyph_ids_requested
					     if i >= len(glyph_order))
		if self.glyphs_missing:
			log.info("Missing requested glyphs: %s", self.glyphs_missing)
			if not self.options.ignore_missing_glyphs:
				raise self.MissingGlyphsSubsettingError(self.glyphs_missing)

		self.glyphs = self.glyphs_requested.copy()

		self.unicodes_missing = set()
		if 'cmap' in font:
			with timer("close glyph list over 'cmap'"):
				font['cmap'].closure_glyphs(self)
				self.glyphs.intersection_update(realGlyphs)
		self.glyphs_cmaped = frozenset(self.glyphs)
		if self.unicodes_missing:
			missing = ["U+%04X" % u for u in self.unicodes_missing]
			log.info("Missing glyphs for requested Unicodes: %s", missing)
			if not self.options.ignore_missing_unicodes:
				raise self.MissingUnicodesSubsettingError(missing)
			del missing

		if self.options.notdef_glyph:
			if 'glyf' in font:
				self.glyphs.add(font.getGlyphName(0))
				log.info("Added gid0 to subset")
			else:
				self.glyphs.add('.notdef')
				log.info("Added .notdef to subset")
		if self.options.recommended_glyphs:
			if 'glyf' in font:
				for i in range(min(4, len(font.getGlyphOrder()))):
					self.glyphs.add(font.getGlyphName(i))
				log.info("Added first four glyphs to subset")

		if self.options.layout_closure and 'GSUB' in font:
			with timer("close glyph list over 'GSUB'"):
				log.info("Closing glyph list over 'GSUB': %d glyphs before",
						 len(self.glyphs))
				log.glyphs(self.glyphs, font=font)
				font['GSUB'].closure_glyphs(self)
				self.glyphs.intersection_update(realGlyphs)
				log.info("Closed glyph list over 'GSUB': %d glyphs after",
						 len(self.glyphs))
				log.glyphs(self.glyphs, font=font)
		self.glyphs_gsubed = frozenset(self.glyphs)

		if 'MATH' in font:
			with timer("close glyph list over 'MATH'"):
				log.info("Closing glyph list over 'MATH': %d glyphs before",
						 len(self.glyphs))
				log.glyphs(self.glyphs, font=font)
				font['MATH'].closure_glyphs(self)
				self.glyphs.intersection_update(realGlyphs)
				log.info("Closed glyph list over 'MATH': %d glyphs after",
						 len(self.glyphs))
				log.glyphs(self.glyphs, font=font)
		self.glyphs_mathed = frozenset(self.glyphs)

		for table in ('COLR', 'bsln'):
			if table in font:
				with timer("close glyph list over '%s'" % table):
					log.info("Closing glyph list over '%s': %d glyphs before",
							 table, len(self.glyphs))
					log.glyphs(self.glyphs, font=font)
					font[table].closure_glyphs(self)
					self.glyphs.intersection_update(realGlyphs)
					log.info("Closed glyph list over '%s': %d glyphs after",
							 table, len(self.glyphs))
					log.glyphs(self.glyphs, font=font)

		if 'glyf' in font:
			with timer("close glyph list over 'glyf'"):
				log.info("Closing glyph list over 'glyf': %d glyphs before",
						 len(self.glyphs))
				log.glyphs(self.glyphs, font=font)
				font['glyf'].closure_glyphs(self)
				self.glyphs.intersection_update(realGlyphs)
				log.info("Closed glyph list over 'glyf': %d glyphs after",
						 len(self.glyphs))
				log.glyphs(self.glyphs, font=font)
		self.glyphs_glyfed = frozenset(self.glyphs)

		if 'CFF ' in font:
			with timer("close glyph list over 'CFF '"):
				log.info("Closing glyph list over 'CFF ': %d glyphs before",
						 len(self.glyphs))
				log.glyphs(self.glyphs, font=font)
				font['CFF '].closure_glyphs(self)
				self.glyphs.intersection_update(realGlyphs)
				log.info("Closed glyph list over 'CFF ': %d glyphs after",
						 len(self.glyphs))
				log.glyphs(self.glyphs, font=font)
		self.glyphs_cffed = frozenset(self.glyphs)

		self.glyphs_retained = frozenset(self.glyphs)

		order = font.getReverseGlyphMap()
		self.reverseOrigGlyphMap = {g:order[g] for g in self.glyphs_retained}

		self.last_retained_order = max(self.reverseOrigGlyphMap.values())
		self.last_retained_glyph = font.getGlyphOrder()[self.last_retained_order]

		self.glyphs_emptied = frozenset()
		if self.options.retain_gids:
			self.glyphs_emptied = {g for g in realGlyphs - self.glyphs_retained if order[g] <= self.last_retained_order}

		self.reverseEmptiedGlyphMap = {g:order[g] for g in self.glyphs_emptied}


		log.info("Retaining %d glyphs", len(self.glyphs_retained))

		del self.glyphs

	def _subset_glyphs(self, font):
		for tag in self._sort_tables(font):
			clazz = ttLib.getTableClass(tag)

			if tag.strip() in self.options.no_subset_tables:
				log.info("%s subsetting not needed", tag)
			elif hasattr(clazz, 'subset_glyphs'):
				with timer("subset '%s'" % tag):
					table = font[tag]
					self.glyphs = self.glyphs_retained
					retain = table.subset_glyphs(self)
					del self.glyphs
				if not retain:
					log.info("%s subsetted to empty; dropped", tag)
					del font[tag]
				else:
					log.info("%s subsetted", tag)
			elif self.options.passthrough_tables:
				log.info("%s NOT subset; don't know how to subset", tag)
			else:
				log.warning("%s NOT subset; don't know how to subset; dropped", tag)
				del font[tag]

		with timer("subset GlyphOrder"):
			glyphOrder = font.getGlyphOrder()
			if not self.options.retain_gids:
				glyphOrder = [g for g in glyphOrder if g in self.glyphs_retained]
			else:
				glyphOrder = [g for g in glyphOrder if font.getGlyphID(g) <= self.last_retained_order]

			font.setGlyphOrder(glyphOrder)
			font._buildReverseGlyphOrderDict()


	def _prune_post_subset(self, font):
		for tag in font.keys():
			if tag == 'GlyphOrder': continue
			if tag == 'OS/2' and self.options.prune_unicode_ranges:
				old_uniranges = font[tag].getUnicodeRanges()
				new_uniranges = font[tag].recalcUnicodeRanges(font, pruneOnly=True)
				if old_uniranges != new_uniranges:
					log.info("%s Unicode ranges pruned: %s", tag, sorted(new_uniranges))
				if self.options.recalc_average_width:
					widths = [m[0] for m in font["hmtx"].metrics.values() if m[0] > 0]
					avg_width = otRound(sum(widths) / len(widths))
					if avg_width != font[tag].xAvgCharWidth:
						font[tag].xAvgCharWidth = avg_width
						log.info("%s xAvgCharWidth updated: %d", tag, avg_width)
				if self.options.recalc_max_context:
					max_context = maxCtxFont(font)
					if max_context != font[tag].usMaxContext:
						font[tag].usMaxContext = max_context
						log.info("%s usMaxContext updated: %d", tag, max_context)
			clazz = ttLib.getTableClass(tag)
			if hasattr(clazz, 'prune_post_subset'):
				with timer("prune '%s'" % tag):
					table = font[tag]
					retain = table.prune_post_subset(font, self.options)
				if not retain:
					log.info("%s pruned to empty; dropped", tag)
					del font[tag]
				else:
					log.info("%s pruned", tag)

	def _sort_tables(self, font):
		tagOrder = ['fvar', 'avar', 'gvar', 'name', 'glyf']
		tagOrder = {t: i + 1 for i, t in enumerate(tagOrder)}
		tags = sorted(font.keys(), key=lambda tag: tagOrder.get(tag, 0))
		return [t for t in tags if t != 'GlyphOrder']

	def subset(self, font):
		self._prune_pre_subset(font)
		self._closure_glyphs(font)
		self._subset_glyphs(font)
		self._prune_post_subset(font)


@timer("load font")
def load_font(fontFile,
	      options,
	      allowVID=False,
	      checkChecksums=False,
	      dontLoadGlyphNames=False,
	      lazy=True):

	font = ttLib.TTFont(fontFile,
			    allowVID=allowVID,
			    checkChecksums=checkChecksums,
			    recalcBBoxes=options.recalc_bounds,
			    recalcTimestamp=options.recalc_timestamp,
			    lazy=lazy,
			    fontNumber=options.font_number)

	# Hack:
	#
	# If we don't need glyph names, change 'post' class to not try to
	# load them.	It avoid lots of headache with broken fonts as well
	# as loading time.
	#
	# Ideally ttLib should provide a way to ask it to skip loading
	# glyph names.	But it currently doesn't provide such a thing.
	#
	if dontLoadGlyphNames:
		post = ttLib.getTableClass('post')
		saved = post.decode_format_2_0
		post.decode_format_2_0 = post.decode_format_3_0
		f = font['post']
		if f.formatType == 2.0:
			f.formatType = 3.0
		post.decode_format_2_0 = saved

	return font

@timer("compile and save font")
def save_font(font, outfile, options):
	if options.with_zopfli and options.flavor == "woff":
		from fontTools.ttLib import sfnt
		sfnt.USE_ZOPFLI = True
	font.flavor = options.flavor
	font.save(outfile, reorderTables=options.canonical_order)

def parse_unicodes(s):
	import re
	s = re.sub (r"0[xX]", " ", s)
	s = re.sub (r"[<+>,;&#\\xXuU\n	]", " ", s)
	l = []
	for item in s.split():
		fields = item.split('-')
		if len(fields) == 1:
			l.append(int(item, 16))
		else:
			start,end = fields
			l.extend(range(int(start, 16), int(end, 16)+1))
	return l

def parse_gids(s):
	l = []
	for item in s.replace(',', ' ').split():
		fields = item.split('-')
		if len(fields) == 1:
			l.append(int(fields[0]))
		else:
			l.extend(range(int(fields[0]), int(fields[1])+1))
	return l

def parse_glyphs(s):
	return s.replace(',', ' ').split()

def usage():
	print("usage:", __usage__, file=sys.stderr)
	print("Try pyftsubset --help for more information.\n", file=sys.stderr)

@timer("make one with everything (TOTAL TIME)")
def main(args=None):
	from os.path import splitext
	from fontTools import configLogger

	if args is None:
		args = sys.argv[1:]

	if '--help' in args:
		print(__doc__)
		return 0

	options = Options()
	try:
		args = options.parse_opts(args,
			ignore_unknown=['gids', 'gids-file',
							'glyphs', 'glyphs-file',
							'text', 'text-file',
							'unicodes', 'unicodes-file',
							'output-file'])
	except options.OptionError as e:
		usage()
		print("ERROR:", e, file=sys.stderr)
		return 2

	if len(args) < 2:
		usage()
		return 1

	configLogger(level=logging.INFO if options.verbose else logging.WARNING)
	if options.timing:
		timer.logger.setLevel(logging.DEBUG)
	else:
		timer.logger.disabled = True

	fontfile = args[0]
	args = args[1:]

	subsetter = Subsetter(options=options)
	outfile = None
	glyphs = []
	gids = []
	unicodes = []
	wildcard_glyphs = False
	wildcard_unicodes = False
	text = ""
	for g in args:
		if g == '*':
			wildcard_glyphs = True
			continue
		if g.startswith('--output-file='):
			outfile = g[14:]
			continue
		if g.startswith('--text='):
			text += g[7:]
			continue
		if g.startswith('--text-file='):
			with open(g[12:], encoding='utf-8') as f:
				text += f.read().replace('\n', '')
			continue
		if g.startswith('--unicodes='):
			if g[11:] == '*':
				wildcard_unicodes = True
			else:
				unicodes.extend(parse_unicodes(g[11:]))
			continue
		if g.startswith('--unicodes-file='):
			with open(g[16:]) as f:
				for line in f.readlines():
					unicodes.extend(parse_unicodes(line.split('#')[0]))
			continue
		if g.startswith('--gids='):
			gids.extend(parse_gids(g[7:]))
			continue
		if g.startswith('--gids-file='):
			with open(g[12:]) as f:
				for line in f.readlines():
					gids.extend(parse_gids(line.split('#')[0]))
			continue
		if g.startswith('--glyphs='):
			if g[9:] == '*':
				wildcard_glyphs = True
			else:
				glyphs.extend(parse_glyphs(g[9:]))
			continue
		if g.startswith('--glyphs-file='):
			with open(g[14:]) as f:
				for line in f.readlines():
					glyphs.extend(parse_glyphs(line.split('#')[0]))
			continue
		glyphs.append(g)

	dontLoadGlyphNames = not options.glyph_names and not glyphs
	font = load_font(fontfile, options, dontLoadGlyphNames=dontLoadGlyphNames)

	if outfile is None:
		basename, _ = splitext(fontfile)
		if options.flavor is not None:
			ext = "." + options.flavor.lower()
		else:
			ext = ".ttf" if font.sfntVersion == "\0\1\0\0" else ".otf"
		outfile = basename + ".subset" + ext

	with timer("compile glyph list"):
		if wildcard_glyphs:
			glyphs.extend(font.getGlyphOrder())
		if wildcard_unicodes:
			for t in font['cmap'].tables:
				if t.isUnicode():
					unicodes.extend(t.cmap.keys())
		assert '' not in glyphs

	log.info("Text: '%s'" % text)
	log.info("Unicodes: %s", unicodes)
	log.info("Glyphs: %s", glyphs)
	log.info("Gids: %s", gids)

	subsetter.populate(glyphs=glyphs, gids=gids, unicodes=unicodes, text=text)
	subsetter.subset(font)

	save_font(font, outfile, options)

	if options.verbose:
		import os
		log.info("Input font:% 7d bytes: %s" % (os.path.getsize(fontfile), fontfile))
		log.info("Subset font:% 7d bytes: %s" % (os.path.getsize(outfile), outfile))

	if options.xml:
		font.saveXML(sys.stdout)

	font.close()


__all__ = [
	'Options',
	'Subsetter',
	'load_font',
	'save_font',
	'parse_gids',
	'parse_glyphs',
	'parse_unicodes',
	'main'
]

if __name__ == '__main__':
	sys.exit(main())
