1464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/* 2464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Copyright 2011 Google Inc. All Rights Reserved. 3464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * 4464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Licensed under the Apache License, Version 2.0 (the "License"); 5464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * you may not use this file except in compliance with the License. 6464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * You may obtain a copy of the License at 7464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * 8464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * http://www.apache.org/licenses/LICENSE-2.0 9464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * 10464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Unless required by applicable law or agreed to in writing, software 11464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * distributed under the License is distributed on an "AS IS" BASIS, 12464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * See the License for the specific language governing permissions and 14464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * limitations under the License. 15464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com */ 16464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1779fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com// type.h needs to be included first because of building issues on Windows 1879fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com// Type aliases we delcare are defined in other headers and make the build 1979fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com// fail otherwise. 20ba91573e890c0871c6949e480a365bc85d408e77dfilimon@google.com#include "sfntly/port/type.h" 2179fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com#include "sfntly/table/core/cmap_table.h" 22464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 23bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#include <stdio.h> 24bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#include <stdlib.h> 25bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 26bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#include <utility> 276b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com 28464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include "sfntly/font.h" 29bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#include "sfntly/math/font_math.h" 30464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include "sfntly/port/endian.h" 31bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#include "sfntly/port/exception_type.h" 32bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#include "sfntly/table/core/name_table.h" 33464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 34464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comnamespace sfntly { 35464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 36464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comconst int32_t CMapTable::NOTDEF = 0; 37464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 38bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapId CMapTable::WINDOWS_BMP = { 39bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com PlatformId::kWindows, 40bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com WindowsEncodingId::kUnicodeUCS2 41bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com}; 42bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapId CMapTable::WINDOWS_UCS4 = { 43bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com PlatformId::kWindows, 44bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com WindowsEncodingId::kUnicodeUCS4 45bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com}; 46bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapId CMapTable::MAC_ROMAN = { 47bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com PlatformId::kWindows, 48bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com MacintoshEncodingId::kRoman 49bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com}; 50bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 51464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/****************************************************************************** 52464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * CMapTable class 53464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/ 54bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapTable(Header* header, ReadableFontData* data) 55bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com : SubTableContainerTable(header, data) { 56bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 57bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 58464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comCMapTable::~CMapTable() {} 59464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 60bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t index) { 61bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (index < 0 || index > NumCMaps()) { 62bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#ifndef SFNTLY_NO_EXCEPTION 63bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com throw IndexOutOfBoundException("Requested CMap index is out of bounds."); 64bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#else 65bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return NULL; 66bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 67bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 68bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com int32_t platform_id = PlatformId(index); 69bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com int32_t encoding_id = EncodingId(index); 70bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapId cmap_id = NewCMapId(platform_id, encoding_id); 71bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com int32_t offset_ = Offset(index); 72bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com Ptr<FontDataTable::Builder> cmap_builder = 73bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com (CMap::Builder::GetBuilder(data_, offset_, cmap_id)); 74bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (!cmap_builder) { 75bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#ifndef SFNTLY_NO_EXCEPTION 76bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com throw NoSuchElementException("Cannot find builder for requested CMap."); 77bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#else 78bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return NULL; 79bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 80bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 8179fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com return down_cast<CMapTable::CMap*>(cmap_builder->Build()); 82bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 83bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 84bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t platform_id, 85bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com const int32_t encoding_id) { 86bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return GetCMap(NewCMapId(platform_id, encoding_id)); 87bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 88bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 89bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCALLER_ATTACH CMapTable::CMap* 90bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::GetCMap(const CMapTable::CMapId cmap_id) { 91abb68accf47583a130eba5578baa89b4257e5679dfilimon@google.com CMapIdFilter id_filter(cmap_id); 92abb68accf47583a130eba5578baa89b4257e5679dfilimon@google.com CMapIterator cmap_iterator(this, &id_filter); 93bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com // There can only be one cmap with a particular CMapId 94bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (cmap_iterator.HasNext()) { 95bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com Ptr<CMapTable::CMap> cmap; 96bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com cmap.Attach(cmap_iterator.Next()); 97bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return cmap.Detach(); 98bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 99bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#ifndef SFNTLY_NO_EXCEPTION 100bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com throw NoSuchElementException(); 101bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#else 102bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return NULL; 103bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 104bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 105bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 106246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::Version() { 107246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadUShort(Offset::kVersion); 108464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 109464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 110246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::NumCMaps() { 111246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadUShort(Offset::kNumTables); 112464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 113464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 114246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::CMapId CMapTable::GetCMapId(int32_t index) { 115bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return NewCMapId(PlatformId(index), EncodingId(index)); 116464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 117464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 118246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::PlatformId(int32_t index) { 119246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadUShort(Offset::kEncodingRecordPlatformId + 120246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com OffsetForEncodingRecord(index)); 121464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 122464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 123246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::EncodingId(int32_t index) { 124246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadUShort(Offset::kEncodingRecordEncodingId + 125246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com OffsetForEncodingRecord(index)); 126464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 127464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 128246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::Offset(int32_t index) { 129246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadULongAsInt(Offset::kEncodingRecordOffset + 130246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com OffsetForEncodingRecord(index)); 131464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 132464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 133246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::OffsetForEncodingRecord(int32_t index) { 134246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return Offset::kEncodingRecordStart + index * Offset::kEncodingRecordSize; 135464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 136464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 137bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapId CMapTable::NewCMapId(int32_t platform_id, 138bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com int32_t encoding_id) { 139bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapId result; 140bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com result.platform_id = platform_id; 141bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com result.encoding_id = encoding_id; 142bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return result; 143464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 144464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 145bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapId CMapTable::NewCMapId(const CMapId& obj) { 146bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapId result; 147bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com result.platform_id = obj.platform_id; 148bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com result.encoding_id = obj.encoding_id; 149bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return result; 150464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 151464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 152bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com/****************************************************************************** 153bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com * CMapTable::CMapIterator class 154bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com ******************************************************************************/ 155bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapIterator::CMapIterator(CMapTable* table, 156bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com const CMapFilter* filter) 157bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com : table_index_(0), filter_(filter), table_(table) { 158464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 159464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 160bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.combool CMapTable::CMapIterator::HasNext() { 161bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (!filter_) { 162bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (table_index_ < table_->NumCMaps()) { 163bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return true; 164bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 165bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return false; 166bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 167bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 168bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com for (; table_index_ < table_->NumCMaps(); ++table_index_) { 169bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (filter_->accept(table_->GetCMapId(table_index_))) { 170bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return true; 171bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 172bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 173bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return false; 174464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 175464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 176bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCALLER_ATTACH CMapTable::CMap* CMapTable::CMapIterator::Next() { 177bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (!HasNext()) { 178bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#ifndef SFNTLY_NO_EXCEPTION 179bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com throw NoSuchElementException(); 180bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#else 181bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return NULL; 182bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 183bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 184bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapPtr next_cmap; 185bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com next_cmap.Attach(table_->GetCMap(table_index_++)); 186bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (next_cmap == NULL) { 187bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#ifndef SFNTLY_NO_EXCEPTION 188bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com throw NoSuchElementException("Error during the creation of the CMap"); 189bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#else 190bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return NULL; 191bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 192bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 193bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return next_cmap.Detach(); 194464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 195464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 196bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com/****************************************************************************** 197bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com * CMapTable::CMapId class 198bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com ******************************************************************************/ 199464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 200464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/****************************************************************************** 201464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * CMapTable::CMapIdComparator class 202464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/ 203464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 204464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.combool CMapTable::CMapIdComparator::operator()(const CMapId& lhs, 205bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com const CMapId& rhs) const { 206bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return ((lhs.platform_id << 8 | lhs.encoding_id) > 207bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com (rhs.platform_id << 8 | rhs.encoding_id)); 208bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 209bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 210bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com/****************************************************************************** 211bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com * CMapTable::CMapIdFilter class 212bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com ******************************************************************************/ 213bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id) 214bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com : wanted_id_(wanted_id), 215bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com comparator_(NULL) { 216bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 217bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 218bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id, 219bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com const CMapIdComparator* comparator) 220bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com : wanted_id_(wanted_id), 221bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com comparator_(comparator) { 222bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 223bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 224bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.combool CMapTable::CMapIdFilter::accept(const CMapId& cmap_id) const { 225bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (!comparator_) 226bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return wanted_id_ == cmap_id; 227bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return (*comparator_)(wanted_id_, cmap_id); 228464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 229464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 230464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/****************************************************************************** 231464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * CMapTable::CMap class 232464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/ 233464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comCMapTable::CMap::CMap(ReadableFontData* data, int32_t format, 234464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com const CMapId& cmap_id) 235464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com : SubTable(data), format_(format), cmap_id_(cmap_id) { 236464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 237464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 238246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::CMap::~CMap() { 239246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 240464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 241464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/****************************************************************************** 242464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * CMapTable::CMap::Builder class 243464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/ 244246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::CMap::Builder::~Builder() { 245246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 246246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 247246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH CMapTable::CMap::Builder* 248bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapTable::CMap::Builder::GetBuilder(ReadableFontData* data, int32_t offset, 249b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com const CMapId& cmap_id) { 250246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com // NOT IMPLEMENTED: Java enum value validation 251246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t format = data->ReadUShort(offset); 252246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com CMapBuilderPtr builder; 253246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com switch (format) { 254246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com case CMapFormat::kFormat0: 255bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com builder.Attach(CMapFormat0::Builder::NewInstance(data, offset, cmap_id)); 256246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com break; 257246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com case CMapFormat::kFormat2: 258bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#if defined (SFNTLY_DEBUG_CMAP) 259bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com fprintf(stderr, "Requesting Format2 builder, but it's unsupported; " 260bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com "returning NULL\n"); 261bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 262bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com break; 263bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com case CMapFormat::kFormat4: 264a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com builder.Attach(CMapFormat4::Builder::NewInstance(data, offset, cmap_id)); 265246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com break; 266246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com default: 267bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#ifdef SFNTLY_DEBUG_CMAP 268bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com fprintf(stderr, "Unknown builder format requested\n"); 269bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 270bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com break; 271bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 272bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return builder.Detach(); 273bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 274bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 275bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCALLER_ATTACH CMapTable::CMap::Builder* 276bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMap::Builder::GetBuilder(int32_t format, const CMapId& cmap_id) { 277bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com Ptr<CMapTable::CMap::Builder> builder; 278bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com switch (format) { 279bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com case CMapFormat::kFormat0: 280bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com builder.Attach(CMapFormat0::Builder::NewInstance(cmap_id)); 281bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com break; 282bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com case CMapFormat::kFormat2: 283bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#if defined (SFNTLY_DEBUG_CMAP) 284bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com fprintf(stderr, "Requesting Format2 builder, but it's unsupported; " 285bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com "returning NULL\n"); 286bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 287bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com break; 288bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com case CMapFormat::kFormat4: 289a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com builder.Attach(CMapFormat4::Builder::NewInstance(cmap_id)); 290bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com break; 291bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com default: 292bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#ifdef SFNTLY_DEBUG_CMAP 293bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com fprintf(stderr, "Unknown builder format requested\n"); 294bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 295246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com break; 296246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com } 297246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return builder.Detach(); 298246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 299246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 300b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comCMapTable::CMap::Builder::Builder(ReadableFontData* data, 301b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com int32_t format, 3026b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com const CMapId& cmap_id) 303b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com : SubTable::Builder(data), 304246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com format_(format), 305bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com cmap_id_(cmap_id), 306bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com language_(0) { 307464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 308464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 309b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comCMapTable::CMap::Builder::Builder(WritableFontData* data, 310b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com int32_t format, 3116b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com const CMapId& cmap_id) 312b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com : SubTable::Builder(data), 313246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com format_(format), 314bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com cmap_id_(cmap_id), 315bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com language_(0) { 316464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 317464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 318246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMap::Builder::SubSerialize(WritableFontData* new_data) { 319246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return InternalReadData()->CopyTo(new_data); 320464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 321464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 322246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.combool CMapTable::CMap::Builder::SubReadyToSerialize() { 323464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return true; 324464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 325464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 326246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMap::Builder::SubDataSizeToSerialize() { 327bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com ReadableFontDataPtr read_data = InternalReadData(); 328bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (!read_data) 329bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return 0; 330bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return read_data->Length(); 331464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 332464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 333246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid CMapTable::CMap::Builder::SubDataSet() { 334464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com // NOP 335464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 336464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 337464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/****************************************************************************** 338246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com * CMapTable::CMapFormat0 339464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/ 340246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::CMapFormat0::~CMapFormat0() { 341464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 342464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 343246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat0::Language() { 344246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return 0; 345246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 346464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 347246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat0::GlyphId(int32_t character) { 348464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com if (character < 0 || character > 255) { 349464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return CMapTable::NOTDEF; 350464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com } 351bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return data_->ReadUByte(character + Offset::kFormat0GlyphIdArray); 352464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 353464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 354246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::CMapFormat0::CMapFormat0(ReadableFontData* data, 355246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com const CMapId& cmap_id) 356246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com : CMap(data, CMapFormat::kFormat0, cmap_id) { 357464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 358464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 35979fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.comCMapTable::CMap::CharacterIterator* CMapTable::CMapFormat0::Iterator() { 36079fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com return new CMapTable::CMapFormat0::CharacterIterator(0, 0xff); 361bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 362bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 363bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 364bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com/****************************************************************************** 365bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com * CMapTable::CMapFormat0::CharacterIterator 366bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com ******************************************************************************/ 367bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapFormat0::CharacterIterator::CharacterIterator(int32_t start, 368bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com int32_t end) 369bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com : character_(start), 370bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com max_character_(end) { 371bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 372bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 373bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapFormat0::CharacterIterator::~CharacterIterator() {} 374bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 375bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.combool CMapTable::CMapFormat0::CharacterIterator::HasNext() { 376bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return character_ < max_character_; 377bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 378bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 379bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comint32_t CMapTable::CMapFormat0::CharacterIterator::Next() { 380bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (HasNext()) 381bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return character_++; 382bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#ifndef SFNTLY_NO_EXCEPTION 383bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com throw NoSuchElementException("No more characters to iterate."); 384bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 385bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return -1; 386bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 387bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 388246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com/****************************************************************************** 389246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com * CMapTable::CMapFormat0::Builder 390246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com ******************************************************************************/ 391bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com// static 392bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCALLER_ATTACH CMapTable::CMapFormat0::Builder* 393bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapFormat0::Builder::NewInstance(WritableFontData* data, 394bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com int32_t offset, 395bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com const CMapId& cmap_id) { 396bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com WritableFontDataPtr wdata; 397bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (data) { 398bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com wdata.Attach(down_cast<WritableFontData*>( 399bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com data->Slice(offset, 400bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com data->ReadUShort(offset + Offset::kFormat0Length)))); 401bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 402bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return new Builder(wdata, CMapFormat::kFormat0, cmap_id); 403bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 404bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 405bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com// static 406bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCALLER_ATTACH CMapTable::CMapFormat0::Builder* 407bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapFormat0::Builder::NewInstance(ReadableFontData* data, 408bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com int32_t offset, 409bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com const CMapId& cmap_id) { 410bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com ReadableFontDataPtr rdata; 411bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (data) { 412bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com rdata.Attach(down_cast<ReadableFontData*>( 413bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com data->Slice(offset, 414bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com data->ReadUShort(offset + Offset::kFormat0Length)))); 415bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 416bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return new Builder(rdata, CMapFormat::kFormat0, cmap_id); 417464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 418464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 419bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com// static 420bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCALLER_ATTACH CMapTable::CMapFormat0::Builder* 421bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapFormat0::Builder::NewInstance(const CMapId& cmap_id) { 422bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return new Builder(cmap_id); 423bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 424bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 425bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com// Always call NewInstance instead of the constructor for creating a new builder 426bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com// object! This refactoring avoids memory leaks when slicing the font data. 427bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapFormat0::Builder::Builder(WritableFontData* data, int32_t offset, 428b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com const CMapId& cmap_id) 429bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) { 430bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com UNREFERENCED_PARAMETER(offset); 431bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 432bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 433bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapFormat0::Builder::Builder( 434bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com ReadableFontData* data, 435bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com int32_t offset, 436bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com const CMapId& cmap_id) 437bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) { 438bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com UNREFERENCED_PARAMETER(offset); 439bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 440bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 44179fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.comCMapTable::CMapFormat0::Builder::Builder(const CMapId& cmap_id) 442bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL), 443bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapFormat::kFormat0, 444bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com cmap_id) { 445464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 446464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 447246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::CMapFormat0::Builder::~Builder() { 448246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 449464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 450246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH FontDataTable* 451246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com CMapTable::CMapFormat0::Builder::SubBuildTable(ReadableFontData* data) { 452246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com FontDataTablePtr table = new CMapFormat0(data, cmap_id()); 453246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return table.Detach(); 454464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 455464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 456464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/****************************************************************************** 457246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com * CMapTable::CMapFormat2 458464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/ 459246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::CMapFormat2::~CMapFormat2() { 460464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 461464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 462246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat2::Language() { 463246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return 0; 464464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 465464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 466246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat2::GlyphId(int32_t character) { 467464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com if (character > 0xffff) { 468464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return CMapTable::NOTDEF; 469464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com } 470464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 471246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com uint32_t c = ToBE32(character); 472464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com byte_t high_byte = (c >> 8) & 0xff; 473464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com byte_t low_byte = c & 0xff; 474246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t offset = SubHeaderOffset(high_byte); 475464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 476464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com if (offset == 0) { 477464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com low_byte = high_byte; 478464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com high_byte = 0; 479464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com } 480464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 481246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t first_code = FirstCode(high_byte); 482246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t entry_count = EntryCount(high_byte); 483464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 484464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com if (low_byte < first_code || low_byte >= first_code + entry_count) { 485464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return CMapTable::NOTDEF; 486464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com } 487464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 488246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t id_range_offset = IdRangeOffset(high_byte); 489464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 490464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com // position of idRangeOffset + value of idRangeOffset + index for low byte 491464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com // = firstcode 492464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com int32_t p_location = (offset + Offset::kFormat2SubHeader_idRangeOffset) + 4936b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com id_range_offset + 4946b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com (low_byte - first_code) * DataSize::kUSHORT; 495246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int p = data_->ReadUShort(p_location); 496464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com if (p == 0) { 497464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return CMapTable::NOTDEF; 498464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com } 499464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 500464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com if (offset == 0) { 501464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return p; 502464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com } 503246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int id_delta = IdDelta(high_byte); 504464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return (p + id_delta) % 65536; 505464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 506464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 507246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat2::BytesConsumed(int32_t character) { 508246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com uint32_t c = ToBE32(character); 509246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t high_byte = (c >> 8) & 0xff; 510246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t offset = SubHeaderOffset(high_byte); 511246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return (offset == 0) ? 1 : 2; 512246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 513246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 514246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::CMapFormat2::CMapFormat2(ReadableFontData* data, 515246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com const CMapId& cmap_id) 516246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com : CMap(data, CMapFormat::kFormat2, cmap_id) { 517246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 518246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 519246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat2::SubHeaderOffset(int32_t sub_header_index) { 520246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadUShort(Offset::kFormat2SubHeaderKeys + 521246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com sub_header_index * DataSize::kUSHORT); 522246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 523246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 524246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat2::FirstCode(int32_t sub_header_index) { 525246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t sub_header_offset = SubHeaderOffset(sub_header_index); 526246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadUShort(sub_header_offset + 527246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com Offset::kFormat2SubHeaderKeys + 528246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com Offset::kFormat2SubHeader_firstCode); 529246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 530246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 531246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat2::EntryCount(int32_t sub_header_index) { 532246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t sub_header_offset = SubHeaderOffset(sub_header_index); 533246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadUShort(sub_header_offset + 534246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com Offset::kFormat2SubHeaderKeys + 535246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com Offset::kFormat2SubHeader_entryCount); 536246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 537246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 538246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat2::IdRangeOffset(int32_t sub_header_index) { 539246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t sub_header_offset = SubHeaderOffset(sub_header_index); 540246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadUShort(sub_header_offset + 541246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com Offset::kFormat2SubHeaderKeys + 542246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com Offset::kFormat2SubHeader_idRangeOffset); 543246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 544246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 545246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::CMapFormat2::IdDelta(int32_t sub_header_index) { 546246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t sub_header_offset = SubHeaderOffset(sub_header_index); 547246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data_->ReadUShort(sub_header_offset + 548246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com Offset::kFormat2SubHeaderKeys + 549246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com Offset::kFormat2SubHeader_idDelta); 550464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 551464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 55279fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.comCMapTable::CMap::CharacterIterator* CMapTable::CMapFormat2::Iterator() { 55379fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com // UNIMPLEMENTED 55479fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com return NULL; 55579fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com} 55679fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com 557246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com/****************************************************************************** 558246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com * CMapTable::CMapFormat2::Builder 559246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com ******************************************************************************/ 560b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comCMapTable::CMapFormat2::Builder::Builder(WritableFontData* data, 561b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com int32_t offset, 562b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com const CMapId& cmap_id) 563b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com : CMapTable::CMap::Builder(data ? down_cast<WritableFontData*>( 564246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com data->Slice(offset, data->ReadUShort( 5656b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com offset + Offset::kFormat0Length))) 5666b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com : reinterpret_cast<WritableFontData*>(NULL), 567464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com CMapFormat::kFormat2, cmap_id) { 568464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix. 569464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 570464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 571b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comCMapTable::CMapFormat2::Builder::Builder(ReadableFontData* data, 572b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com int32_t offset, 573b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com const CMapId& cmap_id) 574b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com : CMapTable::CMap::Builder(data ? down_cast<ReadableFontData*>( 575246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com data->Slice(offset, data->ReadUShort( 5766b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com offset + Offset::kFormat0Length))) 5776b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com : reinterpret_cast<ReadableFontData*>(NULL), 578464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com CMapFormat::kFormat2, cmap_id) { 579464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix. 580464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 581464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 582246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::CMapFormat2::Builder::~Builder() { 583246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 584464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 585246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH FontDataTable* 586246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com CMapTable::CMapFormat2::Builder::SubBuildTable(ReadableFontData* data) { 587246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com FontDataTablePtr table = new CMapFormat2(data, cmap_id()); 588246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return table.Detach(); 589464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 590464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 591464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/****************************************************************************** 592a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * CMapTable::CMapFormat4 593a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com ******************************************************************************/ 594a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::CMapFormat4(ReadableFontData* data, 595a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com const CMapId& cmap_id) 5967bb24d45ed7d04c85f27ecdc3866153a8350ed44dfilimon@google.com : CMap(data, CMapFormat::kFormat4, cmap_id), 597a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com seg_count_(SegCount(data)), 598a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com start_code_offset_(StartCodeOffset(seg_count_)), 599a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com id_delta_offset_(IdDeltaOffset(seg_count_)), 600a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com glyph_id_array_offset_(GlyphIdArrayOffset(seg_count_)) { 601a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 602a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 603a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::~CMapFormat4() { 604a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 605a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 606a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::GlyphId(int32_t character) { 607a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t segment = data_->SearchUShort(StartCodeOffset(seg_count_), 608a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com DataSize::kUSHORT, 609a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com Offset::kFormat4EndCount, 610a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com DataSize::kUSHORT, 611a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com seg_count_, 612a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com character); 613a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (segment == -1) { 614a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return CMapTable::NOTDEF; 615a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 616a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t start_code = StartCode(segment); 617a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return RetrieveGlyphId(segment, start_code, character); 618a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 619a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 620a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::RetrieveGlyphId(int32_t segment, 621a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t start_code, 622a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t character) { 623a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (character < start_code) { 624a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return CMapTable::NOTDEF; 625a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 626a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t id_range_offset = IdRangeOffset(segment); 627a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (id_range_offset == 0) { 628a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return (character + IdDelta(segment)) % 65536; 629a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 630a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return data_->ReadUShort(id_range_offset + 631a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com IdRangeOffsetLocation(segment) + 632a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 2 * (character - start_code)); 633a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 634a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 635a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::seg_count() { 636a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return seg_count_; 637a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 638a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 639a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::Length() { 640a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return Length(data_); 641a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 642a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 643a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::StartCode(int32_t segment) { 644a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (!IsValidIndex(segment)) { 645a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return -1; 646a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 647a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return StartCode(data_.p_, seg_count_, segment); 648a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 649a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 650a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 651a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::Language(ReadableFontData* data) { 652a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t language = data->ReadUShort(Offset::kFormat4Language); 653a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return language; 654a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 655a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 656a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 657a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::Length(ReadableFontData* data) { 658a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t length = data->ReadUShort(Offset::kFormat4Length); 659a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return length; 660a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 661a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 662a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 663a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::SegCount(ReadableFontData* data) { 664a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t seg_count = data->ReadUShort(Offset::kFormat4SegCountX2) / 2; 665a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return seg_count; 666a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 667a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 668a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 669a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::StartCode(ReadableFontData* data, 670a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t seg_count, 671a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t index) { 672a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t start_code = data->ReadUShort(StartCodeOffset(seg_count) + 673a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index * DataSize::kUSHORT); 674a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return start_code; 675a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 676a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 677a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 678a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::StartCodeOffset(int32_t seg_count) { 679a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t start_code_offset = Offset::kFormat4EndCount + 680a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com (seg_count + 1) * DataSize::kUSHORT; 681a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return start_code_offset; 682a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 683a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 684a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 685a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::EndCode(ReadableFontData* data, 686a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t seg_count, 687a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t index) { 688ce2471a4cd4a9d39f3e761bfe6739fb454bf0dc3dfilimon@google.com UNREFERENCED_PARAMETER(seg_count); 689a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t end_code = data->ReadUShort(Offset::kFormat4EndCount + 690a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index * DataSize::kUSHORT); 691a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return end_code; 692a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 693a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 694a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 695a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::IdDelta(ReadableFontData* data, 696a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t seg_count, 697a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t index) { 698a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t id_delta = data->ReadUShort(IdDeltaOffset(seg_count) + 699a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index * DataSize::kUSHORT); 700a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return id_delta; 701a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 702a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 703a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 704a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::IdDeltaOffset(int32_t seg_count) { 705a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t id_delta_offset = 706a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT; 707a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return id_delta_offset; 708a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 709a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 710a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 711a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::IdRangeOffset(ReadableFontData* data, 712a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t seg_count, 713a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t index) { 714a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t id_range_offset = 715a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com data->ReadUShort(IdRangeOffsetOffset(seg_count) 716a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com + index * DataSize::kUSHORT); 717a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return id_range_offset; 718a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 719a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 720a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 721a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::IdRangeOffsetOffset(int32_t seg_count) { 722a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t id_range_offset_offset = 723a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT + 724a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com seg_count * DataSize::kSHORT; 725a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return id_range_offset_offset; 726a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 727a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 728a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 729a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::GlyphIdArrayOffset(int32_t seg_count) { 730a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t glyph_id_array_offset = 731a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com Offset::kFormat4EndCount + (3 * seg_count + 1) * DataSize::kUSHORT + 732a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com seg_count * DataSize::kSHORT; 733a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return glyph_id_array_offset; 734a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 735a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 736a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::EndCode(int32_t segment) { 737a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (IsValidIndex(segment)) { 738a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return EndCode(data_, seg_count_, segment); 739a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 740a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#if defined (SFNTLY_NO_EXCEPTION) 741a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return -1; 742a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#else 743a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com throw IllegalArgumentException(); 744a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#endif 745a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 746a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 747a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.combool CMapTable::CMapFormat4::IsValidIndex(int32_t segment) { 748a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (segment < 0 || segment >= seg_count_) { 749a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#if defined (SFNTLY_NO_EXCEPTION) 750a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return false; 751a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#else 752a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com throw IllegalArgumentException(); 753a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#endif 754a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 755a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return true; 756a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 757a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 758a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::IdDelta(int32_t segment) { 759a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (IsValidIndex(segment)) 760a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return IdDelta(data_, seg_count_, segment); 761a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return -1; 762a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 763a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 764a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::IdRangeOffset(int32_t segment) { 765a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (IsValidIndex(segment)) 766a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return data_->ReadUShort(IdRangeOffsetLocation(segment)); 767a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return -1; 768a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 769a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 770a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::IdRangeOffsetLocation(int32_t segment) { 771a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (IsValidIndex(segment)) 772a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return IdRangeOffsetOffset(seg_count_) + segment * DataSize::kUSHORT; 773a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return -1; 774a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 775a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 776a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::GlyphIdArray(int32_t index) { 777a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return data_->ReadUShort(glyph_id_array_offset_ + index * DataSize::kUSHORT); 778a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 779a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 780a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::Language() { 781a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return Language(data_); 782a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 783a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 784a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 785a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMap::CharacterIterator* CMapTable::CMapFormat4::Iterator() { 786a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return new CharacterIterator(this); 787a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 788a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 789a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com/****************************************************************************** 790a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * CMapTable::CMapFormat4::CharacterIterator class 791a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com ******************************************************************************/ 792a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::CharacterIterator::CharacterIterator( 793a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com CMapFormat4* parent) 794a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com : parent_(parent), 795a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segment_index_(0), 796a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com first_char_in_segment_(-1), 797a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com last_char_in_segment_(-1), 798a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com next_char_(-1), 799a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com next_char_set_(false) { 800a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 801a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 802a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.combool CMapTable::CMapFormat4::CharacterIterator::HasNext() { 803a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (next_char_set_) 804a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return true; 805a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com while (segment_index_ < parent_->seg_count_) { 806a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (first_char_in_segment_ < 0) { 807a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com first_char_in_segment_ = parent_->StartCode(segment_index_); 808a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com last_char_in_segment_ = parent_->EndCode(segment_index_); 809a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com next_char_ = first_char_in_segment_; 810a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com next_char_set_ = true; 811a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return true; 812a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 813a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (next_char_ < last_char_in_segment_) { 814a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com next_char_++; 815a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com next_char_set_ = true; 816a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return true; 817a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 818a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segment_index_++; 819a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com first_char_in_segment_ = -1; 820a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 821a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return false; 822a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 823a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 824a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::CharacterIterator::Next() { 825a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (!next_char_set_) { 826a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (!HasNext()) { 827a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#if defined (SFNTLY_NO_EXCEPTION) 828a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return -1; 829a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#else 830a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com throw NoSuchElementException("No more characters to iterate."); 831a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#endif 832a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 833a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 834a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com next_char_set_ = false; 835a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return next_char_; 836a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 837a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 838a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com/****************************************************************************** 839a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * CMapTable::CMapFormat4::Builder::Segment class 840a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com ******************************************************************************/ 841a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Segment::Segment() {} 842a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 843a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Segment::Segment(Segment* other) 844a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com : start_count_(other->start_count_), 845a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com end_count_(other->end_count_), 846a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com id_delta_(other->id_delta_), 847a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com id_range_offset_(other->id_range_offset_) { 848a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 849a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 850a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Segment::Segment(int32_t start_count, 851a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t end_count, 852a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t id_delta, 853a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t id_range_offset) 854a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com : start_count_(start_count), 855a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com end_count_(end_count), 856a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com id_delta_(id_delta), 857a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com id_range_offset_(id_range_offset) { 858a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 859a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 860a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Segment::~Segment() {} 861a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 862a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::Builder::Segment::start_count() { 863a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return start_count_; 864a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 865a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 866a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comvoid 867a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Segment::set_start_count(int32_t start_count) { 868a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com start_count_ = start_count; 869a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 870a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 871a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::Builder::Segment::end_count() { 872a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return end_count_; 873a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 874a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 875a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comvoid 876a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Segment::set_end_count(int32_t end_count) { 877a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com end_count_ = end_count; 878a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 879a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 880a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::Builder::Segment::id_delta() { 881a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return id_delta_; 882a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 883a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 884a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comvoid 885a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Segment::set_id_delta(int32_t id_delta) { 886a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com id_delta_ = id_delta; 887a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 888a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 889a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::Builder::Segment::id_range_offset() { 890a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return id_range_offset_; 891a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 892a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 893a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comvoid 894a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Segment:: 895a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comset_id_range_offset(int32_t id_range_offset) { 896a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com id_range_offset_ = id_range_offset; 897a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 898a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 899a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com// static 900a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCALLER_ATTACH SegmentList* 901a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Segment::DeepCopy(SegmentList* original) { 902a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com SegmentList* list = new SegmentList; 903a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com for (SegmentList::iterator it = original->begin(), 904a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com e = original->end(); it != e; ++it) { 905a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com list->push_back(*it); 906a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 907a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return list; 908a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 909a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 910a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com/****************************************************************************** 911a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * CMapTable::CMapFormat4::Builder class 912a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com ******************************************************************************/ 913a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCALLER_ATTACH CMapTable::CMapFormat4::Builder* 914a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::NewInstance(ReadableFontData* data, 915a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t offset, 916a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com const CMapId& cmap_id) { 917a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com ReadableFontDataPtr rdata; 918a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (data) { 919a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com rdata.Attach 920a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com (down_cast<ReadableFontData*> 921a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com (data->Slice(offset, 922a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com data->ReadUShort(offset + Offset::kFormat4Length)))); 923a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 924a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return new Builder(rdata, CMapFormat::kFormat4, cmap_id); 925a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 926a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 927a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCALLER_ATTACH CMapTable::CMapFormat4::Builder* 928a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::NewInstance(WritableFontData* data, 929a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t offset, 930a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com const CMapId& cmap_id) { 931a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com WritableFontDataPtr wdata; 932a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (data) { 933a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com wdata.Attach 934a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com (down_cast<WritableFontData*> 935a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com (data->Slice(offset, 936a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com data->ReadUShort(offset + Offset::kFormat4Length)))); 937a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 938a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return new Builder(wdata, CMapFormat::kFormat4, cmap_id); 939a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 940a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 941a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCALLER_ATTACH CMapTable::CMapFormat4::Builder* 942a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::NewInstance(const CMapId& cmap_id) { 943a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return new Builder(cmap_id); 944a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 945a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 946a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Builder(ReadableFontData* data, int32_t offset, 947a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com const CMapId& cmap_id) 948a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) { 949ce2471a4cd4a9d39f3e761bfe6739fb454bf0dc3dfilimon@google.com UNREFERENCED_PARAMETER(offset); 950a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 951a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 952a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Builder(WritableFontData* data, int32_t offset, 953a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com const CMapId& cmap_id) 954a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) { 955ce2471a4cd4a9d39f3e761bfe6739fb454bf0dc3dfilimon@google.com UNREFERENCED_PARAMETER(offset); 956a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 957a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 958a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Builder(SegmentList* segments, 959a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com IntegerList* glyph_id_array, 960a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com const CMapId& cmap_id) 961a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL), 962a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com CMapFormat::kFormat4, cmap_id), 963a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segments_(segments->begin(), segments->end()), 964a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com glyph_id_array_(glyph_id_array->begin(), glyph_id_array->end()) { 965a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com set_model_changed(); 966a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 967a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 968a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::Builder(const CMapId& cmap_id) 969a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL), 970a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com CMapFormat::kFormat4, cmap_id) { 971a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 972a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 973a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::~Builder() {} 974a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 975a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comvoid CMapTable::CMapFormat4::Builder::Initialize(ReadableFontData* data) { 976a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (data == NULL || data->Length() == 0) 977a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return; 978a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 979a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com // build segments 980a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t seg_count = CMapFormat4::SegCount(data); 981a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com for (int32_t index = 0; index < seg_count; ++index) { 982a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com Ptr<Segment> segment = new Segment; 983a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segment->set_start_count(CMapFormat4::StartCode(data, seg_count, index)); 984a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#if defined SFNTLY_DEBUG_CMAP 985a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com fprintf(stderr, "Segment %d; start %d\n", index, segment->start_count()); 986a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#endif 987a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segment->set_end_count(CMapFormat4::EndCode(data, seg_count, index)); 988a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segment->set_id_delta(CMapFormat4::IdDelta(data, seg_count, index)); 989a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segment->set_id_range_offset(CMapFormat4::IdRangeOffset(data, 990a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com seg_count, 991a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index)); 992a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segments_.push_back(segment); 993a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 994a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 995a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com // build glyph id array 996a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t glyph_id_array_offset = CMapFormat4::GlyphIdArrayOffset(seg_count); 997a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t glyph_id_array_length = 998a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com (CMapFormat4::Length(data) - glyph_id_array_offset) 999a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com / DataSize::kUSHORT; 1000a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com fprintf(stderr, "id array size %d\n", glyph_id_array_length); 1001a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com for (int32_t i = 0; i < glyph_id_array_length; i += DataSize::kUSHORT) { 1002a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com glyph_id_array_.push_back(data->ReadUShort(glyph_id_array_offset + i)); 1003a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1004a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1005a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1006a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comSegmentList* CMapTable::CMapFormat4::Builder::segments() { 1007a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (segments_.empty()) { 1008a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com Initialize(InternalReadData()); 1009a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com set_model_changed(); 1010a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1011a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return &segments_; 1012a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1013a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1014a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comvoid CMapTable::CMapFormat4::Builder::set_segments(SegmentList* segments) { 1015a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segments_.assign(segments->begin(), segments->end()); 1016a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com set_model_changed(); 1017a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1018a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1019a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comIntegerList* CMapTable::CMapFormat4::Builder::glyph_id_array() { 1020a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (glyph_id_array_.empty()) { 1021a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com Initialize(InternalReadData()); 1022a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com set_model_changed(); 1023a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1024a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return &glyph_id_array_; 1025a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1026a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1027a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comvoid CMapTable::CMapFormat4::Builder:: 1028a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comset_glyph_id_array(IntegerList* glyph_id_array) { 1029a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com glyph_id_array_.assign(glyph_id_array->begin(), glyph_id_array->end()); 1030a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com set_model_changed(); 1031a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1032a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1033a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCALLER_ATTACH FontDataTable* 1034a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::SubBuildTable(ReadableFontData* data) { 1035a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com FontDataTablePtr table = new CMapFormat4(data, cmap_id()); 1036a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return table.Detach(); 1037a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1038a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1039a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comvoid CMapTable::CMapFormat4::Builder::SubDataSet() { 1040a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com segments_.clear(); 1041a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com glyph_id_array_.clear(); 1042a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com set_model_changed(); 1043a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1044a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1045a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t CMapTable::CMapFormat4::Builder::SubDataSizeToSerialize() { 1046a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (!model_changed()) { 1047a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return CMap::Builder::SubDataSizeToSerialize(); 1048a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1049a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t size = Offset::kFormat4FixedSize + segments_.size() 1050a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * (3 * DataSize::kUSHORT + DataSize::kSHORT) 1051a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com + glyph_id_array_.size() * DataSize::kSHORT; 1052a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return size; 1053a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1054a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1055a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.combool CMapTable::CMapFormat4::Builder::SubReadyToSerialize() { 1056a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (!model_changed()) { 1057a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return CMap::Builder::SubReadyToSerialize(); 1058a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1059a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (!segments()->empty()) { 1060a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return true; 1061a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1062a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return false; 1063a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1064a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1065a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t 1066a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapTable::CMapFormat4::Builder::SubSerialize(WritableFontData* new_data) { 1067a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com if (!model_changed()) { 1068a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return CMap::Builder::SubSerialize(new_data); 1069a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1070a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t index = 0; 1071a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, CMapFormat::kFormat4); 1072a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += DataSize::kUSHORT; // length - write this at the end 1073a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, language()); 1074a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1075a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t seg_count = segments_.size(); 1076a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, seg_count * 2); 1077a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t log2_seg_count = FontMath::Log2(seg_count); 1078a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t search_range = 1 << (log2_seg_count + 1); 1079a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, search_range); 1080a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t entry_selector = log2_seg_count; 1081a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, entry_selector); 1082a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com int32_t range_shift = 2 * seg_count - search_range; 1083a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, range_shift); 1084a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1085a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com for (int32_t i = 0; i < seg_count; ++i) { 1086a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, segments_[i]->end_count()); 1087a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1088a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, 0); // reserved ushort 1089a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com for (int32_t i = 0; i < seg_count; ++i) { 1090a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#if defined SFNTLY_DEBUG_CMAP 1091a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com fprintf(stderr, "Segment %d; start %d\n", i, segments_[i]->start_count()); 1092a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#endif 1093a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, segments_[i]->start_count()); 1094a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1095a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com for (int32_t i = 0; i < seg_count; ++i) { 1096a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteShort(index, segments_[i]->id_delta()); 1097a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1098a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com for (int32_t i = 0; i < seg_count; ++i) { 1099a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, segments_[i]->id_range_offset()); 1100a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1101a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1102a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#if defined SFNTLY_DEBUG_CMAP 1103a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com fprintf(stderr, "Glyph id array size %lu\n", glyph_id_array_.size()); 1104a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#endif 1105a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com for (size_t i = 0; i < glyph_id_array_.size(); ++i) { 1106a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com index += new_data->WriteUShort(index, glyph_id_array_[i]); 1107a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com } 1108a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1109a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com new_data->WriteUShort(Offset::kFormat4Length, index); 1110a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com return index; 1111a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com} 1112a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com 1113a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com/****************************************************************************** 1114464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * CMapTable::Builder class 1115464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/ 1116b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comCMapTable::Builder::Builder(Header* header, WritableFontData* data) 1117a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com : SubTableContainerTable::Builder(header, data), version_(0) { 1118464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 1119464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1120b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comCMapTable::Builder::Builder(Header* header, ReadableFontData* data) 1121a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com : SubTableContainerTable::Builder(header, data), version_(0) { 1122464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 1123464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1124246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCMapTable::Builder::~Builder() { 1125246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com} 1126246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com 1127246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::Builder::SubSerialize(WritableFontData* new_data) { 1128246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t size = new_data->WriteUShort(CMapTable::Offset::kVersion, 11296b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com version_); 1130246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com size += new_data->WriteUShort(CMapTable::Offset::kNumTables, 1131bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com GetCMapBuilders()->size()); 11326b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com 11336b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com int32_t index_offset = size; 1134bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com size += GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize; 1135bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(), 1136bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com e = GetCMapBuilders()->end(); it != e; ++it) { 11376b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com CMapBuilderPtr b = it->second; 11386b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com // header entry 1139246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com index_offset += new_data->WriteUShort(index_offset, b->platform_id()); 1140246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com index_offset += new_data->WriteUShort(index_offset, b->encoding_id()); 1141246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com index_offset += new_data->WriteULong(index_offset, size); 11426b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com 11436b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com // cmap 11446b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com FontDataPtr slice; 1145246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com slice.Attach(new_data->Slice(size)); 1146246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com size += b->SubSerialize(down_cast<WritableFontData*>(slice.p_)); 11476b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com } 11486b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com return size; 1149464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 1150464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1151246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.combool CMapTable::Builder::SubReadyToSerialize() { 1152bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (GetCMapBuilders()->empty()) 11536b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com return false; 11546b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com 11556b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com // check each table 1156bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(), 1157bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com e = GetCMapBuilders()->end(); it != e; ++it) { 1158246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com if (!it->second->SubReadyToSerialize()) 11596b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com return false; 11606b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com } 11616b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com return true; 1162464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 1163464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1164246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::Builder::SubDataSizeToSerialize() { 1165bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (GetCMapBuilders()->empty()) 11666b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com return 0; 11676b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com 11686b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com bool variable = false; 11696b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com int32_t size = CMapTable::Offset::kEncodingRecordStart + 1170bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize; 11716b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com 11726b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com // calculate size of each table 1173bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(), 1174bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com e = GetCMapBuilders()->end(); it != e; ++it) { 1175246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com int32_t cmap_size = it->second->SubDataSizeToSerialize(); 11766b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com size += abs(cmap_size); 11776b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com variable |= cmap_size <= 0; 11786b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com } 11796b5ae74df6b2ff199c63923219c9a18bd9c4d931arthurhsu@google.com return variable ? -size : size; 1180464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 1181464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1182246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid CMapTable::Builder::SubDataSet() { 1183bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com GetCMapBuilders()->clear(); 1184bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com Table::Builder::set_model_changed(); 1185464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 1186464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1187246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH FontDataTable* 1188246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com CMapTable::Builder::SubBuildTable(ReadableFontData* data) { 1189464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com FontDataTablePtr table = new CMapTable(header(), data); 1190246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return table.Detach(); 1191464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 1192464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1193b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comCALLER_ATTACH CMapTable::Builder* 1194b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com CMapTable::Builder::CreateBuilder(Header* header, 1195b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com WritableFontData* data) { 1196b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com Ptr<CMapTable::Builder> builder; 1197b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com builder = new CMapTable::Builder(header, data); 1198b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com return builder.Detach(); 1199b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com} 1200b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com 1201bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com// static 1202b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comCALLER_ATTACH CMapTable::CMap::Builder* 1203b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com CMapTable::Builder::CMapBuilder(ReadableFontData* data, int32_t index) { 1204b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com if (index < 0 || index > NumCMaps(data)) { 1205b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com#if !defined (SFNTLY_NO_EXCEPTION) 1206b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com throw IndexOutOfBoundException( 1207b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com "CMap table is outside of the bounds of the known tables."); 1208b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com#endif 1209464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return NULL; 1210b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com } 1211464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1212b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com int32_t platform_id = data->ReadUShort(Offset::kEncodingRecordPlatformId + 1213b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com OffsetForEncodingRecord(index)); 1214b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com int32_t encoding_id = data->ReadUShort(Offset::kEncodingRecordEncodingId + 1215b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com OffsetForEncodingRecord(index)); 1216b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com int32_t offset = data->ReadULongAsInt(Offset::kEncodingRecordOffset + 1217b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com OffsetForEncodingRecord(index)); 1218bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return CMap::Builder::GetBuilder(data, offset, 1219bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com NewCMapId(platform_id, encoding_id)); 1220464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 1221464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1222bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com// static 1223246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t CMapTable::Builder::NumCMaps(ReadableFontData* data) { 1224464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com if (data == NULL) { 1225464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com return 0; 1226464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com } 1227246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com return data->ReadUShort(Offset::kNumTables); 1228464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} 1229464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com 1230bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comint32_t CMapTable::Builder::NumCMaps() { 1231bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return GetCMapBuilders()->size(); 1232bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 1233bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 1234bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comvoid CMapTable::Builder::Initialize(ReadableFontData* data) { 1235bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com int32_t num_cmaps = NumCMaps(data); 1236bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com for (int32_t i = 0; i < num_cmaps; ++i) { 123779fe62d80f2ab09a217c5948a9adbcd019f4455ddfilimon@google.com CMapTable::CMap::Builder* cmap_builder = CMapBuilder(data, i); 1238bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (!cmap_builder) 1239bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com continue; 1240bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com cmap_builders_[cmap_builder->cmap_id()] = cmap_builder; 1241bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 1242bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 1243bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 1244bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMap::Builder* CMapTable::Builder::NewCMapBuilder( 1245bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com const CMapId& cmap_id, 1246bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com ReadableFontData* data) { 1247bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com Ptr<WritableFontData> wfd; 1248bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com wfd.Attach(WritableFontData::CreateWritableFontData(data->Size())); 1249bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com data->CopyTo(wfd.p_); 1250bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapTable::CMapBuilderPtr builder; 1251bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com builder.Attach(CMap::Builder::GetBuilder(wfd.p_, 0, cmap_id)); 1252bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders(); 1253bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com cmap_builders->insert(std::make_pair(cmap_id, builder.p_)); 1254bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return builder.Detach(); 1255bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 1256bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 1257bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMap::Builder* 1258bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::Builder::NewCMapBuilder(int32_t format, const CMapId& cmap_id) { 1259bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com Ptr<CMapTable::CMap::Builder> cmap_builder; 1260bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com cmap_builder.Attach(CMap::Builder::GetBuilder(format, cmap_id)); 1261bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders(); 1262bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com cmap_builders->insert(std::make_pair(cmap_id, cmap_builder.p_)); 1263bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return cmap_builder.Detach(); 1264bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 1265bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 1266bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMap::Builder* 1267bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::Builder::CMapBuilder(const CMapId& cmap_id) { 1268bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapBuilderMap* cmap_builders = this->GetCMapBuilders(); 1269bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com CMapBuilderMap::iterator builder = cmap_builders->find(cmap_id); 1270bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (builder != cmap_builders->end()) 1271bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return builder->second; 1272bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#ifndef SFNTLY_NO_EXCEPTION 1273bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com throw NoSuchElementException("No builder found for cmap_id"); 1274bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#else 1275bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return NULL; 1276bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com#endif 1277bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 1278bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 1279bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.comCMapTable::CMapBuilderMap* CMapTable::Builder::GetCMapBuilders() { 1280bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com if (cmap_builders_.empty()) { 1281bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com Initialize(InternalReadData()); 1282bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com set_model_changed(); 1283bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com } 1284bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com return &cmap_builders_; 1285bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com} 1286bb035e4061737ef1ac7ee3e1263c443b55c123e9dfilimon@google.com 1287464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com} // namespace sfntly 1288