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

"""Python OpenType Layout Subsetter.

Later grown into full OpenType subsetter, supporting all standard tables.
"""

import sys
import struct
import time
import array

from fontTools import ttLib
from fontTools.ttLib.tables import otTables
from fontTools.misc import psCharStrings
from fontTools.pens import basePen


def _add_method(*clazzes):
  """Returns a decorator function that adds a new method to one or
  more classes."""
  def wrapper(method):
    for clazz in clazzes:
      assert clazz.__name__ != 'DefaultTable', 'Oops, table class not found.'
      assert not hasattr(clazz, method.func_name), \
          "Oops, class '%s' has method '%s'." % (clazz.__name__,
                                                 method.func_name)
      setattr(clazz, method.func_name, method)
    return None
  return wrapper

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

def _set_update(s, *others):
  # Jython's set.update only takes one other argument.
  # Emulate real set.update...
  for other in others:
    s.update(other)


@_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.iteritems() 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.iteritems()
              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 = dict((g,v) for g,v in self.classDefs.iteritems() 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 []) +
      self.classDefs.values())
  if remap:
    self.remap(indices)
  return indices

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

@_add_method(otTables.SingleSubst)
def closure_glyphs(self, s, cur_glyphs=None):
  if cur_glyphs == None: cur_glyphs = s.glyphs
  if self.Format in [1, 2]:
    s.glyphs.update(v for g,v in self.mapping.iteritems() if g in cur_glyphs)
  else:
    assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.SingleSubst)
def subset_glyphs(self, s):
  if self.Format in [1, 2]:
    self.mapping = dict((g,v) for g,v in self.mapping.iteritems()
                        if g in s.glyphs and v in s.glyphs)
    return bool(self.mapping)
  else:
    assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.MultipleSubst)
def closure_glyphs(self, s, cur_glyphs=None):
  if cur_glyphs == None: cur_glyphs = s.glyphs
  if self.Format == 1:
    indices = self.Coverage.intersect(cur_glyphs)
    _set_update(s.glyphs, *(self.Sequence[i].Substitute for i in indices))
  else:
    assert 0, "unknown format: %s" % self.Format

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

@_add_method(otTables.AlternateSubst)
def closure_glyphs(self, s, cur_glyphs=None):
  if cur_glyphs == None: cur_glyphs = s.glyphs
  if self.Format == 1:
    _set_update(s.glyphs, *(vlist for g,vlist in self.alternates.iteritems()
                            if g in cur_glyphs))
  else:
    assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.AlternateSubst)
def subset_glyphs(self, s):
  if self.Format == 1:
    self.alternates = dict((g,vlist)
                           for g,vlist in self.alternates.iteritems()
                           if g in s.glyphs and
                              all(v in s.glyphs for v in vlist))
    return bool(self.alternates)
  else:
    assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.LigatureSubst)
def closure_glyphs(self, s, cur_glyphs=None):
  if cur_glyphs == None: cur_glyphs = s.glyphs
  if self.Format == 1:
    _set_update(s.glyphs, *([seq.LigGlyph for seq in seqs
                             if all(c in s.glyphs for c in seq.Component)]
                            for g,seqs in self.ligatures.iteritems()
                            if g in cur_glyphs))
  else:
    assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.LigatureSubst)
def subset_glyphs(self, s):
  if self.Format == 1:
    self.ligatures = dict((g,v) for g,v in self.ligatures.iteritems()
                          if g in s.glyphs)
    self.ligatures = dict((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.iteritems())
    self.ligatures = dict((g,v) for g,v in self.ligatures.iteritems() if v)
    return bool(self.ligatures)
  else:
    assert 0, "unknown format: %s" % self.Format

@_add_method(otTables.ReverseChainSingleSubst)
def closure_glyphs(self, s, cur_glyphs=None):
  if cur_glyphs == None: cur_glyphs = s.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)
    self.Value = [self.Value[i] for i in indices]
    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, 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)
    self.PairSet = [self.PairSet[i] for i in indices]
    for p in self.PairSet:
      p.PairValueRecord = [r for r in p.PairValueRecord
                           if r.SecondGlyph in s.glyphs]
      p.PairValueCount = len(p.PairValueRecord)
    self.PairSet = [p for p in self.PairSet if p.PairValueCount]
    self.PairSetCount = len(self.PairSet)
    return bool(self.PairSetCount)
  elif self.Format == 2:
    class1_map = self.ClassDef1.subset(s.glyphs, remap=True)
    class2_map = self.ClassDef2.subset(s.glyphs, remap=True)
    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, 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)
    self.EntryExitRecord = [self.EntryExitRecord[i] for i in indices]
    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.Format = 1

@_add_method(otTables.CursivePos)
def prune_post_subset(self, 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, options):
    if not options.hinting:
      for m in self.MarkArray.MarkRecord:
        m.MarkAnchor.prune_hints()
      for b in self.BaseArray.BaseRecord:
        for a in b.BaseAnchor:
          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, options):
    if not options.hinting:
      for m in self.MarkArray.MarkRecord:
        m.MarkAnchor.prune_hints()
      for l in self.LigatureArray.LigatureAttach:
        for c in l.ComponentRecord:
          for a in c.LigatureAnchor:
            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, options):
    if not options.hinting:
      # Drop device tables or contour anchor point
      for m in self.Mark1Array.MarkRecord:
        m.MarkAnchor.prune_hints()
      for b in self.Mark2Array.Mark2Record:
        for m in b.Mark2Anchor:
          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.ContextSubst,
             otTables.ChainContextSubst,
             otTables.ReverseChainSingleSubst,
             otTables.SinglePos,
             otTables.PairPos,
             otTables.CursivePos,
             otTables.MarkBasePos,
             otTables.MarkLigPos,
             otTables.MarkMarkPos,
             otTables.ContextPos,
             otTables.ChainContextPos)
def prune_pre_subset(self, options):
  return True

@_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, 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 __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'
      else:
        Chain = ''
      ChainTyp = Chain+Typ

      self.Typ = Typ
      self.Type = Type
      self.Chain = Chain
      self.ChainTyp = ChainTyp

      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)
        RuleData = lambda r:(r.Input,)
        ChainRuleData = lambda r:(r.Backtrack, r.Input, r.LookAhead)
        SetRuleData = None
        ChainSetRuleData = None
      elif Format == 2:
        Coverage = lambda r: r.Coverage
        ChainCoverage = lambda r: r.Coverage
        ContextData = lambda r:(r.ClassDef,)
        ChainContextData = lambda r:(r.LookAheadClassDef,
                                      r.InputClassDef,
                                      r.BacktrackClassDef)
        RuleData = lambda r:(r.Class,)
        ChainRuleData = lambda r:(r.LookAhead, r.Input, r.Backtrack)
        def SetRuleData(r, d):(r.Class,) = d
        def ChainSetRuleData(r, d):(r.LookAhead, r.Input, r.Backtrack) = d
      elif Format == 3:
        Coverage = lambda r: r.Coverage[0]
        ChainCoverage = lambda r: r.InputCoverage[0]
        ContextData = None
        ChainContextData = None
        RuleData = lambda r: r.Coverage
        ChainRuleData = lambda r:(r.LookAheadCoverage +
                                   r.InputCoverage +
                                   r.BacktrackCoverage)
        SetRuleData = None
        ChainSetRuleData = None
      else:
        assert 0, "unknown format: %s" % Format

      if Chain:
        self.Coverage = ChainCoverage
        self.ContextData = ChainContextData
        self.RuleData = ChainRuleData
        self.SetRuleData = ChainSetRuleData
      else:
        self.Coverage = Coverage
        self.ContextData = ContextData
        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)

        self.ClassDef = 'InputClassDef' if Chain else 'ClassDef'
        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=None):
  if cur_glyphs == None: cur_glyphs = s.glyphs
  c = self.__classify_context()

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

  if self.Format == 1:
    ContextData = c.ContextData(self)
    rss = getattr(self, c.RuleSet)
    for i in indices:
      if not rss[i]: continue
      for r in getattr(rss[i], c.Rule):
        if not r: continue
        if all(all(c.Intersect(s.glyphs, cd, k) for k in klist)
          for cd,klist in zip(ContextData, c.RuleData(r))):
          chaos = False
          for ll in getattr(r, c.LookupRecord):
            if not ll: continue
            seqi = ll.SequenceIndex
            if chaos:
              pos_glyphs = s.glyphs
            else:
              if seqi == 0:
                pos_glyphs = set([c.Coverage(self).glyphs[i]])
              else:
                pos_glyphs = set([r.Input[seqi - 1]])
            lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
            chaos = chaos or lookup.may_have_non_1to1()
            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)
    for i in indices:
      if not rss[i]: continue
      for r in getattr(rss[i], c.Rule):
        if not r: continue
        if all(all(c.Intersect(s.glyphs, cd, k) for k in klist)
          for cd,klist in zip(ContextData, c.RuleData(r))):
          chaos = False
          for ll in getattr(r, c.LookupRecord):
            if not ll: continue
            seqi = ll.SequenceIndex
            if chaos:
              pos_glyphs = s.glyphs
            else:
              if seqi == 0:
                pos_glyphs = ClassDef.intersect_class(cur_glyphs, i)
              else:
                pos_glyphs = ClassDef.intersect_class(s.glyphs,
                                                      getattr(r, c.Input)[seqi - 1])
            lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
            chaos = chaos or lookup.may_have_non_1to1()
            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 = False
    for ll in getattr(r, c.LookupRecord):
      if not ll: continue
      seqi = ll.SequenceIndex
      if chaos:
        pos_glyphs = s.glyphs
      else:
        if seqi == 0:
          pos_glyphs = cur_glyphs
        else:
          pos_glyphs = r.InputCoverage[seqi].intersect_glyphs(s.glyphs)
      lookup = s.table.LookupList.Lookup[ll.LookupListIndex]
      chaos = chaos or lookup.may_have_non_1to1()
      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.__classify_context()

  if self.Format == 1:
    indices = self.Coverage.subset(s.glyphs)
    rss = getattr(self, c.RuleSet)
    rss = [rss[i] for i in indices]
    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 subrulesets
    rss = [rs for rs in rss if rs and getattr(rs, c.Rule)]
    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
    indices = getattr(self, c.ClassDef).subset(self.Coverage.glyphs,
                                                 remap=False)
    rss = getattr(self, c.RuleSet)
    rss = [rss[i] for i in indices]
    ContextData = c.ContextData(self)
    klass_maps = [x.subset(s.glyphs, remap=True) for x in ContextData]
    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 subrulesets
    rss = [rs for rs in rss if rs and getattr(rs, c.Rule)]
    setattr(self, c.RuleSet, rss)
    setattr(self, c.RuleSetCount, len(rss))
    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.__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.__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=None):
  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 prune_pre_subset(self, options):
  if self.Format == 1:
    return self.ExtSubTable.prune_pre_subset(options)
  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, options):
  if self.Format == 1:
    return self.ExtSubTable.prune_post_subset(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):
  for st in self.SubTable:
    if not st: continue
    st.closure_glyphs(s, cur_glyphs)

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

@_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, options):
  ret = False
  for st in self.SubTable:
    if not st: continue
    if st.prune_post_subset(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 _uniq_sort(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 prune_pre_subset(self, options):
  ret = False
  for l in self.Lookup:
    if not l: continue
    if l.prune_pre_subset(options): ret = True
  return ret

@_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, options):
  ret = False
  for l in self.Lookup:
    if not l: continue
    if l.prune_post_subset(options): ret = True
  return ret

@_add_method(otTables.LookupList)
def subset_lookups(self, lookup_indices):
  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 closure_lookups(self, 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):
  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

@_add_method(otTables.Feature)
def collect_lookups(self):
  return self.LookupListIndex[:]

@_add_method(otTables.FeatureList)
def subset_lookups(self, lookup_indices):
  "Returns the indices of nonempty features."
  feature_indices = [i for i,f in enumerate(self.FeatureRecord)
                     if f.Feature.subset_lookups(lookup_indices)]
  self.subset_features(feature_indices)
  return feature_indices

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

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

@_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):
  if(self.DefaultLangSys and
      not self.DefaultLangSys.subset_features(feature_indices)):
    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):
  self.ScriptRecord = [s for s in self.ScriptRecord
                       if s.Script.subset_features(feature_indices)]
  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), []))

@_add_method(ttLib.getTableClass('GSUB'))
def closure_glyphs(self, s):
  s.table = self.table
  feature_indices = self.table.ScriptList.collect_features()
  lookup_indices = self.table.FeatureList.collect_lookups(feature_indices)
  while True:
    orig_glyphs = s.glyphs.copy()
    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.table

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

@_add_method(ttLib.getTableClass('GSUB'),
             ttLib.getTableClass('GPOS'))
def subset_lookups(self, lookup_indices):
  """Retrains specified lookups, then removes empty features, language
     systems, and scripts."""
  self.table.LookupList.subset_lookups(lookup_indices)
  feature_indices = self.table.FeatureList.subset_lookups(lookup_indices)
  self.table.ScriptList.subset_features(feature_indices)

@_add_method(ttLib.getTableClass('GSUB'),
             ttLib.getTableClass('GPOS'))
def prune_lookups(self):
  "Remove unreferenced lookups"
  feature_indices = self.table.ScriptList.collect_features()
  lookup_indices = self.table.FeatureList.collect_lookups(feature_indices)
  lookup_indices = self.table.LookupList.closure_lookups(lookup_indices)
  self.subset_lookups(lookup_indices)

@_add_method(ttLib.getTableClass('GSUB'),
             ttLib.getTableClass('GPOS'))
def subset_feature_tags(self, feature_tags):
  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)
  self.table.ScriptList.subset_features(feature_indices)

@_add_method(ttLib.getTableClass('GSUB'),
             ttLib.getTableClass('GPOS'))
def prune_pre_subset(self, options):
  if '*' not in options.layout_features:
    self.subset_feature_tags(options.layout_features)
  self.prune_lookups()
  self.table.LookupList.prune_pre_subset(options);
  return True

@_add_method(ttLib.getTableClass('GSUB'),
             ttLib.getTableClass('GPOS'))
def prune_post_subset(self, options):
  self.table.LookupList.prune_post_subset(options);
  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 not table.LigCaretList.LigGlyphCount:
      table.LigCaretList = None
  if table.MarkAttachClassDef:
    table.MarkAttachClassDef.classDefs = dict((g,v) for g,v in
                                              table.MarkAttachClassDef.
                                                classDefs.iteritems()
                                              if g in glyphs)
    if not table.MarkAttachClassDef.classDefs:
      table.MarkAttachClassDef = None
  if table.GlyphClassDef:
    table.GlyphClassDef.classDefs = dict((g,v) for g,v in
                                         table.GlyphClassDef.
                                           classDefs.iteritems()
                                         if g in glyphs)
    if not table.GlyphClassDef.classDefs:
      table.GlyphClassDef = None
  if table.AttachList:
    indices = table.AttachList.Coverage.subset(glyphs)
    table.AttachList.AttachPoint = [table.AttachList.AttachPoint[i]
                                    for i in indices]
    table.AttachList.GlyphCount = len(table.AttachList.AttachPoint)
    if not table.AttachList.GlyphCount:
      table.AttachList = None
  return bool(table.LigCaretList or
               table.MarkAttachClassDef or
               table.GlyphClassDef or
               table.AttachList)

@_add_method(ttLib.getTableClass('kern'))
def prune_pre_subset(self, 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 = dict(((a,b),v) for (a,b),v in t.kernTable.iteritems()
                       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'),
             ttLib.getTableClass('hmtx'))
def subset_glyphs(self, s):
  self.metrics = dict((g,v) for g,v in self.metrics.iteritems() if g in s.glyphs)
  return bool(self.metrics)

@_add_method(ttLib.getTableClass('hdmx'))
def subset_glyphs(self, s):
  self.hdmx = dict((sz,_dict((g,v) for g,v in l.iteritems() if g in s.glyphs))
                   for sz,l in self.hdmx.iteritems())
  return bool(self.hdmx)

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

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

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

@_add_method(ttLib.getTableModule('glyf').Glyph)
def remapComponentsFast(self, indices):
  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 = indices.index(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):
  decompose = s.glyphs
  while True:
    components = set()
    for g in decompose:
      if g not in self.glyphs:
        continue
      gl = self.glyphs[g]
      for c in gl.getComponentNames(self):
        if c not in s.glyphs:
          components.add(c)
    components = set(c for c in components if c not in s.glyphs)
    if not components:
      break
    decompose = components
    s.glyphs.update(components)

@_add_method(ttLib.getTableClass('glyf'))
def prune_pre_subset(self, 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((g,v) for g,v in self.glyphs.iteritems() if g in s.glyphs)
  indices = [i for i,g in enumerate(self.glyphOrder) if g in s.glyphs]
  for v in self.glyphs.itervalues():
    if hasattr(v, "data"):
      v.remapComponentsFast(indices)
    else:
      pass  # No need
  self.glyphOrder = [g for g in self.glyphOrder if g in s.glyphs]
  # Don't drop empty 'glyf' tables, otherwise 'loca' doesn't get subset.
  return True

@_add_method(ttLib.getTableClass('glyf'))
def prune_post_subset(self, options):
  if not options.hinting:
    for v in self.glyphs.itervalues():
      v.removeHinting()
  return True

@_add_method(ttLib.getTableClass('CFF '))
def prune_pre_subset(self, options):
  cff = self.cff
  # CFF table must have one font only
  cff.fontNames = cff.fontNames[:1]

  if options.notdef_glyph and not options.notdef_outline:
    for fontname in cff.keys():
      font = cff[fontname]
      c,_ = font.CharStrings.getItemAndSelector('.notdef')
      # XXX we should preserve the glyph width
      c.bytecode = '\x0e' # endchar
      c.program = None

  return True # bool(cff.fontNames)

@_add_method(ttLib.getTableClass('CFF '))
def subset_glyphs(self, s):
  cff = self.cff
  for fontname in cff.keys():
    font = cff[fontname]
    cs = font.CharStrings

    # Load all glyphs
    for g in font.charset:
      if g not in s.glyphs: continue
      c,sel = cs.getItemAndSelector(g)

    if cs.charStringsAreIndexed:
      indices = [i for i,g in enumerate(font.charset) if g in s.glyphs]
      csi = cs.charStringsIndex
      csi.items = [csi.items[i] for i in indices]
      csi.count = len(csi.items)
      del csi.file, csi.offsets
      if hasattr(font, "FDSelect"):
        sel = font.FDSelect
        sel.format = None
        sel.gidArray = [sel.gidArray[i] for i in indices]
      cs.charStrings = dict((g,indices.index(v))
                            for g,v in cs.charStrings.iteritems()
                            if g in s.glyphs)
    else:
      cs.charStrings = dict((g,v)
                            for g,v in cs.charStrings.iteritems()
                            if g in s.glyphs)
    font.charset = [g for g in font.charset if g in s.glyphs]
    font.numGlyphs = len(font.charset)

  return True # any(cff[fontname].numGlyphs for fontname in cff.keys())

@_add_method(psCharStrings.T2CharString)
def subset_subroutines(self, subrs, gsubrs):
  p = self.program
  assert len(p)
  for i in xrange(1, len(p)):
    if p[i] == 'callsubr':
      assert type(p[i-1]) is int
      p[i-1] = subrs._used.index(p[i-1] + subrs._old_bias) - subrs._new_bias
    elif p[i] == 'callgsubr':
      assert type(p[i-1]) is int
      p[i-1] = gsubrs._used.index(p[i-1] + gsubrs._old_bias) - gsubrs._new_bias

@_add_method(psCharStrings.T2CharString)
def drop_hints(self):
  hints = self._hints

  if hints.has_hint:
    self.program = self.program[hints.last_hint:]
    if hasattr(self, 'width'):
      # Insert width back if needed
      if self.width != self.private.defaultWidthX:
        self.program.insert(0, self.width - self.private.nominalWidthX)

  if hints.has_hintmask:
    i = 0
    p = self.program
    while i < len(p):
      if p[i] in ['hintmask', 'cntrmask']:
        assert i + 1 <= len(p)
        del p[i:i+2]
        continue
      i += 1

  assert len(self.program)

  del self._hints

class _MarkingT2Decompiler(psCharStrings.SimpleT2Decompiler):

  def __init__(self, localSubrs, globalSubrs):
    psCharStrings.SimpleT2Decompiler.__init__(self,
                                              localSubrs,
                                              globalSubrs)
    for subrs in [localSubrs, globalSubrs]:
      if subrs and not hasattr(subrs, "_used"):
        subrs._used = set()

  def op_callsubr(self, index):
    self.localSubrs._used.add(self.operandStack[-1]+self.localBias)
    psCharStrings.SimpleT2Decompiler.op_callsubr(self, index)

  def op_callgsubr(self, index):
    self.globalSubrs._used.add(self.operandStack[-1]+self.globalBias)
    psCharStrings.SimpleT2Decompiler.op_callgsubr(self, index)

class _DehintingT2Decompiler(psCharStrings.SimpleT2Decompiler):

  class Hints:
    def __init__(self):
      # Whether calling this charstring produces any hint stems
      self.has_hint = False
      # Index to start at to drop all hints
      self.last_hint = 0
      # Index up to which we know more hints are possible.  Only
      # relevant if status is 0 or 1.
      self.last_checked = 0
      # The status means:
      # 0: after dropping hints, this charstring is empty
      # 1: after dropping hints, there may be more hints continuing after this
      # 2: no more hints possible after this charstring
      self.status = 0
      # Has hintmask instructions; not recursive
      self.has_hintmask = False
    pass

  def __init__(self, css, localSubrs, globalSubrs):
    self._css = css
    psCharStrings.SimpleT2Decompiler.__init__(self,
                                              localSubrs,
                                              globalSubrs)

  def execute(self, charString):
    old_hints = charString._hints if hasattr(charString, '_hints') else None
    charString._hints = self.Hints()

    psCharStrings.SimpleT2Decompiler.execute(self, charString)

    hints = charString._hints

    if hints.has_hint or hints.has_hintmask:
      self._css.add(charString)

    if hints.status != 2:
      # Check from last_check, make sure we didn't have any operators.
      for i in xrange(hints.last_checked, len(charString.program) - 1):
        if type(charString.program[i]) == str:
          hints.status = 2
          break;
        else:
          hints.status = 1 # There's *something* here
      hints.last_checked = len(charString.program)

    if old_hints:
      assert hints.__dict__ == old_hints.__dict__

  def op_callsubr(self, index):
    subr = self.localSubrs[self.operandStack[-1]+self.localBias]
    psCharStrings.SimpleT2Decompiler.op_callsubr(self, index)
    self.processSubr(index, subr)

  def op_callgsubr(self, index):
    subr = self.globalSubrs[self.operandStack[-1]+self.globalBias]
    psCharStrings.SimpleT2Decompiler.op_callgsubr(self, index)
    self.processSubr(index, subr)

  def op_hstem(self, index):
    psCharStrings.SimpleT2Decompiler.op_hstem(self, index)
    self.processHint(index)
  def op_vstem(self, index):
    psCharStrings.SimpleT2Decompiler.op_vstem(self, index)
    self.processHint(index)
  def op_hstemhm(self, index):
    psCharStrings.SimpleT2Decompiler.op_hstemhm(self, index)
    self.processHint(index)
  def op_vstemhm(self, index):
    psCharStrings.SimpleT2Decompiler.op_vstemhm(self, index)
    self.processHint(index)
  def op_hintmask(self, index):
    psCharStrings.SimpleT2Decompiler.op_hintmask(self, index)
    self.processHintmask(index)
  def op_cntrmask(self, index):
    psCharStrings.SimpleT2Decompiler.op_cntrmask(self, index)
    self.processHintmask(index)

  def processHintmask(self, index):
    cs = self.callingStack[-1]
    hints = cs._hints
    hints.has_hintmask = True
    if hints.status != 2 and hints.has_hint:
      # Check from last_check, see if we may be an implicit vstem
      for i in xrange(hints.last_checked, index - 1):
        if type(cs.program[i]) == str:
          hints.status = 2
          break;
      if hints.status != 2:
        # We are an implicit vstem
        hints.last_hint = index + 1
        hints.status = 0
      hints.last_checked = index + 1

  def processHint(self, index):
    cs = self.callingStack[-1]
    hints = cs._hints
    hints.has_hint = True
    hints.last_hint = index
    hints.last_checked = index

  def processSubr(self, index, subr):
    cs = self.callingStack[-1]
    hints = cs._hints
    subr_hints = subr._hints

    if subr_hints.has_hint:
      if hints.status != 2:
        hints.has_hint = True
        hints.last_checked = index
        hints.status = subr_hints.status
        # Decide where to chop off from
        if subr_hints.status == 0:
          hints.last_hint = index
        else:
          hints.last_hint = index - 2 # Leave the subr call in
      else:
        # In my understanding, this is a font bug.  Ie. it has hint stems
        # *after* path construction.  I've seen this in widespread fonts.
        # Best to ignore the hints I suppose...
        pass
        #assert 0
    else:
      hints.status = max(hints.status, subr_hints.status)
      if hints.status != 2:
        # Check from last_check, make sure we didn't have
        # any operators.
        for i in xrange(hints.last_checked, index - 1):
          if type(cs.program[i]) == str:
            hints.status = 2
            break;
        hints.last_checked = index

@_add_method(ttLib.getTableClass('CFF '))
def prune_post_subset(self, options):
  cff = self.cff
  for fontname in cff.keys():
    font = cff[fontname]
    cs = font.CharStrings


    #
    # Drop unused FontDictionaries
    #
    if hasattr(font, "FDSelect"):
      sel = font.FDSelect
      indices = _uniq_sort(sel.gidArray)
      sel.gidArray = [indices.index (ss) for ss in sel.gidArray]
      arr = font.FDArray
      arr.items = [arr[i] for i in indices]
      arr.count = len(arr.items)
      del arr.file, arr.offsets


    #
    # Drop hints if not needed
    #
    if not options.hinting:

      #
      # This can be tricky, but doesn't have to.  What we do is:
      #
      # - Run all used glyph charstrings and recurse into subroutines,
      # - For each charstring (including subroutines), if it has any
      #   of the hint stem operators, we mark it as such.  Upon returning,
      #   for each charstring we note all the subroutine calls it makes
      #   that (recursively) contain a stem,
      # - Dropping hinting then consists of the following two ops:
      #   * Drop the piece of the program in each charstring before the
      #     last call to a stem op or a stem-calling subroutine,
      #   * Drop all hintmask operations.
      # - It's trickier... A hintmask right after hints and a few numbers
      #   will act as an implicit vstemhm.  As such, we track whether
      #   we have seen any non-hint operators so far and do the right
      #   thing, recursively...  Good luck understanding that :(
      #
      css = set()
      for g in font.charset:
        c,sel = cs.getItemAndSelector(g)
        # Make sure it's decompiled.  We want our "decompiler" to walk
        # the program, not the bytecode.
        c.draw(basePen.NullPen())
        subrs = getattr(c.private, "Subrs", [])
        decompiler = _DehintingT2Decompiler(css, subrs, c.globalSubrs)
        decompiler.execute(c)
      for charstring in css:
        charstring.drop_hints()

      # Drop font-wide hinting values
      all_privs = []
      if hasattr(font, 'FDSelect'):
        all_privs.extend(fd.Private for fd in font.FDArray)
      else:
        all_privs.append(font.Private)
      for priv in all_privs:
        priv.BlueValues = []
        for k in ['OtherBlues', 'StemSnapH', 'StemSnapV', 'StdHW', 'StdVW', \
                  'FamilyBlues', 'FamilyOtherBlues']:
          if hasattr(priv, k):
            setattr(priv, k, None)


    #
    # Renumber subroutines to remove unused ones
    #

    # Mark all used subroutines
    for g in font.charset:
      c,sel = cs.getItemAndSelector(g)
      subrs = getattr(c.private, "Subrs", [])
      decompiler = _MarkingT2Decompiler(subrs, c.globalSubrs)
      decompiler.execute(c)

    all_subrs = [font.GlobalSubrs]
    if hasattr(font, 'FDSelect'):
      all_subrs.extend(fd.Private.Subrs for fd in font.FDArray if hasattr(fd.Private, 'Subrs') and fd.Private.Subrs)
    elif hasattr(font.Private, 'Subrs') and font.Private.Subrs:
      all_subrs.append(font.Private.Subrs)

    subrs = set(subrs) # Remove duplicates

    # Prepare
    for subrs in all_subrs:
      if not hasattr(subrs, '_used'):
        subrs._used = set()
      subrs._used = _uniq_sort(subrs._used)
      subrs._old_bias = psCharStrings.calcSubrBias(subrs)
      subrs._new_bias = psCharStrings.calcSubrBias(subrs._used)

    # Renumber glyph charstrings
    for g in font.charset:
      c,sel = cs.getItemAndSelector(g)
      subrs = getattr(c.private, "Subrs", [])
      c.subset_subroutines (subrs, font.GlobalSubrs)

    # Renumber subroutines themselves
    for subrs in all_subrs:

      if subrs == font.GlobalSubrs:
        if not hasattr(font, 'FDSelect') and hasattr(font.Private, 'Subrs'):
          local_subrs = font.Private.Subrs
        else:
          local_subrs = []
      else:
        local_subrs = subrs

      subrs.items = [subrs.items[i] for i in subrs._used]
      subrs.count = len(subrs.items)
      del subrs.file
      if hasattr(subrs, 'offsets'):
        del subrs.offsets

      for i in xrange (subrs.count):
        subrs[i].subset_subroutines (local_subrs, font.GlobalSubrs)

    # Cleanup
    for subrs in all_subrs:
      del subrs._used, subrs._old_bias, subrs._new_bias

  return True

@_add_method(ttLib.getTableClass('cmap'))
def closure_glyphs(self, s):
  tables = [t for t in self.tables
            if t.platformID == 3 and t.platEncID in [1, 10]]
  for u in s.unicodes_requested:
    found = False
    for table in tables:
      if u in table.cmap:
        s.glyphs.add(table.cmap[u])
        found = True
        break
    if not found:
      s.log("No glyph for Unicode value %s; skipping." % u)

@_add_method(ttLib.getTableClass('cmap'))
def prune_pre_subset(self, options):
  if not options.legacy_cmap:
    # Drop non-Unicode / non-Symbol cmaps
    self.tables = [t for t in self.tables
                   if t.platformID == 3 and t.platEncID in [0, 1, 10]]
  if not options.symbol_cmap:
    self.tables = [t for t in self.tables
                   if t.platformID == 3 and t.platEncID in [1, 10]]
  # 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 bool(self.tables)

@_add_method(ttLib.getTableClass('cmap'))
def subset_glyphs(self, s):
  s.glyphs = s.glyphs_cmaped
  for t in self.tables:
    # For reasons I don't understand I need this here
    # to force decompilation of the cmap format 14.
    try:
      getattr(t, "asdf")
    except AttributeError:
      pass
    if t.format == 14:
      # TODO(behdad) XXX We drop all the default-UVS mappings(g==None).
      t.uvsDict = dict((v,[(u,g) for u,g in l if g in s.glyphs])
                       for v,l in t.uvsDict.iteritems())
      t.uvsDict = dict((v,l) for v,l in t.uvsDict.iteritems() if l)
    else:
      t.cmap = dict((u,g) for u,g in t.cmap.iteritems()
                    if g in s.glyphs_requested or u in s.unicodes_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 bool(self.tables)

@_add_method(ttLib.getTableClass('name'))
def prune_pre_subset(self, options):
  if '*' not in options.name_IDs:
    self.names = [n for n in self.names if n.nameID in options.name_IDs]
  if not options.name_legacy:
    self.names = [n for n in self.names
                  if n.platformID == 3 and n.platEncID == 1]
  if '*' not in options.name_languages:
    self.names = [n for n in self.names if n.langID in options.name_languages]
  return True  # Retain even if empty


# TODO(behdad) OS/2 ulUnicodeRange / ulCodePageRange?
# 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.

class Options(object):

  class UnknownOptionError(Exception):
    pass

  _drop_tables_default = ['BASE', 'JSTF', 'DSIG', 'EBDT', 'EBLC', 'EBSC', 'SVG ',
                          'PCLT', 'LTSH']
  _drop_tables_default += ['Feat', 'Glat', 'Gloc', 'Silf', 'Sill']  # Graphite
  _drop_tables_default += ['CBLC', 'CBDT', 'sbix', 'COLR', 'CPAL']  # Color
  _no_subset_tables_default = ['gasp', 'head', 'hhea', 'maxp', 'vhea', 'OS/2',
                               'loca', 'name', 'cvt ', 'fpgm', 'prep']
  _hinting_tables_default = ['cvt ', 'fpgm', 'prep', 'hdmx', 'VDMX']

  # Based on HarfBuzz shapers
  _layout_features_groups = {
    # Default shaper
    'common': ['ccmp', 'liga', 'locl', 'mark', 'mkmk', 'rlig'],
    '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'],
    'hangul': ['ljmo', 'vjmo', 'tjmo'],
    'tibetal': ['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(
      _layout_features_groups.itervalues(), []))

  drop_tables = _drop_tables_default
  no_subset_tables = _no_subset_tables_default
  hinting_tables = _hinting_tables_default
  layout_features = _layout_features_default
  hinting = False
  glyph_names = False
  legacy_cmap = False
  symbol_cmap = False
  name_IDs = [1, 2]  # Family and Style
  name_legacy = False
  name_languages = [0x0409]  # English
  notdef_glyph = True # gid0 for TrueType / .notdef for CFF
  notdef_outline = False # No need for notdef to have an outline really
  recommended_glyphs = False  # gid1, gid2, gid3 for TrueType
  recalc_bounds = False # Recalculate font bounding boxes
  canonical_order = False # Order tables as recommended
  flavor = None # May be 'woff'

  def __init__(self, **kwargs):

    self.set(**kwargs)

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

  def parse_opts(self, argv, ignore_unknown=False):
    ret = []
    opts = {}
    for a in argv:
      orig_a = a
      if not a.startswith('--'):
        ret.append(a)
        continue
      a = a[2:]
      i = a.find('=')
      op = '='
      if i == -1:
        if a.startswith("no-"):
          k = a[3:]
          v = False
        else:
          k = a
          v = True
      else:
        k = a[:i]
        if k[-1] in "-+":
          op = k[-1]+'='  # Ops is '-=' or '+=' now.
          k = k[:-1]
        v = a[i+1:]
      k = k.replace('-', '_')
      if not hasattr(self, k):
        if ignore_unknown == True or k in ignore_unknown:
          ret.append(orig_a)
          continue
        else:
          raise self.UnknownOptionError("Unknown option '%s'" % a)

      ov = getattr(self, k)
      if isinstance(ov, bool):
        v = bool(v)
      elif isinstance(ov, int):
        v = int(v)
      elif isinstance(ov, list):
        vv = v.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 0

      opts[k] = v
    self.set(**opts)

    return ret


class Subsetter(object):

  def __init__(self, options=None, log=None):

    if not log:
      log = Logger()
    if not options:
      options = Options()

    self.options = options
    self.log = log
    self.unicodes_requested = set()
    self.glyphs_requested = set()
    self.glyphs = set()

  def populate(self, glyphs=[], unicodes=[], text=""):
    self.unicodes_requested.update(unicodes)
    if isinstance(text, str):
      text = text.decode("utf8")
    for u in text:
      self.unicodes_requested.add(ord(u))
    self.glyphs_requested.update(glyphs)
    self.glyphs.update(glyphs)

  def _prune_pre_subset(self, font):

    for tag in font.keys():
      if tag == 'GlyphOrder': continue

      if(tag in self.options.drop_tables or
         (tag in self.options.hinting_tables and not self.options.hinting)):
        self.log(tag, "dropped")
        del font[tag]
        continue

      clazz = ttLib.getTableClass(tag)

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

  def _closure_glyphs(self, font):

    self.glyphs = self.glyphs_requested.copy()

    if 'cmap' in font:
      font['cmap'].closure_glyphs(self)
    self.glyphs_cmaped = self.glyphs

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

    if 'GSUB' in font:
      self.log("Closing glyph list over 'GSUB': %d glyphs before" %
                len(self.glyphs))
      self.log.glyphs(self.glyphs, font=font)
      font['GSUB'].closure_glyphs(self)
      self.log("Closed  glyph list over 'GSUB': %d glyphs after" %
                len(self.glyphs))
      self.log.glyphs(self.glyphs, font=font)
      self.log.lapse("close glyph list over 'GSUB'")
    self.glyphs_gsubed = self.glyphs.copy()

    if 'glyf' in font:
      self.log("Closing glyph list over 'glyf': %d glyphs before" %
                len(self.glyphs))
      self.log.glyphs(self.glyphs, font=font)
      font['glyf'].closure_glyphs(self)
      self.log("Closed  glyph list over 'glyf': %d glyphs after" %
                len(self.glyphs))
      self.log.glyphs(self.glyphs, font=font)
      self.log.lapse("close glyph list over 'glyf'")
    self.glyphs_glyfed = self.glyphs.copy()

    self.glyphs_all = self.glyphs.copy()

    self.log("Retaining %d glyphs: " % len(self.glyphs_all))

  def _subset_glyphs(self, font):
    for tag in font.keys():
      if tag == 'GlyphOrder': continue
      clazz = ttLib.getTableClass(tag)

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

    glyphOrder = font.getGlyphOrder()
    glyphOrder = [g for g in glyphOrder if g in self.glyphs_all]
    font.setGlyphOrder(glyphOrder)
    font._buildReverseGlyphOrderDict()
    self.log.lapse("subset GlyphOrder")

  def _prune_post_subset(self, font):
    for tag in font.keys():
      if tag == 'GlyphOrder': continue
      clazz = ttLib.getTableClass(tag)
      if hasattr(clazz, 'prune_post_subset'):
        table = font[tag]
        retain = table.prune_post_subset(self.options)
        self.log.lapse("prune  '%s'" % tag)
        if not retain:
          self.log(tag, "pruned to empty; dropped")
          del font[tag]
        else:
          self.log(tag, "pruned")

  def subset(self, font):

    self._prune_pre_subset(font)
    self._closure_glyphs(font)
    self._subset_glyphs(font)
    self._prune_post_subset(font)


class Logger(object):

  def __init__(self, verbose=False, xml=False, timing=False):
    self.verbose = verbose
    self.xml = xml
    self.timing = timing
    self.last_time = self.start_time = time.time()

  def parse_opts(self, argv):
    argv = argv[:]
    for v in ['verbose', 'xml', 'timing']:
      if "--"+v in argv:
        setattr(self, v, True)
        argv.remove("--"+v)
    return argv

  def __call__(self, *things):
    if not self.verbose:
      return
    print ' '.join(str(x) for x in things)

  def lapse(self, *things):
    if not self.timing:
      return
    new_time = time.time()
    print "Took %0.3fs to %s" %(new_time - self.last_time,
                                 ' '.join(str(x) for x in things))
    self.last_time = new_time

  def glyphs(self, glyphs, font=None):
    self("Names: ", sorted(glyphs))
    if font:
      reverseGlyphMap = font.getReverseGlyphMap()
      self("Gids : ", sorted(reverseGlyphMap[g] for g in glyphs))

  def font(self, font, file=sys.stdout):
    if not self.xml:
      return
    from fontTools.misc import xmlWriter
    writer = xmlWriter.XMLWriter(file)
    font.disassembleInstructions = False  # Work around ttLib bug
    for tag in font.keys():
      writer.begintag(tag)
      writer.newline()
      font[tag].toXML(writer, font)
      writer.endtag(tag)
      writer.newline()


def load_font(fontFile,
              options,
              checkChecksums=False,
              dontLoadGlyphNames=False):

  font = ttLib.TTFont(fontFile,
                                checkChecksums=checkChecksums,
                                recalcBBoxes=options.recalc_bounds)

  # 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

def save_font(font, outfile, options):
  if options.flavor and not hasattr(font, 'flavor'):
    raise Exception("fonttools version does not support flavors.")
  font.flavor = options.flavor
  font.save(outfile, reorderTables=options.canonical_order)

def main(args):

  log = Logger()
  args = log.parse_opts(args)

  options = Options()
  args = options.parse_opts(args, ignore_unknown=['text'])

  if len(args) < 2:
    print >>sys.stderr, "usage: pyftsubset font-file glyph... [--text=ABC]... [--option=value]..."
    sys.exit(1)

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

  dontLoadGlyphNames =(not options.glyph_names and
         all(any(g.startswith(p)
             for p in ['gid', 'glyph', 'uni', 'U+'])
              for g in args))

  font = load_font(fontfile, options, dontLoadGlyphNames=dontLoadGlyphNames)
  subsetter = Subsetter(options=options, log=log)
  log.lapse("load font")

  names = font.getGlyphNames()
  log.lapse("loading glyph names")

  glyphs = []
  unicodes = []
  text = ""
  for g in args:
    if g == '*':
      glyphs.extend(font.getGlyphOrder())
      continue
    if g in names:
      glyphs.append(g)
      continue
    if g.startswith('--text='):
      text += g[7:]
      continue
    if g.startswith('uni') or g.startswith('U+'):
      if g.startswith('uni') and len(g) > 3:
        g = g[3:]
      elif g.startswith('U+') and len(g) > 2:
        g = g[2:]
      u = int(g, 16)
      unicodes.append(u)
      continue
    if g.startswith('gid') or g.startswith('glyph'):
      if g.startswith('gid') and len(g) > 3:
        g = g[3:]
      elif g.startswith('glyph') and len(g) > 5:
        g = g[5:]
      try:
        glyphs.append(font.getGlyphName(int(g), requireReal=1))
      except ValueError:
        raise Exception("Invalid glyph identifier: %s" % g)
      continue
    raise Exception("Invalid glyph identifier: %s" % g)
  log.lapse("compile glyph list")
  log("Unicodes:", unicodes)
  log("Glyphs:", glyphs)

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

  outfile = fontfile + '.subset'

  save_font (font, outfile, options)
  log.lapse("compile and save font")

  log.last_time = log.start_time
  log.lapse("make one with everything(TOTAL TIME)")

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

  log.font(font)

  font.close()


__all__ = [
  'Options',
  'Subsetter',
  'Logger',
  'load_font',
  'save_font',
  'main'
]

if __name__ == '__main__':
  main(sys.argv[1:])
