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