/*
 * Copyright 2011 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// File is originally from Chromium third_party/sfntly/src/subsetter.
// Use as test case in sfntly so that problems can be caught in upstream early.

#include "test/subsetter_impl.h"

#include <string.h>

#include <map>
#include <set>

#include "sfntly/table/bitmap/eblc_table.h"
#include "sfntly/table/bitmap/ebdt_table.h"
#include "sfntly/table/bitmap/index_sub_table.h"
#include "sfntly/table/bitmap/index_sub_table_format1.h"
#include "sfntly/table/bitmap/index_sub_table_format2.h"
#include "sfntly/table/bitmap/index_sub_table_format3.h"
#include "sfntly/table/bitmap/index_sub_table_format4.h"
#include "sfntly/table/bitmap/index_sub_table_format5.h"
#include "sfntly/table/core/name_table.h"
#include "sfntly/table/truetype/glyph_table.h"
#include "sfntly/table/truetype/loca_table.h"
#include "sfntly/tag.h"
#include "sfntly/data/memory_byte_array.h"
#include "sfntly/port/memory_input_stream.h"
#include "sfntly/port/memory_output_stream.h"


namespace {

// The bitmap tables must be greater than 16KB to trigger bitmap subsetter.
static const int BITMAP_SIZE_THRESHOLD = 16384;

}

namespace sfntly {

void ConstructName(UChar* name_part, UnicodeString* name, int32_t name_id) {
  switch (name_id) {
    case NameId::kFullFontName:
      *name = name_part;
      break;
    case NameId::kFontFamilyName:
    case NameId::kPreferredFamily:
    case NameId::kWWSFamilyName: {
      UnicodeString original = *name;
      *name = name_part;
      *name += original;
      break;
    }
    case NameId::kFontSubfamilyName:
    case NameId::kPreferredSubfamily:
    case NameId::kWWSSubfamilyName:
      *name += name_part;
      break;
    default:
      // This name part is not used to construct font name (e.g. copyright).
      // Simply ignore it.
      break;
  }
}

int32_t HashCode(int32_t platform_id, int32_t encoding_id, int32_t language_id,
                 int32_t name_id) {
  int32_t result = platform_id << 24 | encoding_id << 16 | language_id << 8;
  if (name_id == NameId::kFullFontName) {
    result |= 0xff;
  } else if (name_id == NameId::kPreferredFamily ||
             name_id == NameId::kPreferredSubfamily) {
    result |= 0xf;
  } else if (name_id == NameId::kWWSFamilyName ||
             name_id == NameId::kWWSSubfamilyName) {
    result |= 1;
  }
  return result;
}

bool HasName(const char* font_name, Font* font) {
  UnicodeString font_string = UnicodeString::fromUTF8(font_name);
  if (font_string.isEmpty())
    return false;
  UnicodeString regular_suffix = UnicodeString::fromUTF8(" Regular");
  UnicodeString alt_font_string = font_string;
  alt_font_string += regular_suffix;

  typedef std::map<int32_t, UnicodeString> NameMap;
  NameMap names;
  NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
  if (name_table == NULL) {
    return false;
  }

  for (int32_t i = 0; i < name_table->NameCount(); ++i) {
    switch (name_table->NameId(i)) {
      case NameId::kFontFamilyName:
      case NameId::kFontSubfamilyName:
      case NameId::kFullFontName:
      case NameId::kPreferredFamily:
      case NameId::kPreferredSubfamily:
      case NameId::kWWSFamilyName:
      case NameId::kWWSSubfamilyName: {
        int32_t hash_code = HashCode(name_table->PlatformId(i),
                                     name_table->EncodingId(i),
                                     name_table->LanguageId(i),
                                     name_table->NameId(i));
        UChar* name_part = name_table->Name(i);
        ConstructName(name_part, &(names[hash_code]), name_table->NameId(i));
        delete[] name_part;
        break;
      }
      default:
        break;
    }
  }

  if (!names.empty()) {
    for (NameMap::iterator b = names.begin(), e = names.end(); b != e; ++b) {
      if (b->second.caseCompare(font_string, 0) == 0 ||
          b->second.caseCompare(alt_font_string, 0) == 0) {
        return true;
      }
    }
  }
  return false;
}

Font* FindFont(const char* font_name, const FontArray& font_array) {
  if (font_array.empty() || font_array[0] == NULL) {
    return NULL;
  }

  if (font_name && strlen(font_name)) {
    for (FontArray::const_iterator b = font_array.begin(), e = font_array.end();
         b != e; ++b) {
      if (HasName(font_name, (*b).p_)) {
        return (*b).p_;
      }
    }
  }

  return font_array[0].p_;
}

bool ResolveCompositeGlyphs(GlyphTable* glyf,
                            LocaTable* loca,
                            const unsigned int* glyph_ids,
                            size_t glyph_count,
                            IntegerSet* glyph_id_processed) {
  if (glyf == NULL || loca == NULL || glyph_ids == NULL || glyph_count == 0 ||
      glyph_id_processed == NULL) {
    return false;
  }

  // Find glyf and loca table.
  GlyphTablePtr glyph_table = glyf;
  LocaTablePtr loca_table = loca;

  // Sort and uniquify glyph ids.
  IntegerSet glyph_id_remaining;
  glyph_id_remaining.insert(0);  // Always include glyph id 0.
  for (size_t i = 0; i < glyph_count; ++i) {
    glyph_id_remaining.insert(glyph_ids[i]);
  }

  // Identify if any given glyph id maps to a composite glyph.  If so, include
  // the glyphs referenced by that composite glyph.
  while (!glyph_id_remaining.empty()) {
    IntegerSet comp_glyph_id;
    for (IntegerSet::iterator i = glyph_id_remaining.begin(),
                              e = glyph_id_remaining.end(); i != e; ++i) {
      if (*i < 0 || *i >= loca_table->num_glyphs()) {
        // Invalid glyph id, ignore.
        continue;
      }

      int32_t length = loca_table->GlyphLength(*i);
      if (length == 0) {
        // Empty glyph, ignore.
        continue;
      }
      int32_t offset = loca_table->GlyphOffset(*i);

      GlyphPtr glyph;
      glyph.Attach(glyph_table->GetGlyph(offset, length));
      if (glyph == NULL) {
        // Error finding glyph, ignore.
        continue;
      }

      if (glyph->GlyphType() == GlyphType::kComposite) {
        Ptr<GlyphTable::CompositeGlyph> comp_glyph =
            down_cast<GlyphTable::CompositeGlyph*>(glyph.p_);
        for (int32_t j = 0; j < comp_glyph->NumGlyphs(); ++j) {
          int32_t glyph_id = comp_glyph->GlyphIndex(j);
          if (glyph_id_processed->find(glyph_id) == glyph_id_processed->end() &&
              glyph_id_remaining.find(glyph_id) == glyph_id_remaining.end()) {
            comp_glyph_id.insert(comp_glyph->GlyphIndex(j));
          }
        }
      }

      glyph_id_processed->insert(*i);
    }

    glyph_id_remaining.clear();
    glyph_id_remaining = comp_glyph_id;
  }

  return true;
}

bool SetupGlyfBuilders(Font::Builder* builder,
                       GlyphTable* glyf,
                       LocaTable* loca,
                       const IntegerSet& glyph_ids) {
  if (!builder || !glyf || !loca) {
    return false;
  }

  // The tables are already checked in ResolveCompositeGlyphs().
  GlyphTablePtr glyph_table = glyf;
  LocaTablePtr loca_table = loca;

  FontBuilderPtr font_builder = builder;
  GlyphTableBuilderPtr glyph_table_builder =
      down_cast<GlyphTable::Builder*>(font_builder->NewTableBuilder(Tag::glyf));
  LocaTableBuilderPtr loca_table_builder =
      down_cast<LocaTable::Builder*>(font_builder->NewTableBuilder(Tag::loca));
  if (glyph_table_builder == NULL || loca_table_builder == NULL) {
    // Out of memory.
    return false;
  }

  // Extract glyphs and setup loca list.
  IntegerList loca_list;
  loca_list.resize(loca_table->num_glyphs());
  loca_list.push_back(0);
  int32_t last_glyph_id = 0;
  int32_t last_offset = 0;
  GlyphTable::GlyphBuilderList* glyph_builders =
      glyph_table_builder->GlyphBuilders();
  for (IntegerSet::const_iterator i = glyph_ids.begin(), e = glyph_ids.end();
                                  i != e; ++i) {
    int32_t length = loca_table->GlyphLength(*i);
    int32_t offset = loca_table->GlyphOffset(*i);

    GlyphPtr glyph;
    glyph.Attach(glyph_table->GetGlyph(offset, length));

    // Add glyph to new glyf table.
    ReadableFontDataPtr data = glyph->ReadFontData();
    WritableFontDataPtr copy_data;
    copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length()));
    data->CopyTo(copy_data);
    GlyphBuilderPtr glyph_builder;
    glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
    glyph_builders->push_back(glyph_builder);

    // Configure loca list.
    for (int32_t j = last_glyph_id + 1; j <= *i; ++j) {
      loca_list[j] = last_offset;
    }
    last_offset += length;
    loca_list[*i + 1] = last_offset;
    last_glyph_id = *i;
  }
  for (int32_t j = last_glyph_id + 1; j <= loca_table->num_glyphs(); ++j) {
    loca_list[j] = last_offset;
  }
  loca_table_builder->SetLocaList(&loca_list);

  return true;
}

bool HasOverlap(int32_t range_begin, int32_t range_end,
                const IntegerSet& glyph_ids) {
  if (range_begin == range_end) {
    return glyph_ids.find(range_begin) != glyph_ids.end();
  } else if (range_end > range_begin) {
    IntegerSet::const_iterator left = glyph_ids.lower_bound(range_begin);
    IntegerSet::const_iterator right = glyph_ids.lower_bound(range_end);
    return right != left;
  }
  return false;
}

// Initialize builder, returns false if glyph_id subset is not covered.
bool ShallSubset(EbdtTable::Builder* ebdt, EblcTable::Builder* eblc,
                 const IntegerSet& glyph_ids) {
  EblcTableBuilderPtr eblc_builder = eblc;
  EbdtTableBuilderPtr ebdt_builder = ebdt;

  BitmapLocaList loca_list;
  BitmapSizeTableBuilderList* strikes = eblc_builder->BitmapSizeBuilders();

  // Note: Do not call eblc_builder->GenerateLocaList(&loca_list) and then
  //       ebdt_builder->SetLoca(loca_list).  For fonts like SimSun, there are
  //       >28K glyphs inside, where a typical usage will be <1K glyphs.  Doing
  //       the calls improperly will result in creation of >100K objects that
  //       will be destroyed immediately, inducing significant slowness.
  IntegerList removed_strikes;
  for (size_t i = 0; i < strikes->size(); i++) {
    if (!HasOverlap((*strikes)[i]->StartGlyphIndex(),
                    (*strikes)[i]->EndGlyphIndex(), glyph_ids)) {
      removed_strikes.push_back(i);
      continue;
    }

    IndexSubTableBuilderList* index_builders =
        (*strikes)[i]->IndexSubTableBuilders();
    IntegerList removed_indexes;
    BitmapGlyphInfoMap info_map;
    for (size_t j = 0; j < index_builders->size(); ++j) {
      int32_t first_glyph_id = (*index_builders)[j]->first_glyph_index();
      int32_t last_glyph_id = (*index_builders)[j]->last_glyph_index();
      if (!HasOverlap(first_glyph_id, last_glyph_id, glyph_ids)) {
        removed_indexes.push_back(j);
        continue;
      }
      for (IntegerSet::const_iterator gid = glyph_ids.begin(),
                                      gid_end = glyph_ids.end();
                                      gid != gid_end; gid++) {
        if (*gid < first_glyph_id) {
          continue;
        }
        if (*gid > last_glyph_id) {
          break;
        }
        BitmapGlyphInfoPtr info;
        info.Attach((*index_builders)[j]->GlyphInfo(*gid));
        if (info && info->length()) {  // Do not include gid without bitmap
          info_map[*gid] = info;
        }
      }
    }
    if (!info_map.empty()) {
      loca_list.push_back(info_map);
    } else {
      removed_strikes.push_back(i);  // Detected null entries.
    }

    // Remove unused index sub tables
    for (IntegerList::reverse_iterator j = removed_indexes.rbegin(),
                                       e = removed_indexes.rend();
                                       j != e; j++) {
      index_builders->erase(index_builders->begin() + *j);
    }
  }
  if (removed_strikes.size() == strikes->size() || loca_list.empty()) {
    return false;  // All strikes shall be gone.
  }

  // Remove unused strikes
  for (IntegerList::reverse_iterator j = removed_strikes.rbegin(),
                                     e = removed_strikes.rend(); j != e; j++) {
    strikes->erase(strikes->begin() + *j);
  }

  if (strikes->empty()) {  // no glyph covered, can safely drop the builders.
    return false;
  }

  ebdt_builder->SetLoca(&loca_list);
  ebdt_builder->GlyphBuilders();  // Initialize the builder.
  return true;
}

void CopyBigGlyphMetrics(BigGlyphMetrics::Builder* source,
                         BigGlyphMetrics::Builder* target) {
  target->SetHeight(static_cast<byte_t>(source->Height()));
  target->SetWidth(static_cast<byte_t>(source->Width()));
  target->SetHoriBearingX(static_cast<byte_t>(source->HoriBearingX()));
  target->SetHoriBearingY(static_cast<byte_t>(source->HoriBearingY()));
  target->SetHoriAdvance(static_cast<byte_t>(source->HoriAdvance()));
  target->SetVertBearingX(static_cast<byte_t>(source->VertBearingX()));
  target->SetVertBearingY(static_cast<byte_t>(source->VertBearingY()));
  target->SetVertAdvance(static_cast<byte_t>(source->VertAdvance()));
}

CALLER_ATTACH IndexSubTable::Builder*
ConstructIndexFormat4(IndexSubTable::Builder* b, const BitmapGlyphInfoMap& loca,
                      int32_t* image_data_offset) {
  IndexSubTableFormat4BuilderPtr builder4;
  builder4.Attach(IndexSubTableFormat4::Builder::CreateBuilder());
  CodeOffsetPairBuilderList offset_pairs;

  size_t offset = 0;
  int32_t lower_bound = b->first_glyph_index();
  int32_t upper_bound = b->last_glyph_index();
  bool lower_bound_reached = false;
  bool upper_bound_reached = false;
  int32_t last_gid = -1;
  BitmapGlyphInfoMap::const_iterator last_element = loca.end();
  --last_element;
  for (BitmapGlyphInfoMap::const_iterator i = loca.begin(), e = loca.end();
                                          i != e; i++) {
    int32_t gid = i->first;
    if (gid < lower_bound) {
      continue;
    }
    if (!lower_bound_reached) {
      builder4->set_first_glyph_index(gid);
      builder4->set_image_format(b->image_format());
      builder4->set_image_data_offset(*image_data_offset);
      last_gid = gid;
      lower_bound_reached = true;
    }
    if (gid > upper_bound) {
      upper_bound_reached = true;
    }
    if (!upper_bound_reached) {
      offset_pairs.push_back(
          IndexSubTableFormat4::CodeOffsetPairBuilder(gid, offset));
      offset += i->second->length();
      last_gid = gid;
      if (i == last_element) {
        upper_bound_reached = true;
      }
    }
    if (upper_bound_reached) {
      offset_pairs.push_back(
          IndexSubTableFormat4::CodeOffsetPairBuilder(-1, offset));
      builder4->set_last_glyph_index(last_gid);
      *image_data_offset += offset;
      break;
    }
  }
  builder4->SetOffsetArray(offset_pairs);

  return builder4.Detach();
}

CALLER_ATTACH IndexSubTable::Builder*
ConstructIndexFormat5(IndexSubTable::Builder* b, const BitmapGlyphInfoMap& loca,
                      int32_t* image_data_offset) {
  IndexSubTableFormat5BuilderPtr new_builder;
  new_builder.Attach(IndexSubTableFormat5::Builder::CreateBuilder());

  // Copy BigMetrics
  int32_t image_size = 0;
  if (b->index_format() == IndexSubTable::Format::FORMAT_2) {
    IndexSubTableFormat2BuilderPtr builder2 =
      down_cast<IndexSubTableFormat2::Builder*>(b);
    CopyBigGlyphMetrics(builder2->BigMetrics(), new_builder->BigMetrics());
    image_size = builder2->ImageSize();
  } else {
    IndexSubTableFormat5BuilderPtr builder5 =
      down_cast<IndexSubTableFormat5::Builder*>(b);
    BigGlyphMetricsBuilderPtr metrics_builder;
    CopyBigGlyphMetrics(builder5->BigMetrics(), new_builder->BigMetrics());
    image_size = builder5->ImageSize();
  }

  IntegerList* glyph_array = new_builder->GlyphArray();
  size_t offset = 0;
  int32_t lower_bound = b->first_glyph_index();
  int32_t upper_bound = b->last_glyph_index();
  bool lower_bound_reached = false;
  bool upper_bound_reached = false;
  int32_t last_gid = -1;
  BitmapGlyphInfoMap::const_iterator last_element = loca.end();
  --last_element;
  for (BitmapGlyphInfoMap::const_iterator i = loca.begin(), e = loca.end();
                                          i != e; i++) {
    int32_t gid = i->first;
    if (gid < lower_bound) {
      continue;
    }
    if (!lower_bound_reached) {
      new_builder->set_first_glyph_index(gid);
      new_builder->set_image_format(b->image_format());
      new_builder->set_image_data_offset(*image_data_offset);
      new_builder->SetImageSize(image_size);
      last_gid = gid;
      lower_bound_reached = true;
    }
    if (gid > upper_bound || i == last_element) {
      upper_bound_reached = true;
    }
    if (!upper_bound_reached || i == last_element) {
      glyph_array->push_back(gid);
      offset += i->second->length();
      last_gid = gid;
    }
    if (upper_bound_reached) {
      new_builder->set_last_glyph_index(last_gid);
      *image_data_offset += offset;
      break;
    }
  }
  return new_builder.Detach();
}

CALLER_ATTACH IndexSubTable::Builder*
SubsetIndexSubTable(IndexSubTable::Builder* builder,
                    const BitmapGlyphInfoMap& loca,
                    int32_t* image_data_offset) {
  switch (builder->index_format()) {
    case IndexSubTable::Format::FORMAT_1:
    case IndexSubTable::Format::FORMAT_3:
    case IndexSubTable::Format::FORMAT_4:
      return ConstructIndexFormat4(builder, loca, image_data_offset);
    case IndexSubTable::Format::FORMAT_2:
    case IndexSubTable::Format::FORMAT_5:
      return ConstructIndexFormat5(builder, loca, image_data_offset);
    default:
      assert(false);  // Shall not be here.
      break;
  }
  return NULL;
}

void SubsetEBLC(EblcTable::Builder* eblc, const BitmapLocaList& new_loca) {
  EblcTableBuilderPtr eblc_builder = eblc;
  BitmapSizeTableBuilderList* size_builders = eblc->BitmapSizeBuilders();
  if (size_builders == NULL) {
    return;  // No valid EBLC.
  }

  int32_t image_data_offset = EbdtTable::Offset::kHeaderLength;
  for (size_t strike = 0; strike < size_builders->size(); ++strike) {
    IndexSubTableBuilderList* index_builders =
        (*size_builders)[strike]->IndexSubTableBuilders();
    for (size_t index = 0; index < index_builders->size(); ++index) {
      IndexSubTable::Builder* new_builder_raw =
          SubsetIndexSubTable((*index_builders)[index], new_loca[strike],
                              &image_data_offset);
      if (NULL != new_builder_raw) {
        (*index_builders)[index].Attach(new_builder_raw);
      }
    }
  }
}

/******************************************************************************
  Long background comments

EBLC structure:
  header
  bitmapSizeTable[]
    one per strike
    holds strike metrics - sbitLineMetrics
    holds info about indexSubTableArray
  indexSubTableArray[][]
    one per strike and then one per indexSubTable for that strike
    holds info about the indexSubTable
    the indexSubTable entries pointed to can be of different formats
  indexSubTable
    one per indexSubTableArray entry
    tells how to get the glyphs
    may hold the glyph metrics if they are uniform for all the glyphs in range

There is nothing that says that the indexSubTableArray entries and/or the
indexSubTable items need to be unique. They may be shared between strikes.

EBDT structure:
  header
  glyphs
    amorphous blob of data
    different glyphs that are only able to be figured out from the EBLC table
    may hold metrics - depends on the EBLC entry that pointed to them

Subsetting EBLC table:
  Most pages use only a fraction (hundreds or less) glyphs out of a given font
  (which can have >20K glyphs for CJK).  It's safe to assume that the subset
  font will have sparse bitmap glyphs.  As a result, the EBLC table shall be
  reconstructed to either format 4 or 5.
*******************************************************************************/
bool SetupBitmapBuilders(Font* font, Font::Builder* builder,
                         const IntegerSet& glyph_ids, bool use_ebdt) {
  if (!font || !builder) {
    return false;
  }

  EbdtTablePtr ebdt_table =
      down_cast<EbdtTable*>(font->GetTable(use_ebdt ? Tag::EBDT : Tag::bdat));
  EblcTablePtr eblc_table =
      down_cast<EblcTable*>(font->GetTable(use_ebdt ? Tag::EBLC : Tag::bloc));

  // If the bitmap table's size is too small, skip subsetting.
  if (ebdt_table->DataLength() + eblc_table->DataLength() <
      BITMAP_SIZE_THRESHOLD) {
    return true;
  }

  // Get the builders.
  FontBuilderPtr font_builder = builder;
  EbdtTableBuilderPtr ebdt_table_builder = down_cast<EbdtTable::Builder*>(
      font_builder->NewTableBuilder(use_ebdt ? Tag::EBDT : Tag::bdat,
                                    ebdt_table->ReadFontData()));
  EblcTableBuilderPtr eblc_table_builder = down_cast<EblcTable::Builder*>(
      font_builder->NewTableBuilder(use_ebdt ? Tag::EBLC : Tag::bloc,
                                    eblc_table->ReadFontData()));
  if (ebdt_table_builder == NULL || eblc_table_builder == NULL) {
    // Out of memory.
    return false;
  }

  if (!ShallSubset(ebdt_table_builder, eblc_table_builder, glyph_ids)) {
    // Bitmap tables do not cover the glyphs in our subset.
    font_builder->RemoveTableBuilder(use_ebdt ? Tag::EBLC : Tag::bloc);
    font_builder->RemoveTableBuilder(use_ebdt ? Tag::EBDT : Tag::bdat);
    return false;
  }

  BitmapLocaList new_loca;
  ebdt_table_builder->GenerateLocaList(&new_loca);
  SubsetEBLC(eblc_table_builder, new_loca);

  return true;
}

enum BitmapDetection {
  kNotFound,
  kEBDTFound,
  kOnlyBDATFound
};

// Some fonts have both EBDT/EBLC and bdat/bloc, we need only one set of them.
int DetectBitmapBuilders(Font* font) {
  // Check if bitmap table exists.
  EbdtTablePtr ebdt_table = down_cast<EbdtTable*>(font->GetTable(Tag::EBDT));
  EblcTablePtr eblc_table = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
  if (ebdt_table == NULL && eblc_table == NULL) {
    // Check BDAT variants.
    ebdt_table = down_cast<EbdtTable*>(font->GetTable(Tag::bdat));
    eblc_table = down_cast<EblcTable*>(font->GetTable(Tag::bloc));
    if (ebdt_table == NULL || eblc_table == NULL) {
      // There's no bitmap tables.
      return kNotFound;
    }
    return kOnlyBDATFound;
  }
  return kEBDTFound;
}

SubsetterImpl::SubsetterImpl() {
}

SubsetterImpl::~SubsetterImpl() {
}

bool SubsetterImpl::LoadFont(const char* font_name,
                             const unsigned char* original_font,
                             size_t font_size) {
  MemoryInputStream mis;
  mis.Attach(original_font, font_size);
  if (factory_ == NULL) {
    factory_.Attach(FontFactory::GetInstance());
  }

  FontArray font_array;
  factory_->LoadFonts(&mis, &font_array);
  font_ = FindFont(font_name, font_array);
  if (font_ == NULL) {
    return false;
  }

  return true;
}

int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids,
                              size_t glyph_count,
                              unsigned char** output_buffer) {
  if (factory_ == NULL || font_ == NULL) {
    return -1;
  }

  // Find glyf and loca table.
  GlyphTablePtr glyph_table =
      down_cast<GlyphTable*>(font_->GetTable(Tag::glyf));
  LocaTablePtr loca_table = down_cast<LocaTable*>(font_->GetTable(Tag::loca));
  if (glyph_table == NULL || loca_table == NULL) {
    // We are not able to subset the font.
    return 0;
  }

  IntegerSet glyph_id_processed;
  if (!ResolveCompositeGlyphs(glyph_table, loca_table,
                              glyph_ids, glyph_count, &glyph_id_processed) ||
      glyph_id_processed.empty()) {
    return 0;
  }

  FontPtr new_font;
  new_font.Attach(Subset(glyph_id_processed));
  if (new_font == NULL) {
    return 0;
  }

  MemoryOutputStream output_stream;
  factory_->SerializeFont(new_font, &output_stream);
  int length = static_cast<int>(output_stream.Size());
  if (length > 0) {
    *output_buffer = new unsigned char[length];
    memcpy(*output_buffer, output_stream.Get(), length);
  }

  return length;
}

/*******************************************************************************
  Long comments regarding TTF tables and PDF

According to PDF spec (section 9.9), the following tables must present:
  head, hhea, loca, maxp, cvt, prep, glyf, hmtx, fpgm
  cmap if font is used as a TTF and not a CIDFont dict

Other tables we need to keep for PDF rendering to support zoom in/out:
  bdat, bloc, ebdt, eblc, ebsc, gasp

Special table:
  CFF - if you have this table then you shouldn't have a glyf table and this is
        the table with all the glyphs.  Shall skip subsetting completely since
        sfntly is not capable of subsetting it for now.
  post - extra info here for printing on PostScript printers but maybe not
         enough to outweigh the space taken by the names

Tables to break apart:
  name - could throw away all but one language and one platform strings / might
         throw away some of the name entries
  cmap - could strip out non-needed cmap subtables
       - format 4 subtable can be subsetted as well using sfntly

Graphite tables:
  silf, glat, gloc, feat - shall be okay to strip out

Tables that can be discarded:
  OS/2 - everything here is for layout and description of the font that is
         elsewhere (some in the PDF objects)
  BASE, GDEF, GSUB, GPOS, JSTF - all used for layout
  kern - old style layout
  DSIG - this will be invalid after subsetting
  hdmx - layout
  PCLT - metadata that's not needed
  vmtx - layout
  vhea - layout
  VDMX
  VORG - not used by TT/OT - used by CFF
  hsty - would be surprised if you saw one of these - used on the Newton
  AAT tables - mort, morx, feat, acnt, bsin, just, lcar, fdsc, fmtx, prop,
               Zapf, opbd, trak, fvar, gvar, avar, cvar
             - these are all layout tables and once layout happens are not
               needed anymore
  LTSH - layout
*******************************************************************************/
CALLER_ATTACH Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids) {
  // The const is initialized here to workaround VC bug of rendering all Tag::*
  // as 0.  These tags represents the TTF tables that we will embed in subset
  // font.
  const int32_t VALID_TABLE_TAG[] = {
    Tag::head, Tag::hhea, Tag::loca, Tag::maxp, Tag::cvt,
    Tag::prep, Tag::glyf, Tag::hmtx, Tag::fpgm, Tag::EBDT,
    Tag::EBLC, Tag::EBSC, Tag::bdat, Tag::bloc, Tag::bhed,
    Tag::cmap,  // Keep here for future tagged PDF development.
    Tag::name,  // Keep here due to legal concerns: copyright info inside.
  };

  // Setup font builders we need.
  FontBuilderPtr font_builder;
  font_builder.Attach(factory_->NewFontBuilder());
  IntegerSet remove_tags;

  GlyphTablePtr glyph_table =
      down_cast<GlyphTable*>(font_->GetTable(Tag::glyf));
  LocaTablePtr loca_table = down_cast<LocaTable*>(font_->GetTable(Tag::loca));

  if (SetupGlyfBuilders(font_builder, glyph_table, loca_table, glyph_ids)) {
    remove_tags.insert(Tag::glyf);
    remove_tags.insert(Tag::loca);
  }

  int flag = DetectBitmapBuilders(font_);
  if (flag != kNotFound) {
    bool use_ebdt = (flag == kEBDTFound);
    bool subset_success =
        SetupBitmapBuilders(font_, font_builder, glyph_ids, use_ebdt);

    if (use_ebdt || !subset_success) {
      remove_tags.insert(Tag::bdat);
      remove_tags.insert(Tag::bloc);
      remove_tags.insert(Tag::bhed);
    }
    if (use_ebdt && !subset_success) {
      remove_tags.insert(Tag::EBDT);
      remove_tags.insert(Tag::EBLC);
      remove_tags.insert(Tag::EBSC);
    }
  }

  IntegerSet allowed_tags;
  for (size_t i = 0; i < sizeof(VALID_TABLE_TAG) / sizeof(int32_t); ++i) {
    allowed_tags.insert(VALID_TABLE_TAG[i]);
  }
  for (IntegerSet::iterator i = remove_tags.begin(), e = remove_tags.end();
                            i != e; i++) {
    IntegerSet::iterator it = allowed_tags.find(*i);
    if (it != allowed_tags.end()) {
      allowed_tags.erase(it);
    }
  }

  // Setup remaining builders.
  for (IntegerSet::iterator i = allowed_tags.begin(), e = allowed_tags.end();
                            i != e; ++i) {
    Table* table = font_->GetTable(*i);
    if (table) {
      font_builder->NewTableBuilder(*i, table->ReadFontData());
    }
  }

  return font_builder->Build();
}

}  // namespace sfntly
