font.cc revision 584bf6606b53bda8bf0810e7c0ad57e24cacb4f1
195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu/*
295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * Copyright 2011 Google Inc. All Rights Reserved.
395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu *
495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * Licensed under the Apache License, Version 2.0 (the "License");
595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * you may not use this file except in compliance with the License.
695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * You may obtain a copy of the License at
795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu *
895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu *      http://www.apache.org/licenses/LICENSE-2.0
995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu *
1095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * Unless required by applicable law or agreed to in writing, software
1195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * distributed under the License is distributed on an "AS IS" BASIS,
1295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * See the License for the specific language governing permissions and
1495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * limitations under the License.
1595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu */
1695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
17c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu#include "sfntly/font.h"
18c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu
1995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include <functional>
2095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include <algorithm>
2195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include <map>
2295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include <typeinfo>
2395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
24c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu#include "sfntly/data/font_input_stream.h"
2595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include "sfntly/font_factory.h"
2695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include "sfntly/math/fixed1616.h"
2795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include "sfntly/math/font_math.h"
2895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include "sfntly/port/exception_type.h"
29584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/core/font_header_table.h"
30584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/core/horizontal_header_table.h"
31584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/core/horizontal_metrics_table.h"
32584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/core/maximum_profile_table.h"
33584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/truetype/loca_table.h"
34c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu#include "sfntly/tag.h"
3595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
3695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsunamespace sfntly {
3795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
38c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuconst int32_t SFNTVERSION_1 = Fixed1616::Fixed(1, 0);
3995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
4095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu/******************************************************************************
4195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * Font class
4295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu ******************************************************************************/
4395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsuFont::~Font() {}
4495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
45c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsubool Font::HasTable(int32_t tag) {
4695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  TableMap::const_iterator result = tables_.find(tag);
4795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  TableMap::const_iterator end = tables_.end();
4895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  return (result != end);
4995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
5095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
51c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuTable* Font::GetTable(int32_t tag) {
52c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  if (!HasTable(tag)) {
5395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    return NULL;
5495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
5595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  return tables_[tag];
5695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
5795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
58c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuTableMap* Font::Tables() {
5995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  return &tables_;
6095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
6195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
62c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Serialize(OutputStream* os, IntegerList* table_ordering) {
6395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  assert(table_ordering);
6495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  IntegerList final_table_ordering;
65c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  TableOrdering(table_ordering, &final_table_ordering);
6695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  TableHeaderList table_records;
67c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  BuildTableHeadersForSerialization(&final_table_ordering, &table_records);
6895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
6995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  FontOutputStream fos(os);
70c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  SerializeHeader(&fos, &table_records);
71c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  SerializeTables(&fos, &table_records);
72c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu}
73c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu
74c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH WritableFontData* Font::GetNewData(int32_t size) {
75c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  return factory_->GetNewData(size);
76c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu}
77c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu
78c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuFont::Font(FontFactory* factory, int32_t sfnt_version, ByteVector* digest,
79c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu           TableMap* tables)
80c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    : factory_(factory),
81c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu      sfnt_version_(sfnt_version) {
82c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  // non-trivial assignments that makes debugging hard if placed in
83c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  // initialization list
84c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  digest_ = *digest;
85c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  tables_ = *tables;
8695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
8795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
88c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::BuildTableHeadersForSerialization(IntegerList* table_ordering,
8995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                             TableHeaderList* table_headers) {
9095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  assert(table_headers);
9195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  assert(table_ordering);
9295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
9395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  IntegerList final_table_ordering;
94c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  TableOrdering(table_ordering, &final_table_ordering);
95c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  int32_t table_offset = Offset::kTableRecordBegin + num_tables() *
9695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                         Offset::kTableRecordSize;
9795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (IntegerList::iterator tag = final_table_ordering.begin(),
9895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                             tag_end = final_table_ordering.end();
9995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                             tag != tag_end; ++tag) {
10095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    TablePtr table = tables_[*tag];
10195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    if (table != NULL) {
10295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      TableHeaderPtr header =
103c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu          new Table::Header(*tag, table->CalculatedChecksum(), table_offset,
104c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu                            table->Length());
10595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      table_headers->push_back(header);
106c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu      table_offset += (table->Length() + 3) & ~3;
10795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    }
10895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
10995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
11095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
111c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::SerializeHeader(FontOutputStream* fos,
11295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                           TableHeaderList* table_headers) {
113c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  fos->WriteFixed(sfnt_version_);
114c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  fos->WriteUShort(table_headers->size());
115c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  int32_t log2_of_max_power_of_2 = FontMath::Log2(table_headers->size());
11695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  int32_t search_range = 2 << (log2_of_max_power_of_2 - 1 + 4);
117c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  fos->WriteUShort(search_range);
118c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  fos->WriteUShort(log2_of_max_power_of_2);
119c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  fos->WriteUShort((table_headers->size() * 16) - search_range);
12095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
12195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (TableHeaderList::iterator record = table_headers->begin(),
12295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 record_end = table_headers->end();
12395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 record != record_end; ++record) {
124c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    fos->WriteULong((*record)->tag());
125c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    fos->WriteULong((int32_t)((*record)->checksum()));
126c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    fos->WriteULong((*record)->offset());
127c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    fos->WriteULong((*record)->length());
12895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
12995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
13095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
131c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::SerializeTables(FontOutputStream* fos,
13295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                           TableHeaderList* table_headers) {
13395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  ByteVector SERIALIZATION_FILLER(3);
13495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  std::fill(SERIALIZATION_FILLER.begin(), SERIALIZATION_FILLER.end(), 0);
13595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (TableHeaderList::iterator record = table_headers->begin(),
13695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 end_of_headers = table_headers->end();
13795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 record != end_of_headers; ++record) {
138c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    TablePtr target_table = GetTable((*record)->tag());
13995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    if (target_table == NULL) {
140fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#if defined (SFNTLY_NO_EXCEPTION)
141fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu      return;
142fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#else
14395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      throw IOException("Table out of sync with font header.");
144fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#endif
14595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    }
146c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    int32_t table_size = target_table->Serialize(fos);
14774dd654d997383188b37566661cbce34a8b82154arthurhsu    if (table_size != (*record)->length()) {
14874dd654d997383188b37566661cbce34a8b82154arthurhsu      assert(false);
14974dd654d997383188b37566661cbce34a8b82154arthurhsu    }
15095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    int32_t filler_size = ((table_size + 3) & ~3) - table_size;
151c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    fos->Write(&SERIALIZATION_FILLER, 0, filler_size);
15295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
15395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
15495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
155c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::TableOrdering(IntegerList* default_table_ordering,
15695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                         IntegerList* table_ordering) {
15795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  assert(default_table_ordering);
15895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  assert(table_ordering);
15995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  table_ordering->clear();
16095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  if (default_table_ordering->empty()) {
161c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    DefaultTableOrdering(default_table_ordering);
16295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
16395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
16495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  typedef std::map<int32_t, bool> Int2Bool;
16595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  typedef std::pair<int32_t, bool> Int2BoolEntry;
16695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  Int2Bool tables_in_font;
16795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (TableMap::iterator table = tables_.begin(), table_end = tables_.end();
16895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                          table != table_end; ++table) {
16995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    tables_in_font.insert(Int2BoolEntry(table->first, false));
17095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
17195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (IntegerList::iterator tag = default_table_ordering->begin(),
17295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                             tag_end = default_table_ordering->end();
17395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                             tag != tag_end; ++tag) {
174c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    if (HasTable(*tag)) {
17595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      table_ordering->push_back(*tag);
17695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      tables_in_font[*tag] = true;
17795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    }
17895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
17995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (Int2Bool::iterator table = tables_in_font.begin(),
18095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                          table_end = tables_in_font.end();
18195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                          table != table_end; ++table) {
18295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    if (table->second == false)
18395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      table_ordering->push_back(table->first);
18495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
18595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
18695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
187c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::DefaultTableOrdering(IntegerList* default_table_ordering) {
18895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  assert(default_table_ordering);
18995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  default_table_ordering->clear();
190c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  if (HasTable(Tag::CFF)) {
19195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    default_table_ordering->resize(CFF_TABLE_ORDERING_SIZE);
19295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    std::copy(CFF_TABLE_ORDERING, CFF_TABLE_ORDERING + CFF_TABLE_ORDERING_SIZE,
19395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu              default_table_ordering->begin());
19495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    return;
19595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
19695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  default_table_ordering->resize(TRUE_TYPE_TABLE_ORDERING_SIZE);
19795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  std::copy(TRUE_TYPE_TABLE_ORDERING,
19895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu            TRUE_TYPE_TABLE_ORDERING + TRUE_TYPE_TABLE_ORDERING_SIZE,
19995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu            default_table_ordering->begin());
20095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
20195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
20295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu/******************************************************************************
20395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * Font::Builder class
20495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu ******************************************************************************/
20595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsuFont::Builder::~Builder() {}
20695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
207c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(
20895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    FontFactory* factory, InputStream* is) {
20995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  FontBuilderPtr builder = new Builder(factory);
210c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  builder->LoadFont(is);
211c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  return builder.Detach();
21295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
21395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
214c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(
21595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    FontFactory* factory, ByteArray* ba, int32_t offset_to_offset_table) {
21695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  FontBuilderPtr builder = new Builder(factory);
217c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  builder->LoadFont(ba, offset_to_offset_table);
218c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  return builder.Detach();
21995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
22095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
221c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(
22295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    FontFactory* factory) {
22395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  FontBuilderPtr builder = new Builder(factory);
224c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  return builder.Detach();
22595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
22695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
227c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsubool Font::Builder::ReadyToBuild() {
22895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  // just read in data with no manipulation
22995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  if (table_builders_.empty() && !data_blocks_.empty()) {
23095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    return true;
23195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
23295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
23395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  // TODO(stuartg): font level checks - required tables etc.
23495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (TableBuilderMap::iterator table_builder = table_builders_.begin(),
23595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 table_builder_end = table_builders_.end();
23695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 table_builder != table_builder_end;
23795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 ++table_builder) {
238c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    if (!table_builder->second->ReadyToBuild())
23995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      return false;
24095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
24195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  return true;
24295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
24395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
244c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Font* Font::Builder::Build() {
24595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  TableMap tables;
24695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  if (!table_builders_.empty()) {
247c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    BuildTablesFromBuilders(&table_builders_, &tables);
24895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
24995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  FontPtr font = new Font(factory_, sfnt_version_, &digest_, &tables);
25095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  table_builders_.clear();
25195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  data_blocks_.clear();
252c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  return font.Detach();
25395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
25495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
255c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH WritableFontData* Font::Builder::GetNewData(int32_t capacity) {
256c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  return factory_->GetNewData(capacity);
25795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
25895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
259c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH WritableFontData* Font::Builder::GetNewGrowableData(
26095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    ReadableFontData* src_data) {
261c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  return factory_->GetNewGrowableData(src_data);
26295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
26395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
264c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::SetDigest(ByteVector* digest) {
26595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  digest_.clear();
26695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  digest_ = *digest;
26795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
26895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
269c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::CleanTableBuilders() {
27095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  table_builders_.clear();
27195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
27295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
273c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsubool Font::Builder::HasTableBuilder(int32_t tag) {
27495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  return (table_builders_.find(tag) != table_builders_.end());
27595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
27695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
277c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuTable::Builder* Font::Builder::GetTableBuilder(int32_t tag) {
278c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  if (HasTableBuilder(tag))
27995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    return table_builders_[tag];
28095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  return NULL;
28195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
28295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
283c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Table::Builder* Font::Builder::NewTableBuilder(int32_t tag) {
28495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  TableHeaderPtr header = new Table::Header(tag);
285c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  TableBuilderPtr builder = Table::Builder::GetBuilder(this, header, NULL);
28695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  table_builders_.insert(TableBuilderEntry(header->tag(), builder));
28795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  return builder;
28895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
28995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
290c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Table::Builder*
291c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    Font::Builder::NewTableBuilder(int32_t tag, ReadableFontData* src_data) {
29295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  WritableFontDataPtr data;
293c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  data.Attach(GetNewGrowableData(src_data));
29495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  TableHeaderPtr header = new Table::Header(tag);
295c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  TableBuilderPtr builder = Table::Builder::GetBuilder(this, header, data);
29695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  table_builders_.insert(TableBuilderEntry(tag, builder));
29795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  return builder;
29895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
29995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
300c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::TableBuilderTags(IntegerSet* key_set) {
30195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  assert(key_set);
30295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  key_set->clear();
30395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (TableBuilderMap::iterator i = table_builders_.begin(),
30495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 e = table_builders_.end(); i != e; ++i) {
30595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    key_set->insert(i->first);
30695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
30795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
30895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
309c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::RemoveTableBuilder(int32_t tag) {
31095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  TableBuilderMap::iterator target = table_builders_.find(tag);
31195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  if (target != table_builders_.end()) {
31295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    table_builders_.erase(target);
31395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
31495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
31595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
316c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuFont::Builder::Builder(FontFactory* factory)
317c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    : factory_(factory), sfnt_version_(SFNTVERSION_1) {
318c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu}
319c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu
320c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::LoadFont(InputStream* is) {
321c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  // Note: we do not throw exception here for is.  This is more of an assertion.
322c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  assert(is);
323c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  FontInputStream font_is(is);
324c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  TableHeaderSortedSet records;
325c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  ReadHeader(&font_is, &records);
326c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  LoadTableData(&records, &font_is, &data_blocks_);
327c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  BuildAllTableBuilders(&data_blocks_, &table_builders_);
328c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  font_is.Close();
329c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu}
330c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu
331c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::LoadFont(ByteArray* ba,
332c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu                             int32_t offset_to_offset_table) {
333c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  // Note: we do not throw exception here for is.  This is more of an assertion.
334c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  assert(ba);
335c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  WritableFontDataPtr fd = new WritableFontData(ba);
336c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  TableHeaderSortedSet records;
337c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  ReadHeader(fd, offset_to_offset_table, &records);
338c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  LoadTableData(&records, fd, &data_blocks_);
339c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  BuildAllTableBuilders(&data_blocks_, &table_builders_);
34095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
34195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
342c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuint32_t Font::Builder::SfntWrapperSize() {
34395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  return Offset::kSfntHeaderSize +
34495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu         (Offset::kTableRecordSize * table_builders_.size());
34595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
34695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
347c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::BuildAllTableBuilders(DataBlockMap* table_data,
34895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                          TableBuilderMap* builder_map) {
34995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (DataBlockMap::iterator record = table_data->begin(),
35095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                              record_end = table_data->end();
35195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                              record != record_end; ++record) {
35295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    TableBuilderPtr builder;
353c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    builder.Attach(GetTableBuilder(record->first.p_, record->second.p_));
35495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    builder_map->insert(TableBuilderEntry(record->first->tag(), builder));
35595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
356c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  InterRelateBuilders(&table_builders_);
35795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
35895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
359c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Table::Builder*
360c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    Font::Builder::GetTableBuilder(Table::Header* header,
361c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu                                   WritableFontData* data) {
362c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  return Table::Builder::GetBuilder(this, header, data);
36395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
36495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
365c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::BuildTablesFromBuilders(TableBuilderMap* builder_map,
36695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                            TableMap* table_map) {
367c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  InterRelateBuilders(builder_map);
36895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
36995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  // Now build all the tables.
37095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (TableBuilderMap::iterator builder = builder_map->begin(),
37195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 builder_end = builder_map->end();
37295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                 builder != builder_end; ++builder) {
37395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    TablePtr table;
3742f57786796743446495a41f1a1f8688b13fa1a86arthurhsu    if (builder->second && builder->second->ReadyToBuild()) {
375fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#if !defined (SFNTLY_NO_EXCEPTION)
37695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      try {
377fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#endif
378c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu        table.Attach(down_cast<Table*>(builder->second->Build()));
379fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#if !defined (SFNTLY_NO_EXCEPTION)
38095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      } catch(IOException& e) {
38195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu        std::string builder_string = "Unable to build table - ";
38295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu        builder_string += typeid(builder->second).name();
38395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu        builder_string += e.what();
38495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu        throw RuntimeException(builder_string.c_str());
38595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      }
386fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#endif
38795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    }
38895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    if (table == NULL) {
389fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#if defined (SFNTLY_NO_EXCEPTION)
3902ac95dcf52d76634fba3f8fa81c575424f01d992arthurhsu      table_map->clear();
391fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu      return;
392fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#else
39395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      std::string builder_string = "Unable to build table - ";
39495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      builder_string += typeid(builder->second).name();
39595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu      throw RuntimeException(builder_string.c_str());
396fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#endif
39795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    }
39895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    table_map->insert(TableMapEntry(table->header()->tag(), table));
39995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
40095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
40195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
4023eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsustatic Table::Builder* GetBuilder(TableBuilderMap* builder_map, int32_t tag) {
4033eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  if (builder_map) {
4043eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu    TableBuilderMap::iterator target = builder_map->find(tag);
4053eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu    if (target != builder_map->end()) {
4063eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu      return target->second.p_;
4073eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu    }
4083eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  }
4093eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu
4103eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  return NULL;
4113eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu}
4123eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu
413c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) {
4143eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  Table::Builder* raw_head_builder = GetBuilder(builder_map, Tag::head);
4153eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  FontHeaderTableBuilderPtr header_table_builder;
4163eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  if (raw_head_builder != NULL) {
4173eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu      header_table_builder =
4183eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu          down_cast<FontHeaderTable::Builder*>(raw_head_builder);
4193eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  }
4203eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu
4213eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  Table::Builder* raw_hhea_builder = GetBuilder(builder_map, Tag::hhea);
4223eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  HorizontalHeaderTableBuilderPtr horizontal_header_builder;
4233eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  if (raw_head_builder != NULL) {
4243eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu      horizontal_header_builder =
4253eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu          down_cast<HorizontalHeaderTable::Builder*>(raw_hhea_builder);
4263eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  }
4273eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu
4283eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  Table::Builder* raw_maxp_builder = GetBuilder(builder_map, Tag::maxp);
4293eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  MaximumProfileTableBuilderPtr max_profile_builder;
4303eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  if (raw_maxp_builder != NULL) {
4313eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu      max_profile_builder =
4323eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu          down_cast<MaximumProfileTable::Builder*>(raw_maxp_builder);
4333eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  }
4343eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu
4353eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  Table::Builder* raw_loca_builder = GetBuilder(builder_map, Tag::loca);
4363eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  LocaTableBuilderPtr loca_table_builder;
4373eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  if (raw_loca_builder != NULL) {
4383eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu      loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder);
4393eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  }
4403eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu
4413eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  Table::Builder* raw_hmtx_builder = GetBuilder(builder_map, Tag::hmtx);
4423eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  HorizontalMetricsTableBuilderPtr horizontal_metrics_builder;
4433eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  if (raw_hmtx_builder != NULL) {
4443eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu      horizontal_metrics_builder =
4453eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu          down_cast<HorizontalMetricsTable::Builder*>(raw_hmtx_builder);
4463eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu  }
44795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
44895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  // set the inter table data required to build certain tables
44995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  if (horizontal_metrics_builder != NULL) {
45095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    if (max_profile_builder != NULL) {
451c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu      horizontal_metrics_builder->SetNumGlyphs(
452c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu          max_profile_builder->NumGlyphs());
45395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    }
45495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    if (horizontal_header_builder != NULL) {
455c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu      horizontal_metrics_builder->SetNumberOfHMetrics(
456c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu          horizontal_header_builder->NumberOfHMetrics());
45795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    }
45895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
45995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
46095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  if (loca_table_builder != NULL) {
46195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    if (max_profile_builder != NULL) {
462c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu      loca_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs());
46395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    }
46495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    if (header_table_builder != NULL) {
465c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu      loca_table_builder->SetFormatVersion(
466c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu          header_table_builder->IndexToLocFormat());
46795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    }
46895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
46995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
47095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
471c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::ReadHeader(FontInputStream* is,
47295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                               TableHeaderSortedSet* records) {
47395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  assert(records);
474c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  sfnt_version_ = is->ReadFixed();
475c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  num_tables_ = is->ReadUShort();
476c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  search_range_ = is->ReadUShort();
477c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  entry_selector_ = is->ReadUShort();
478c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  range_shift_ = is->ReadUShort();
47995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
48095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (int32_t table_number = 0; table_number < num_tables_; ++table_number) {
48195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    // Need to use temporary vars here.  C++ evaluates function parameters from
48295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    // right to left and thus breaks the order of input stream.
483c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    int32_t tag = is->ReadULongAsInt();
484c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    int64_t checksum = is->ReadULong();
485c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    int32_t offset = is->ReadULongAsInt();
486c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    int32_t length = is->ReadULongAsInt();
48795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    TableHeaderPtr table = new Table::Header(tag, checksum, offset, length);
48895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    records->insert(table);
48995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
49095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
49195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
492c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::ReadHeader(ReadableFontData* fd,
493c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu                               int32_t offset,
494c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu                               TableHeaderSortedSet* records) {
495c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  assert(records);
496c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  sfnt_version_ = fd->ReadFixed(offset + Offset::kSfntVersion);
497c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  num_tables_ = fd->ReadUShort(offset + Offset::kNumTables);
498c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  search_range_ = fd->ReadUShort(offset + Offset::kSearchRange);
499c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  entry_selector_ = fd->ReadUShort(offset + Offset::kEntrySelector);
500c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  range_shift_ = fd->ReadUShort(offset + Offset::kRangeShift);
501c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu
502c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  int32_t table_offset = offset + Offset::kTableRecordBegin;
503c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  for (int32_t table_number = 0;
504c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu       table_number < num_tables_;
505c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu       table_number++, table_offset += Offset::kTableRecordSize) {
506c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    int32_t tag = fd->ReadULongAsInt(table_offset + Offset::kTableTag);
507c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    int64_t checksum = fd->ReadULong(table_offset + Offset::kTableCheckSum);
508c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    int32_t offset = fd->ReadULongAsInt(table_offset + Offset::kTableOffset);
509c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    int32_t length = fd->ReadULongAsInt(table_offset + Offset::kTableLength);
510c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    TableHeaderPtr table = new Table::Header(tag, checksum, offset, length);
511c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    records->insert(table);
512c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu  }
513c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu}
514c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu
515c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::LoadTableData(TableHeaderSortedSet* headers,
51695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                  FontInputStream* is,
51795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                  DataBlockMap* table_data) {
51895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  assert(table_data);
51995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (TableHeaderSortedSet::iterator
52095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu           table_header = headers->begin(), table_end = headers->end();
52195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu           table_header != table_end; ++table_header) {
522c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu    is->Skip((*table_header)->offset() - is->position());
52395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    FontInputStream table_is(is, (*table_header)->length());
52487114756046ef50158ad5bbf357bf40e05ebdd94arthurhsu    WritableFontDataPtr data;
52587114756046ef50158ad5bbf357bf40e05ebdd94arthurhsu    data.Attach(
52687114756046ef50158ad5bbf357bf40e05ebdd94arthurhsu        WritableFontData::CreateWritableFontData((*table_header)->length()));
52787114756046ef50158ad5bbf357bf40e05ebdd94arthurhsu    data->CopyFrom(&table_is, (*table_header)->length());
52895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    table_data->insert(DataBlockEntry(*table_header, data));
52995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
53095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
53195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
532c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::LoadTableData(TableHeaderSortedSet* headers,
53395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                  WritableFontData* fd,
53495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu                                  DataBlockMap* table_data) {
53595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  for (TableHeaderSortedSet::iterator
53695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu           table_header = headers->begin(), table_end = headers->end();
53795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu           table_header != table_end; ++table_header) {
53895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    FontDataPtr sliced_data;
53987114756046ef50158ad5bbf357bf40e05ebdd94arthurhsu    sliced_data.Attach(
54087114756046ef50158ad5bbf357bf40e05ebdd94arthurhsu        fd->Slice((*table_header)->offset(), (*table_header)->length()));
54195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    WritableFontDataPtr data = down_cast<WritableFontData*>(sliced_data.p_);
54295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu    table_data->insert(DataBlockEntry(*table_header, data));
54395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu  }
54495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}
54595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu
54695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu}  // namespace sfntly
547