font.cc revision 30d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cd
130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/* 230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Copyright 2011 Google Inc. All Rights Reserved. 330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Licensed under the Apache License, Version 2.0 (the "License"); 530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * you may not use this file except in compliance with the License. 630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * You may obtain a copy of the License at 730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * http://www.apache.org/licenses/LICENSE-2.0 930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Unless required by applicable law or agreed to in writing, software 1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * distributed under the License is distributed on an "AS IS" BASIS, 1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * See the License for the specific language governing permissions and 1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * limitations under the License. 1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun */ 1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/font.h" 1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <stdio.h> 2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <functional> 2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <algorithm> 2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <map> 2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <string> 2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <typeinfo> 2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <iterator> 2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/data/font_input_stream.h" 2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/font_factory.h" 3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/math/fixed1616.h" 3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/math/font_math.h" 3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/exception_type.h" 3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/core/font_header_table.h" 3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/core/horizontal_device_metrics_table.h" 3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/core/horizontal_header_table.h" 3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/core/horizontal_metrics_table.h" 3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/core/maximum_profile_table.h" 3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/truetype/loca_table.h" 3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/tag.h" 4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly { 4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t SFNTVERSION_MAJOR = 1; 4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t SFNTVERSION_MINOR = 0; 4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Font class 4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFont::~Font() {} 5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool Font::HasTable(int32_t tag) { 5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableMap::const_iterator result = tables_.find(tag); 5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableMap::const_iterator end = tables_.end(); 5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return (result != end); 5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTable* Font::GetTable(int32_t tag) { 5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!HasTable(tag)) { 5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return tables_[tag]; 6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst TableMap* Font::GetTableMap() { 6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return &tables_; 6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Serialize(OutputStream* os, IntegerList* table_ordering) { 6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(table_ordering); 7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun IntegerList final_table_ordering; 7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GenerateTableOrdering(table_ordering, &final_table_ordering); 7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableHeaderList table_records; 7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun BuildTableHeadersForSerialization(&final_table_ordering, &table_records); 7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontOutputStream fos(os); 7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun SerializeHeader(&fos, &table_records); 7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun SerializeTables(&fos, &table_records); 7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFont::Font(int32_t sfnt_version, ByteVector* digest) 8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : sfnt_version_(sfnt_version) { 8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // non-trivial assignments that makes debugging hard if placed in 8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // initialization list 8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun digest_ = *digest; 8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::BuildTableHeadersForSerialization(IntegerList* table_ordering, 8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableHeaderList* table_headers) { 8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(table_headers); 9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(table_ordering); 9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun IntegerList final_table_ordering; 9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GenerateTableOrdering(table_ordering, &final_table_ordering); 9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t table_offset = Offset::kTableRecordBegin + num_tables() * 9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kTableRecordSize; 9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (IntegerList::iterator tag = final_table_ordering.begin(), 9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun tag_end = final_table_ordering.end(); 9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun tag != tag_end; ++tag) { 9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (tables_.find(*tag) == tables_.end()) { 10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun continue; 10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TablePtr table = tables_[*tag]; 10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (table != NULL) { 10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderPtr header = 10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun new Header(*tag, table->CalculatedChecksum(), table_offset, 10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table->header()->length()); 10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_headers->push_back(header); 10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_offset += (table->DataLength() + 3) & ~3; 10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::SerializeHeader(FontOutputStream* fos, 11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableHeaderList* table_headers) { 11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->WriteFixed(sfnt_version_); 11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->WriteUShort(table_headers->size()); 11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t log2_of_max_power_of_2 = FontMath::Log2(table_headers->size()); 11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t search_range = 2 << (log2_of_max_power_of_2 - 1 + 4); 11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->WriteUShort(search_range); 12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->WriteUShort(log2_of_max_power_of_2); 12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->WriteUShort((table_headers->size() * 16) - search_range); 12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderTagSortedSet sorted_headers; 12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun std::copy(table_headers->begin(), 12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_headers->end(), 12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun std::inserter(sorted_headers, sorted_headers.end())); 12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (HeaderTagSortedSet::iterator record = sorted_headers.begin(), 12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun record_end = sorted_headers.end(); 13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun record != record_end; ++record) { 13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->WriteULong((*record)->tag()); 13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->WriteULong((int32_t)((*record)->checksum())); 13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->WriteULong((*record)->offset()); 13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->WriteULong((*record)->length()); 13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::SerializeTables(FontOutputStream* fos, 13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableHeaderList* table_headers) { 14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(fos); 14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(table_headers); 14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (TableHeaderList::iterator record = table_headers->begin(), 14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun end_of_headers = table_headers->end(); 14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun record != end_of_headers; ++record) { 14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TablePtr target_table = GetTable((*record)->tag()); 14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (target_table == NULL) { 14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IOException("Table out of sync with font header."); 14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t table_size = target_table->Serialize(fos); 15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (table_size != (*record)->length()) { 15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(false); 15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t filler_size = ((table_size + 3) & ~3) - table_size; 15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < filler_size; ++i) { 15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fos->Write(static_cast<byte_t>(0)); 15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::GenerateTableOrdering(IntegerList* default_table_ordering, 16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun IntegerList* table_ordering) { 16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(default_table_ordering); 16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(table_ordering); 16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_ordering->clear(); 16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (default_table_ordering->empty()) { 16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DefaultTableOrdering(default_table_ordering); 17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun typedef std::map<int32_t, bool> Int2Bool; 17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun typedef std::pair<int32_t, bool> Int2BoolEntry; 17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Int2Bool tables_in_font; 17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (TableMap::iterator table = tables_.begin(), table_end = tables_.end(); 17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table != table_end; ++table) { 17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun tables_in_font.insert(Int2BoolEntry(table->first, false)); 17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (IntegerList::iterator tag = default_table_ordering->begin(), 18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun tag_end = default_table_ordering->end(); 18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun tag != tag_end; ++tag) { 18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (HasTable(*tag)) { 18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_ordering->push_back(*tag); 18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun tables_in_font[*tag] = true; 18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (Int2Bool::iterator table = tables_in_font.begin(), 18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_end = tables_in_font.end(); 18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table != table_end; ++table) { 19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (table->second == false) 19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_ordering->push_back(table->first); 19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::DefaultTableOrdering(IntegerList* default_table_ordering) { 19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(default_table_ordering); 19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun default_table_ordering->clear(); 19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (HasTable(Tag::CFF)) { 19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun default_table_ordering->resize(CFF_TABLE_ORDERING_SIZE); 20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun std::copy(CFF_TABLE_ORDERING, CFF_TABLE_ORDERING + CFF_TABLE_ORDERING_SIZE, 20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun default_table_ordering->begin()); 20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun default_table_ordering->resize(TRUE_TYPE_TABLE_ORDERING_SIZE); 20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun std::copy(TRUE_TYPE_TABLE_ORDERING, 20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TRUE_TYPE_TABLE_ORDERING + TRUE_TYPE_TABLE_ORDERING_SIZE, 20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun default_table_ordering->begin()); 20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Font::Builder class 21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFont::Builder::~Builder() {} 21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(FontFactory* factory, 21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun InputStream* is) { 21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontBuilderPtr builder = new Builder(factory); 21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder->LoadFont(is); 21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder( 22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontFactory* factory, 22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData* wfd, 22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset_to_offset_table) { 22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontBuilderPtr builder = new Builder(factory); 22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder->LoadFont(wfd, offset_to_offset_table); 22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder( 23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontFactory* factory) { 23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontBuilderPtr builder = new Builder(factory); 23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool Font::Builder::ReadyToBuild() { 23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // just read in data with no manipulation 23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (table_builders_.empty() && !data_blocks_.empty()) { 24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // TODO(stuartg): font level checks - required tables etc? 24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (TableBuilderMap::iterator table_builder = table_builders_.begin(), 24530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_builder_end = table_builders_.end(); 24630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_builder != table_builder_end; 24730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ++table_builder) { 24830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!table_builder->second->ReadyToBuild()) 24930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 25030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 25130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 25230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 25330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 25430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH Font* Font::Builder::Build() { 25530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontPtr font = new Font(sfnt_version_, &digest_); 25630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 25730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!table_builders_.empty()) { 25830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Note: Different from Java. Directly use font->tables_ here to avoid 25930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // STL container copying. 26030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun BuildTablesFromBuilders(font, &table_builders_, &font->tables_); 26130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 26230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 26330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_builders_.clear(); 26430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data_blocks_.clear(); 26530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return font.Detach(); 26630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 26730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 26830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::SetDigest(ByteVector* digest) { 26930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun digest_.clear(); 27030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun digest_ = *digest; 27130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 27230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 27330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::ClearTableBuilders() { 27430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_builders_.clear(); 27530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 27630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 27730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool Font::Builder::HasTableBuilder(int32_t tag) { 27830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return (table_builders_.find(tag) != table_builders_.end()); 27930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 28030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 28130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTable::Builder* Font::Builder::GetTableBuilder(int32_t tag) { 28230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (HasTableBuilder(tag)) 28330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return table_builders_[tag]; 28430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 28530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 28630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 28730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTable::Builder* Font::Builder::NewTableBuilder(int32_t tag) { 28830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderPtr header = new Header(tag); 28930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableBuilderPtr builder; 29030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder.Attach(Table::Builder::GetBuilder(header, NULL)); 29130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_builders_.insert(TableBuilderEntry(header->tag(), builder)); 29230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder; 29330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 29430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 29530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTable::Builder* Font::Builder::NewTableBuilder(int32_t tag, 29630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* src_data) { 29730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(src_data); 29830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontDataPtr data; 29930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data.Attach(WritableFontData::CreateWritableFontData(src_data->Length())); 30030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // TODO(stuarg): take over original data instead? 30130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun src_data->CopyTo(data); 30230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 30330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderPtr header = new Header(tag, data->Length()); 30430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableBuilderPtr builder; 30530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder.Attach(Table::Builder::GetBuilder(header, data)); 30630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_builders_.insert(TableBuilderEntry(tag, builder)); 30730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder; 30830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 30930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 31030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::RemoveTableBuilder(int32_t tag) { 31130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableBuilderMap::iterator target = table_builders_.find(tag); 31230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (target != table_builders_.end()) { 31330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_builders_.erase(target); 31430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 31530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 31630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 31730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFont::Builder::Builder(FontFactory* factory) 31830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : factory_(factory), 31930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sfnt_version_(Fixed1616::Fixed(SFNTVERSION_MAJOR, SFNTVERSION_MINOR)) { 32030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 32130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 32230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::LoadFont(InputStream* is) { 32330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Note: we do not throw exception here for is. This is more of an assertion. 32430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(is); 32530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontInputStream font_is(is); 32630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderOffsetSortedSet records; 32730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadHeader(&font_is, &records); 32830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun LoadTableData(&records, &font_is, &data_blocks_); 32930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun BuildAllTableBuilders(&data_blocks_, &table_builders_); 33030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun font_is.Close(); 33130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 33230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 33330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::LoadFont(WritableFontData* wfd, 33430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset_to_offset_table) { 33530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Note: we do not throw exception here for is. This is more of an assertion. 33630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(wfd); 33730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderOffsetSortedSet records; 33830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadHeader(wfd, offset_to_offset_table, &records); 33930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun LoadTableData(&records, wfd, &data_blocks_); 34030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun BuildAllTableBuilders(&data_blocks_, &table_builders_); 34130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 34230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 34330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t Font::Builder::SfntWrapperSize() { 34430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return Offset::kSfntHeaderSize + 34530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (Offset::kTableRecordSize * table_builders_.size()); 34630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 34730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 34830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::BuildAllTableBuilders(DataBlockMap* table_data, 34930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableBuilderMap* builder_map) { 35030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (DataBlockMap::iterator record = table_data->begin(), 35130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun record_end = table_data->end(); 35230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun record != record_end; ++record) { 35330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableBuilderPtr builder; 35430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder.Attach(GetTableBuilder(record->first.p_, record->second.p_)); 35530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder_map->insert(TableBuilderEntry(record->first->tag(), builder)); 35630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 35730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun InterRelateBuilders(&table_builders_); 35830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 35930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 36030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH 36130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTable::Builder* Font::Builder::GetTableBuilder(Header* header, 36230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData* data) { 36330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return Table::Builder::GetBuilder(header, data); 36430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 36530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 36630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::BuildTablesFromBuilders(Font* font, 36730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableBuilderMap* builder_map, 36830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableMap* table_map) { 36930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(font); 37030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun InterRelateBuilders(builder_map); 37130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 37230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Now build all the tables. 37330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (TableBuilderMap::iterator builder = builder_map->begin(), 37430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder_end = builder_map->end(); 37530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder != builder_end; ++builder) { 37630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TablePtr table; 37730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (builder->second && builder->second->ReadyToBuild()) { 37830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table.Attach(down_cast<Table*>(builder->second->Build())); 37930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 38030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (table == NULL) { 38130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_map->clear(); 38230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 38330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun std::string builder_string = "Unable to build table - "; 38430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun char* table_name = TagToString(builder->first); 38530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder_string += table_name; 38630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun delete[] table_name; 38730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw RuntimeException(builder_string.c_str()); 38830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 38930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 39030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 39130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_map->insert(TableMapEntry(table->header()->tag(), table)); 39230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 39330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 39430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 39530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstatic Table::Builder* GetBuilder(TableBuilderMap* builder_map, int32_t tag) { 39630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (builder_map) { 39730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun TableBuilderMap::iterator target = builder_map->find(tag); 39830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (target != builder_map->end()) { 39930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return target->second.p_; 40030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 40130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 40230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 40330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 40430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 40530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 40630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) { 40730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Table::Builder* raw_head_builder = GetBuilder(builder_map, Tag::head); 40830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontHeaderTableBuilderPtr header_table_builder; 40930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (raw_head_builder != NULL) { 41030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun header_table_builder = 41130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun down_cast<FontHeaderTable::Builder*>(raw_head_builder); 41230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 41330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 41430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Table::Builder* raw_hhea_builder = GetBuilder(builder_map, Tag::hhea); 41530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HorizontalHeaderTableBuilderPtr horizontal_header_builder; 41630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (raw_head_builder != NULL) { 41730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun horizontal_header_builder = 41830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun down_cast<HorizontalHeaderTable::Builder*>(raw_hhea_builder); 41930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 42030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 42130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Table::Builder* raw_maxp_builder = GetBuilder(builder_map, Tag::maxp); 42230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MaximumProfileTableBuilderPtr max_profile_builder; 42330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (raw_maxp_builder != NULL) { 42430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun max_profile_builder = 42530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun down_cast<MaximumProfileTable::Builder*>(raw_maxp_builder); 42630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 42730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 42830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Table::Builder* raw_loca_builder = GetBuilder(builder_map, Tag::loca); 42930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun LocaTableBuilderPtr loca_table_builder; 43030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (raw_loca_builder != NULL) { 43130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder); 43230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 43330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 43430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Table::Builder* raw_hmtx_builder = GetBuilder(builder_map, Tag::hmtx); 43530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HorizontalMetricsTableBuilderPtr horizontal_metrics_builder; 43630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (raw_hmtx_builder != NULL) { 43730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun horizontal_metrics_builder = 43830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun down_cast<HorizontalMetricsTable::Builder*>(raw_hmtx_builder); 43930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 44030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 44130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_EXPERIMENTAL) 44230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Table::Builder* raw_hdmx_builder = GetBuilder(builder_map, Tag::hdmx); 44330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HorizontalDeviceMetricsTableBuilderPtr hdmx_table_builder; 44430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (raw_hdmx_builder != NULL) { 44530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun hdmx_table_builder = 44630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun down_cast<HorizontalDeviceMetricsTable::Builder*>(raw_hdmx_builder); 44730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 44830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 44930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 45030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // set the inter table data required to build certain tables 45130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (horizontal_metrics_builder != NULL) { 45230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (max_profile_builder != NULL) { 45330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun horizontal_metrics_builder->SetNumGlyphs( 45430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun max_profile_builder->NumGlyphs()); 45530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 45630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (horizontal_header_builder != NULL) { 45730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun horizontal_metrics_builder->SetNumberOfHMetrics( 45830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun horizontal_header_builder->NumberOfHMetrics()); 45930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 46030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 46130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 46230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (loca_table_builder != NULL) { 46330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (max_profile_builder != NULL) { 46430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs()); 46530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 46630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (header_table_builder != NULL) { 46730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_table_builder->set_format_version( 46830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun header_table_builder->IndexToLocFormat()); 46930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 47030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 47130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 47230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_EXPERIMENTAL) 47330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Note: In C++, hdmx_table_builder can be NULL in a subsetter. 47430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (max_profile_builder != NULL && hdmx_table_builder != NULL) { 47530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun hdmx_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs()); 47630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 47730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 47830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 47930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 48030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::ReadHeader(FontInputStream* is, 48130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderOffsetSortedSet* records) { 48230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(records); 48330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sfnt_version_ = is->ReadFixed(); 48430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun num_tables_ = is->ReadUShort(); 48530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun search_range_ = is->ReadUShort(); 48630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun entry_selector_ = is->ReadUShort(); 48730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun range_shift_ = is->ReadUShort(); 48830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 48930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t table_number = 0; table_number < num_tables_; ++table_number) { 49030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Need to use temporary vars here. C++ evaluates function parameters from 49130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // right to left and thus breaks the order of input stream. 49230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t tag = is->ReadULongAsInt(); 49330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int64_t checksum = is->ReadULong(); 49430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset = is->ReadULongAsInt(); 49530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t length = is->ReadULongAsInt(); 49630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderPtr table = new Header(tag, checksum, offset, length); 49730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun records->insert(table); 49830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 49930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 50030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 50130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::ReadHeader(ReadableFontData* fd, 50230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 50330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderOffsetSortedSet* records) { 50430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(records); 50530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sfnt_version_ = fd->ReadFixed(offset + Offset::kSfntVersion); 50630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun num_tables_ = fd->ReadUShort(offset + Offset::kNumTables); 50730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun search_range_ = fd->ReadUShort(offset + Offset::kSearchRange); 50830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun entry_selector_ = fd->ReadUShort(offset + Offset::kEntrySelector); 50930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun range_shift_ = fd->ReadUShort(offset + Offset::kRangeShift); 51030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 51130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t table_offset = offset + Offset::kTableRecordBegin; 51230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t table_number = 0; 51330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_number < num_tables_; 51430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_number++, table_offset += Offset::kTableRecordSize) { 51530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t tag = fd->ReadULongAsInt(table_offset + Offset::kTableTag); 51630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int64_t checksum = fd->ReadULong(table_offset + Offset::kTableCheckSum); 51730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset = fd->ReadULongAsInt(table_offset + Offset::kTableOffset); 51830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t length = fd->ReadULongAsInt(table_offset + Offset::kTableLength); 51930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun HeaderPtr table = new Header(tag, checksum, offset, length); 52030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun records->insert(table); 52130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 52230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 52330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 52430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers, 52530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontInputStream* is, 52630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataBlockMap* table_data) { 52730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(table_data); 52830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (HeaderOffsetSortedSet::iterator table_header = headers->begin(), 52930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_end = headers->end(); 53030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_header != table_end; 53130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ++table_header) { 53230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun is->Skip((*table_header)->offset() - is->position()); 53330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontInputStream table_is(is, (*table_header)->length()); 53430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontDataPtr data; 53530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data.Attach( 53630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData::CreateWritableFontData((*table_header)->length())); 53730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->CopyFrom(&table_is, (*table_header)->length()); 53830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_data->insert(DataBlockEntry(*table_header, data)); 53930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 54030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 54130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 54230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers, 54330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData* fd, 54430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataBlockMap* table_data) { 54530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (HeaderOffsetSortedSet::iterator table_header = headers->begin(), 54630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_end = headers->end(); 54730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_header != table_end; 54830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ++table_header) { 54930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataPtr sliced_data; 55030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sliced_data.Attach( 55130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fd->Slice((*table_header)->offset(), (*table_header)->length())); 55230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontDataPtr data = down_cast<WritableFontData*>(sliced_data.p_); 55330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun table_data->insert(DataBlockEntry(*table_header, data)); 55430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 55530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 55630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 55730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} // namespace sfntly 558