font.cc revision 813efeb18bf6205354b01a525352ebdb10eebe06
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 19f48f9495bfb5297171b933641a0a489cb86ad39bdfilimon#include <stdio.h> 20f48f9495bfb5297171b933641a0a489cb86ad39bdfilimon 2195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include <functional> 2295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include <algorithm> 2395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include <map> 24f48f9495bfb5297171b933641a0a489cb86ad39bdfilimon#include <string> 2595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include <typeinfo> 266a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu#include <iterator> 2795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 28c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu#include "sfntly/data/font_input_stream.h" 2995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include "sfntly/font_factory.h" 3095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include "sfntly/math/fixed1616.h" 3195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include "sfntly/math/font_math.h" 3295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu#include "sfntly/port/exception_type.h" 33584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/core/font_header_table.h" 349e5bf57583793d6db93bb01fd982760ad110a50farthurhsu#include "sfntly/table/core/horizontal_device_metrics_table.h" 35584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/core/horizontal_header_table.h" 36584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/core/horizontal_metrics_table.h" 37584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/core/maximum_profile_table.h" 38584bf6606b53bda8bf0810e7c0ad57e24cacb4f1arthurhsu#include "sfntly/table/truetype/loca_table.h" 39c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu#include "sfntly/tag.h" 4095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 4195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsunamespace sfntly { 4295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 43813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhangnamespace { 44813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang 45813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhangconst int32_t kSFNTVersionMajor = 1; 46813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhangconst int32_t kSFNTVersionMinor = 0; 47813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang 48813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhangconst int32_t kMaxTableSize = 200 * 1024 * 1024; 49813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang 50813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang} // namespace 5195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 5295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu/****************************************************************************** 5395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * Font class 5495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu ******************************************************************************/ 5595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsuFont::~Font() {} 5695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 57813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhangbool Font::HasTable(int32_t tag) const { 58813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang return tables_.find(tag) != tables_.end(); 5995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 6095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 61c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuTable* Font::GetTable(int32_t tag) { 62813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang if (!HasTable(tag)) 6395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return NULL; 6495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return tables_[tag]; 6595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 6695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 676a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuconst TableMap* Font::GetTableMap() { 6895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return &tables_; 6995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 7095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 71c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Serialize(OutputStream* os, IntegerList* table_ordering) { 7295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu assert(table_ordering); 7395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu IntegerList final_table_ordering; 746a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu GenerateTableOrdering(table_ordering, &final_table_ordering); 7595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TableHeaderList table_records; 76c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu BuildTableHeadersForSerialization(&final_table_ordering, &table_records); 7795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 7895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu FontOutputStream fos(os); 79c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu SerializeHeader(&fos, &table_records); 80c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu SerializeTables(&fos, &table_records); 81c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu} 82c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu 836a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuFont::Font(int32_t sfnt_version, ByteVector* digest) 846a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu : sfnt_version_(sfnt_version) { 85c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu // non-trivial assignments that makes debugging hard if placed in 86c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu // initialization list 87c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu digest_ = *digest; 8895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 8995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 90c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::BuildTableHeadersForSerialization(IntegerList* table_ordering, 9195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TableHeaderList* table_headers) { 9295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu assert(table_headers); 9395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu assert(table_ordering); 9495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 9595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu IntegerList final_table_ordering; 966a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu GenerateTableOrdering(table_ordering, &final_table_ordering); 97c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t table_offset = Offset::kTableRecordBegin + num_tables() * 9895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu Offset::kTableRecordSize; 9995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu for (IntegerList::iterator tag = final_table_ordering.begin(), 10095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu tag_end = final_table_ordering.end(); 10195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu tag != tag_end; ++tag) { 1026a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu if (tables_.find(*tag) == tables_.end()) { 1036a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu continue; 1046a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu } 10595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TablePtr table = tables_[*tag]; 10695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (table != NULL) { 10728258feb374913d40c347932937500210ba23d7carthurhsu HeaderPtr header = 10828258feb374913d40c347932937500210ba23d7carthurhsu new Header(*tag, table->CalculatedChecksum(), table_offset, 10928258feb374913d40c347932937500210ba23d7carthurhsu table->header()->length()); 11095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_headers->push_back(header); 1116a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu table_offset += (table->DataLength() + 3) & ~3; 11295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 11395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 11495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 11595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 116c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::SerializeHeader(FontOutputStream* fos, 11795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TableHeaderList* table_headers) { 118c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu fos->WriteFixed(sfnt_version_); 119c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu fos->WriteUShort(table_headers->size()); 120c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t log2_of_max_power_of_2 = FontMath::Log2(table_headers->size()); 12195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu int32_t search_range = 2 << (log2_of_max_power_of_2 - 1 + 4); 122c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu fos->WriteUShort(search_range); 123c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu fos->WriteUShort(log2_of_max_power_of_2); 124c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu fos->WriteUShort((table_headers->size() * 16) - search_range); 12595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 1266a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu HeaderTagSortedSet sorted_headers; 1276a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu std::copy(table_headers->begin(), 1286a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu table_headers->end(), 1296a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu std::inserter(sorted_headers, sorted_headers.end())); 1306a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu 1316a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu for (HeaderTagSortedSet::iterator record = sorted_headers.begin(), 1326a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu record_end = sorted_headers.end(); 1336a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu record != record_end; ++record) { 134c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu fos->WriteULong((*record)->tag()); 135c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu fos->WriteULong((int32_t)((*record)->checksum())); 136c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu fos->WriteULong((*record)->offset()); 137c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu fos->WriteULong((*record)->length()); 13895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 13995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 14095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 141c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::SerializeTables(FontOutputStream* fos, 14295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TableHeaderList* table_headers) { 1436a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu assert(fos); 1446a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu assert(table_headers); 14595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu for (TableHeaderList::iterator record = table_headers->begin(), 14695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu end_of_headers = table_headers->end(); 14795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu record != end_of_headers; ++record) { 148c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu TablePtr target_table = GetTable((*record)->tag()); 14995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (target_table == NULL) { 1506a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu#if !defined (SFNTLY_NO_EXCEPTION) 15195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu throw IOException("Table out of sync with font header."); 152fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#endif 1536a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu return; 15495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 155c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t table_size = target_table->Serialize(fos); 15674dd654d997383188b37566661cbce34a8b82154arthurhsu if (table_size != (*record)->length()) { 15774dd654d997383188b37566661cbce34a8b82154arthurhsu assert(false); 15874dd654d997383188b37566661cbce34a8b82154arthurhsu } 15995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu int32_t filler_size = ((table_size + 3) & ~3) - table_size; 1606a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu for (int32_t i = 0; i < filler_size; ++i) { 1616a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu fos->Write(static_cast<byte_t>(0)); 1626a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu } 16395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 16495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 16595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 1666a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuvoid Font::GenerateTableOrdering(IntegerList* default_table_ordering, 1676a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu IntegerList* table_ordering) { 16895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu assert(default_table_ordering); 16995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu assert(table_ordering); 17095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_ordering->clear(); 17195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (default_table_ordering->empty()) { 172c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu DefaultTableOrdering(default_table_ordering); 17395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 17495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 17595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu typedef std::map<int32_t, bool> Int2Bool; 17695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu typedef std::pair<int32_t, bool> Int2BoolEntry; 17795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu Int2Bool tables_in_font; 17895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu for (TableMap::iterator table = tables_.begin(), table_end = tables_.end(); 17995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table != table_end; ++table) { 18095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu tables_in_font.insert(Int2BoolEntry(table->first, false)); 18195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 18295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu for (IntegerList::iterator tag = default_table_ordering->begin(), 18395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu tag_end = default_table_ordering->end(); 18495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu tag != tag_end; ++tag) { 185c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu if (HasTable(*tag)) { 18695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_ordering->push_back(*tag); 18795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu tables_in_font[*tag] = true; 18895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 18995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 19095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu for (Int2Bool::iterator table = tables_in_font.begin(), 19195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_end = tables_in_font.end(); 19295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table != table_end; ++table) { 19395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (table->second == false) 19495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_ordering->push_back(table->first); 19595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 19695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 19795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 198c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::DefaultTableOrdering(IntegerList* default_table_ordering) { 19995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu assert(default_table_ordering); 20095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu default_table_ordering->clear(); 201c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu if (HasTable(Tag::CFF)) { 20295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu default_table_ordering->resize(CFF_TABLE_ORDERING_SIZE); 20395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu std::copy(CFF_TABLE_ORDERING, CFF_TABLE_ORDERING + CFF_TABLE_ORDERING_SIZE, 20495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu default_table_ordering->begin()); 20595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return; 20695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 20795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu default_table_ordering->resize(TRUE_TYPE_TABLE_ORDERING_SIZE); 20895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu std::copy(TRUE_TYPE_TABLE_ORDERING, 20995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TRUE_TYPE_TABLE_ORDERING + TRUE_TYPE_TABLE_ORDERING_SIZE, 21095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu default_table_ordering->begin()); 21195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 21295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 21395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu/****************************************************************************** 21495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu * Font::Builder class 21595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu ******************************************************************************/ 21695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsuFont::Builder::~Builder() {} 21795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 2186a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuCALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(FontFactory* factory, 2196a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu InputStream* is) { 22095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu FontBuilderPtr builder = new Builder(factory); 221c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu builder->LoadFont(is); 222c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu return builder.Detach(); 22395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 22495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 225c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder( 2266a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu FontFactory* factory, 2276a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu WritableFontData* wfd, 2286a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu int32_t offset_to_offset_table) { 22995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu FontBuilderPtr builder = new Builder(factory); 2306a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu builder->LoadFont(wfd, offset_to_offset_table); 231c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu return builder.Detach(); 23295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 23395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 234c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder( 23595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu FontFactory* factory) { 23695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu FontBuilderPtr builder = new Builder(factory); 237c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu return builder.Detach(); 23895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 23995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 240c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsubool Font::Builder::ReadyToBuild() { 24195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu // just read in data with no manipulation 24295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (table_builders_.empty() && !data_blocks_.empty()) { 24395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return true; 24495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 24595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 2466a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu // TODO(stuartg): font level checks - required tables etc? 24795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu for (TableBuilderMap::iterator table_builder = table_builders_.begin(), 24895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_builder_end = table_builders_.end(); 24995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_builder != table_builder_end; 25095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu ++table_builder) { 251c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu if (!table_builder->second->ReadyToBuild()) 25295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return false; 25395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 25495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return true; 25595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 25695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 257c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuCALLER_ATTACH Font* Font::Builder::Build() { 2586a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu FontPtr font = new Font(sfnt_version_, &digest_); 2596a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu 26095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (!table_builders_.empty()) { 2616a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu // Note: Different from Java. Directly use font->tables_ here to avoid 2626a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu // STL container copying. 2636a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu BuildTablesFromBuilders(font, &table_builders_, &font->tables_); 26495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 2656a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu 26695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_builders_.clear(); 26795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu data_blocks_.clear(); 268c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu return font.Detach(); 26995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 27095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 271c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::SetDigest(ByteVector* digest) { 27295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu digest_.clear(); 27395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu digest_ = *digest; 27495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 27595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 2766a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuvoid Font::Builder::ClearTableBuilders() { 27795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_builders_.clear(); 27895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 27995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 280c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsubool Font::Builder::HasTableBuilder(int32_t tag) { 28195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return (table_builders_.find(tag) != table_builders_.end()); 28295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 28395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 284c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuTable::Builder* Font::Builder::GetTableBuilder(int32_t tag) { 285c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu if (HasTableBuilder(tag)) 28695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return table_builders_[tag]; 28795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return NULL; 28895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 28995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 290f48f9495bfb5297171b933641a0a489cb86ad39bdfilimonTable::Builder* Font::Builder::NewTableBuilder(int32_t tag) { 29128258feb374913d40c347932937500210ba23d7carthurhsu HeaderPtr header = new Header(tag); 292f48f9495bfb5297171b933641a0a489cb86ad39bdfilimon TableBuilderPtr builder; 2936a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu builder.Attach(Table::Builder::GetBuilder(header, NULL)); 29495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_builders_.insert(TableBuilderEntry(header->tag(), builder)); 29595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return builder; 29695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 29795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 298f48f9495bfb5297171b933641a0a489cb86ad39bdfilimonTable::Builder* Font::Builder::NewTableBuilder(int32_t tag, 299f48f9495bfb5297171b933641a0a489cb86ad39bdfilimon ReadableFontData* src_data) { 3006a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu assert(src_data); 30195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu WritableFontDataPtr data; 3026a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu data.Attach(WritableFontData::CreateWritableFontData(src_data->Length())); 303158cdcb9cf09418ba8b49f4be7be69e37aa8e9faarthurhsu // TODO(stuarg): take over original data instead? 304158cdcb9cf09418ba8b49f4be7be69e37aa8e9faarthurhsu src_data->CopyTo(data); 305158cdcb9cf09418ba8b49f4be7be69e37aa8e9faarthurhsu 30628258feb374913d40c347932937500210ba23d7carthurhsu HeaderPtr header = new Header(tag, data->Length()); 307f48f9495bfb5297171b933641a0a489cb86ad39bdfilimon TableBuilderPtr builder; 3086a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu builder.Attach(Table::Builder::GetBuilder(header, data)); 30995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_builders_.insert(TableBuilderEntry(tag, builder)); 31095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return builder; 31195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 31295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 313c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::RemoveTableBuilder(int32_t tag) { 314813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang table_builders_.erase(tag); 31595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 31695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 317c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuFont::Builder::Builder(FontFactory* factory) 3189d49ee2650b0ffd660ff22f93ca9a6831847446farthurhsu : factory_(factory), 319813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang sfnt_version_(Fixed1616::Fixed(kSFNTVersionMajor, kSFNTVersionMinor)) { 320c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu} 321c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu 322c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::LoadFont(InputStream* is) { 323c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu // Note: we do not throw exception here for is. This is more of an assertion. 324c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu assert(is); 325c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu FontInputStream font_is(is); 3266a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu HeaderOffsetSortedSet records; 327c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu ReadHeader(&font_is, &records); 328c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu LoadTableData(&records, &font_is, &data_blocks_); 329c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu BuildAllTableBuilders(&data_blocks_, &table_builders_); 330c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu font_is.Close(); 331c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu} 332c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu 3336a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuvoid Font::Builder::LoadFont(WritableFontData* wfd, 334c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t offset_to_offset_table) { 335c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu // Note: we do not throw exception here for is. This is more of an assertion. 3366a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu assert(wfd); 3376a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu HeaderOffsetSortedSet records; 3386a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu ReadHeader(wfd, offset_to_offset_table, &records); 3396a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu LoadTableData(&records, wfd, &data_blocks_); 340c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu BuildAllTableBuilders(&data_blocks_, &table_builders_); 34195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 34295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 343c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuint32_t Font::Builder::SfntWrapperSize() { 34495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu return Offset::kSfntHeaderSize + 34595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu (Offset::kTableRecordSize * table_builders_.size()); 34695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 34795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 348c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::BuildAllTableBuilders(DataBlockMap* table_data, 34995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TableBuilderMap* builder_map) { 35095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu for (DataBlockMap::iterator record = table_data->begin(), 35195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu record_end = table_data->end(); 35295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu record != record_end; ++record) { 35395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TableBuilderPtr builder; 354c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu builder.Attach(GetTableBuilder(record->first.p_, record->second.p_)); 35595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu builder_map->insert(TableBuilderEntry(record->first->tag(), builder)); 35695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 357c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu InterRelateBuilders(&table_builders_); 35895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 35995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 3606a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuCALLER_ATTACH 36128258feb374913d40c347932937500210ba23d7carthurhsuTable::Builder* Font::Builder::GetTableBuilder(Header* header, 3626a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu WritableFontData* data) { 3636a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu return Table::Builder::GetBuilder(header, data); 36495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 36595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 3666a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuvoid Font::Builder::BuildTablesFromBuilders(Font* font, 3676a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu TableBuilderMap* builder_map, 36895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TableMap* table_map) { 3696a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu UNREFERENCED_PARAMETER(font); 370c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu InterRelateBuilders(builder_map); 37195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 37295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu // Now build all the tables. 37395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu for (TableBuilderMap::iterator builder = builder_map->begin(), 37495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu builder_end = builder_map->end(); 37528258feb374913d40c347932937500210ba23d7carthurhsu builder != builder_end; ++builder) { 37695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu TablePtr table; 3772f57786796743446495a41f1a1f8688b13fa1a86arthurhsu if (builder->second && builder->second->ReadyToBuild()) { 378158cdcb9cf09418ba8b49f4be7be69e37aa8e9faarthurhsu table.Attach(down_cast<Table*>(builder->second->Build())); 37995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 38095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (table == NULL) { 3812ac95dcf52d76634fba3f8fa81c575424f01d992arthurhsu table_map->clear(); 3826a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu#if !defined (SFNTLY_NO_EXCEPTION) 3836a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu std::string builder_string = "Unable to build table - "; 3846a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu char* table_name = TagToString(builder->first); 3856a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu builder_string += table_name; 3866a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu delete[] table_name; 38795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu throw RuntimeException(builder_string.c_str()); 388fa606d4385cc0cc97f319dc25c97f46b2d44f1b9arthurhsu#endif 3896a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu return; 39095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 39195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu table_map->insert(TableMapEntry(table->header()->tag(), table)); 39295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 39395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 39495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 3953eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsustatic Table::Builder* GetBuilder(TableBuilderMap* builder_map, int32_t tag) { 3963eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu if (builder_map) { 3973eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu TableBuilderMap::iterator target = builder_map->find(tag); 3983eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu if (target != builder_map->end()) { 3993eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu return target->second.p_; 4003eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu } 4013eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu } 4023eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu 4033eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu return NULL; 4043eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu} 4053eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu 406c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) { 4073eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu Table::Builder* raw_head_builder = GetBuilder(builder_map, Tag::head); 4083eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu FontHeaderTableBuilderPtr header_table_builder; 4093eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu if (raw_head_builder != NULL) { 4103eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu header_table_builder = 4113eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu down_cast<FontHeaderTable::Builder*>(raw_head_builder); 4123eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu } 4133eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu 4143eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu Table::Builder* raw_hhea_builder = GetBuilder(builder_map, Tag::hhea); 4153eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu HorizontalHeaderTableBuilderPtr horizontal_header_builder; 4163eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu if (raw_head_builder != NULL) { 4173eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu horizontal_header_builder = 4183eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu down_cast<HorizontalHeaderTable::Builder*>(raw_hhea_builder); 4193eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu } 4203eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu 4213eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu Table::Builder* raw_maxp_builder = GetBuilder(builder_map, Tag::maxp); 4223eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu MaximumProfileTableBuilderPtr max_profile_builder; 4233eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu if (raw_maxp_builder != NULL) { 4243eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu max_profile_builder = 4253eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu down_cast<MaximumProfileTable::Builder*>(raw_maxp_builder); 4263eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu } 4273eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu 4283eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu Table::Builder* raw_loca_builder = GetBuilder(builder_map, Tag::loca); 4293eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu LocaTableBuilderPtr loca_table_builder; 4303eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu if (raw_loca_builder != NULL) { 4313eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder); 4323eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu } 4333eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu 4343eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu Table::Builder* raw_hmtx_builder = GetBuilder(builder_map, Tag::hmtx); 4353eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu HorizontalMetricsTableBuilderPtr horizontal_metrics_builder; 4363eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu if (raw_hmtx_builder != NULL) { 4373eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu horizontal_metrics_builder = 4383eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu down_cast<HorizontalMetricsTable::Builder*>(raw_hmtx_builder); 4393eca5f26ef52cfef7d814f35fd52deb4c097531aarthurhsu } 44095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 4419e5bf57583793d6db93bb01fd982760ad110a50farthurhsu#if defined (SFNTLY_EXPERIMENTAL) 4429e5bf57583793d6db93bb01fd982760ad110a50farthurhsu Table::Builder* raw_hdmx_builder = GetBuilder(builder_map, Tag::hdmx); 4439e5bf57583793d6db93bb01fd982760ad110a50farthurhsu HorizontalDeviceMetricsTableBuilderPtr hdmx_table_builder; 4449e5bf57583793d6db93bb01fd982760ad110a50farthurhsu if (raw_hdmx_builder != NULL) { 4459e5bf57583793d6db93bb01fd982760ad110a50farthurhsu hdmx_table_builder = 4469e5bf57583793d6db93bb01fd982760ad110a50farthurhsu down_cast<HorizontalDeviceMetricsTable::Builder*>(raw_hdmx_builder); 4479e5bf57583793d6db93bb01fd982760ad110a50farthurhsu } 4489e5bf57583793d6db93bb01fd982760ad110a50farthurhsu#endif 4499e5bf57583793d6db93bb01fd982760ad110a50farthurhsu 45095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu // set the inter table data required to build certain tables 45195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (horizontal_metrics_builder != NULL) { 45295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (max_profile_builder != NULL) { 453c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu horizontal_metrics_builder->SetNumGlyphs( 454c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu max_profile_builder->NumGlyphs()); 45595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 45695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (horizontal_header_builder != NULL) { 457c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu horizontal_metrics_builder->SetNumberOfHMetrics( 458c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu horizontal_header_builder->NumberOfHMetrics()); 45995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 46095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 46195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 46295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (loca_table_builder != NULL) { 46395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (max_profile_builder != NULL) { 464c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu loca_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs()); 46595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 46695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu if (header_table_builder != NULL) { 4676a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu loca_table_builder->set_format_version( 468c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu header_table_builder->IndexToLocFormat()); 46995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 47095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 4719e5bf57583793d6db93bb01fd982760ad110a50farthurhsu 4729e5bf57583793d6db93bb01fd982760ad110a50farthurhsu#if defined (SFNTLY_EXPERIMENTAL) 4739e5bf57583793d6db93bb01fd982760ad110a50farthurhsu // Note: In C++, hdmx_table_builder can be NULL in a subsetter. 4749e5bf57583793d6db93bb01fd982760ad110a50farthurhsu if (max_profile_builder != NULL && hdmx_table_builder != NULL) { 4759e5bf57583793d6db93bb01fd982760ad110a50farthurhsu hdmx_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs()); 4769e5bf57583793d6db93bb01fd982760ad110a50farthurhsu } 4779e5bf57583793d6db93bb01fd982760ad110a50farthurhsu#endif 47895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 47995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 480c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::ReadHeader(FontInputStream* is, 4816a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu HeaderOffsetSortedSet* records) { 48295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu assert(records); 483c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu sfnt_version_ = is->ReadFixed(); 484c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu num_tables_ = is->ReadUShort(); 485c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu search_range_ = is->ReadUShort(); 486c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu entry_selector_ = is->ReadUShort(); 487c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu range_shift_ = is->ReadUShort(); 48895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 48995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu for (int32_t table_number = 0; table_number < num_tables_; ++table_number) { 49095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu // Need to use temporary vars here. C++ evaluates function parameters from 49195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu // right to left and thus breaks the order of input stream. 492c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t tag = is->ReadULongAsInt(); 493c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int64_t checksum = is->ReadULong(); 494c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t offset = is->ReadULongAsInt(); 495c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t length = is->ReadULongAsInt(); 49628258feb374913d40c347932937500210ba23d7carthurhsu HeaderPtr table = new Header(tag, checksum, offset, length); 49795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu records->insert(table); 49895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 49995efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 50095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 501c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsuvoid Font::Builder::ReadHeader(ReadableFontData* fd, 502c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t offset, 5036a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu HeaderOffsetSortedSet* records) { 504c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu assert(records); 505c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu sfnt_version_ = fd->ReadFixed(offset + Offset::kSfntVersion); 506c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu num_tables_ = fd->ReadUShort(offset + Offset::kNumTables); 507c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu search_range_ = fd->ReadUShort(offset + Offset::kSearchRange); 508c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu entry_selector_ = fd->ReadUShort(offset + Offset::kEntrySelector); 509c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu range_shift_ = fd->ReadUShort(offset + Offset::kRangeShift); 510c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu 511c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t table_offset = offset + Offset::kTableRecordBegin; 512c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu for (int32_t table_number = 0; 513c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu table_number < num_tables_; 514c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu table_number++, table_offset += Offset::kTableRecordSize) { 515c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t tag = fd->ReadULongAsInt(table_offset + Offset::kTableTag); 516c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int64_t checksum = fd->ReadULong(table_offset + Offset::kTableCheckSum); 517c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t offset = fd->ReadULongAsInt(table_offset + Offset::kTableOffset); 518c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu int32_t length = fd->ReadULongAsInt(table_offset + Offset::kTableLength); 51928258feb374913d40c347932937500210ba23d7carthurhsu HeaderPtr table = new Header(tag, checksum, offset, length); 520c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu records->insert(table); 521c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu } 522c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu} 523c143ecb4bbc4f3ccca5145dc2b17cc20ca738efearthurhsu 5246a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuvoid Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers, 52595efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu FontInputStream* is, 52695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu DataBlockMap* table_data) { 52795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu assert(table_data); 528813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang for (HeaderOffsetSortedSet::iterator it = headers->begin(), 5296a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu table_end = headers->end(); 530813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang it != table_end; 531813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang ++it) { 532813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang const Ptr<Header> header = *it; 533813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang is->Skip(header->offset() - is->position()); 534813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang if (header->length() > kMaxTableSize) 535813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang continue; 536813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang 537813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang FontInputStream table_is(is, header->length()); 53887114756046ef50158ad5bbf357bf40e05ebdd94arthurhsu WritableFontDataPtr data; 539813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang data.Attach(WritableFontData::CreateWritableFontData(header->length())); 540813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang data->CopyFrom(&table_is, header->length()); 541813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang table_data->insert(DataBlockEntry(header, data)); 54295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 54395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 54495efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 5456a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsuvoid Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers, 54695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu WritableFontData* fd, 54795efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu DataBlockMap* table_data) { 548813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang for (HeaderOffsetSortedSet::iterator it = headers->begin(), 5496a2a8e7db878d1115d600c3be02e2700d8b372bcarthurhsu table_end = headers->end(); 550813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang it != table_end; 551813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang ++it) { 552813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang const Ptr<Header> header = *it; 553813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang if (header->length() > kMaxTableSize) 554813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang continue; 555813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang 55695efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu FontDataPtr sliced_data; 557813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang sliced_data.Attach(fd->Slice(header->offset(), header->length())); 55895efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu WritableFontDataPtr data = down_cast<WritableFontData*>(sliced_data.p_); 559813efeb18bf6205354b01a525352ebdb10eebe06Lei Zhang table_data->insert(DataBlockEntry(header, data)); 56095efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu } 56195efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} 56295efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu 56395efcd4ba41e367b466b7206a942605bbbbb2c9arthurhsu} // namespace sfntly 564