130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/* 230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Copyright 2011 Google Inc. All Rights Reserved. 330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Licensed under the Apache License, Version 2.0 (the "License"); 530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * you may not use this file except in compliance with the License. 630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * You may obtain a copy of the License at 730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * http://www.apache.org/licenses/LICENSE-2.0 930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Unless required by applicable law or agreed to in writing, software 1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * distributed under the License is distributed on an "AS IS" BASIS, 1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * See the License for the specific language governing permissions and 1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * limitations under the License. 1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun */ 1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// type.h needs to be included first because of building issues on Windows 1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Type aliases we delcare are defined in other headers and make the build 1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// fail otherwise. 2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/type.h" 2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/core/cmap_table.h" 2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <stdio.h> 2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <stdlib.h> 2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <utility> 2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/font.h" 2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/math/font_math.h" 3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/endian.h" 3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/exception_type.h" 3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/core/name_table.h" 3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly { 3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t CMapTable::NOTDEF = 0; 3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapId CMapTable::WINDOWS_BMP = { 3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun PlatformId::kWindows, 4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WindowsEncodingId::kUnicodeUCS2 4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapId CMapTable::WINDOWS_UCS4 = { 4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun PlatformId::kWindows, 4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WindowsEncodingId::kUnicodeUCS4 4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapId CMapTable::MAC_ROMAN = { 4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun PlatformId::kWindows, 4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MacintoshEncodingId::kRoman 4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable class 5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapTable(Header* header, ReadableFontData* data) 5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTableContainerTable(header, data) { 5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::~CMapTable() {} 5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t index) { 6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (index < 0 || index > NumCMaps()) { 6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifndef SFNTLY_NO_EXCEPTION 6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IndexOutOfBoundException("Requested CMap index is out of bounds."); 6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t platform_id = PlatformId(index); 6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t encoding_id = EncodingId(index); 7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapId cmap_id = NewCMapId(platform_id, encoding_id); 7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset_ = Offset(index); 7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<FontDataTable::Builder> cmap_builder = 7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (CMap::Builder::GetBuilder(data_, offset_, cmap_id)); 7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!cmap_builder) { 7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifndef SFNTLY_NO_EXCEPTION 7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw NoSuchElementException("Cannot find builder for requested CMap."); 7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return down_cast<CMapTable::CMap*>(cmap_builder->Build()); 8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t platform_id, 8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const int32_t encoding_id) { 8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GetCMap(NewCMapId(platform_id, encoding_id)); 8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMap* 9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::GetCMap(const CMapTable::CMapId cmap_id) { 9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapIdFilter id_filter(cmap_id); 9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapIterator cmap_iterator(this, &id_filter); 9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // There can only be one cmap with a particular CMapId 9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (cmap_iterator.HasNext()) { 9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<CMapTable::CMap> cmap; 9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cmap.Attach(cmap_iterator.Next()); 9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return cmap.Detach(); 9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifndef SFNTLY_NO_EXCEPTION 10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw NoSuchElementException(); 10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::Version() { 10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(Offset::kVersion); 10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::NumCMaps() { 11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(Offset::kNumTables); 11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapId CMapTable::GetCMapId(int32_t index) { 11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NewCMapId(PlatformId(index), EncodingId(index)); 11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::PlatformId(int32_t index) { 11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(Offset::kEncodingRecordPlatformId + 12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OffsetForEncodingRecord(index)); 12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::EncodingId(int32_t index) { 12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(Offset::kEncodingRecordEncodingId + 12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OffsetForEncodingRecord(index)); 12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::Offset(int32_t index) { 12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadULongAsInt(Offset::kEncodingRecordOffset + 13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OffsetForEncodingRecord(index)); 13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::OffsetForEncodingRecord(int32_t index) { 13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return Offset::kEncodingRecordStart + index * Offset::kEncodingRecordSize; 13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapId CMapTable::NewCMapId(int32_t platform_id, 13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t encoding_id) { 13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapId result; 14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun result.platform_id = platform_id; 14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun result.encoding_id = encoding_id; 14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return result; 14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapId CMapTable::NewCMapId(const CMapId& obj) { 14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapId result; 14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun result.platform_id = obj.platform_id; 14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun result.encoding_id = obj.encoding_id; 14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return result; 15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapIterator class 15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapIterator::CMapIterator(CMapTable* table, 15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapFilter* filter) 15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : table_index_(0), filter_(filter), table_(table) { 15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CMapTable::CMapIterator::HasNext() { 16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!filter_) { 16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (table_index_ < table_->NumCMaps()) { 16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (; table_index_ < table_->NumCMaps(); ++table_index_) { 16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (filter_->accept(table_->GetCMapId(table_index_))) { 17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMap* CMapTable::CMapIterator::Next() { 17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!HasNext()) { 17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifndef SFNTLY_NO_EXCEPTION 17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw NoSuchElementException(); 18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapPtr next_cmap; 18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun next_cmap.Attach(table_->GetCMap(table_index_++)); 18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (next_cmap == NULL) { 18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifndef SFNTLY_NO_EXCEPTION 18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw NoSuchElementException("Error during the creation of the CMap"); 18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return next_cmap.Detach(); 19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapId class 19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapIdComparator class 20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CMapTable::CMapIdComparator::operator()(const CMapId& lhs, 20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& rhs) const { 20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return ((lhs.platform_id << 8 | lhs.encoding_id) > 20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (rhs.platform_id << 8 | rhs.encoding_id)); 20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapIdFilter class 21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id) 21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : wanted_id_(wanted_id), 21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun comparator_(NULL) { 21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id, 21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapIdComparator* comparator) 22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : wanted_id_(wanted_id), 22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun comparator_(comparator) { 22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CMapTable::CMapIdFilter::accept(const CMapId& cmap_id) const { 22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!comparator_) 22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return wanted_id_ == cmap_id; 22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return (*comparator_)(wanted_id_, cmap_id); 22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMap class 23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::CMap(ReadableFontData* data, int32_t format, 23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTable(data), format_(format), cmap_id_(cmap_id) { 23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::~CMap() { 23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMap::Builder class 24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::Builder::~Builder() { 24530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 24630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 24730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMap::Builder* 24830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapTable::CMap::Builder::GetBuilder(ReadableFontData* data, int32_t offset, 24930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) { 25030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // NOT IMPLEMENTED: Java enum value validation 25130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t format = data->ReadUShort(offset); 25230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapBuilderPtr builder; 25330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun switch (format) { 25430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case CMapFormat::kFormat0: 25530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder.Attach(CMapFormat0::Builder::NewInstance(data, offset, cmap_id)); 25630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun break; 25730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case CMapFormat::kFormat2: 25830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_CMAP) 25930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "Requesting Format2 builder, but it's unsupported; " 26030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun "returning NULL\n"); 26130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 26230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun break; 26330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case CMapFormat::kFormat4: 26430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder.Attach(CMapFormat4::Builder::NewInstance(data, offset, cmap_id)); 26530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun break; 26630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun default: 26730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifdef SFNTLY_DEBUG_CMAP 26830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "Unknown builder format requested\n"); 26930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 27030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun break; 27130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 27230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 27330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 27430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 27530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMap::Builder* 27630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::Builder::GetBuilder(int32_t format, const CMapId& cmap_id) { 27730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<CMapTable::CMap::Builder> builder; 27830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun switch (format) { 27930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case CMapFormat::kFormat0: 28030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder.Attach(CMapFormat0::Builder::NewInstance(cmap_id)); 28130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun break; 28230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case CMapFormat::kFormat2: 28330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_CMAP) 28430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "Requesting Format2 builder, but it's unsupported; " 28530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun "returning NULL\n"); 28630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 28730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun break; 28830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case CMapFormat::kFormat4: 28930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder.Attach(CMapFormat4::Builder::NewInstance(cmap_id)); 29030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun break; 29130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun default: 29230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifdef SFNTLY_DEBUG_CMAP 29330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "Unknown builder format requested\n"); 29430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 29530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun break; 29630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 29730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 29830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 29930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 30030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::Builder::Builder(ReadableFontData* data, 30130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t format, 30230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 30330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTable::Builder(data), 30430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun format_(format), 30530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cmap_id_(cmap_id), 30630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun language_(0) { 30730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 30830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 30930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::Builder::Builder(WritableFontData* data, 31030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t format, 31130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 31230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTable::Builder(data), 31330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun format_(format), 31430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cmap_id_(cmap_id), 31530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun language_(0) { 31630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 31730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 31830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMap::Builder::SubSerialize(WritableFontData* new_data) { 31930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return InternalReadData()->CopyTo(new_data); 32030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 32130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 32230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CMapTable::CMap::Builder::SubReadyToSerialize() { 32330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 32430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 32530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 32630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMap::Builder::SubDataSizeToSerialize() { 32730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontDataPtr read_data = InternalReadData(); 32830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!read_data) 32930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 33030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return read_data->Length(); 33130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 33230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 33330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid CMapTable::CMap::Builder::SubDataSet() { 33430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // NOP 33530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 33630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 33730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 33830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapFormat0 33930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 34030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::~CMapFormat0() { 34130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 34230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 34330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat0::Language() { 34430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 34530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 34630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 34730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat0::GlyphId(int32_t character) { 34830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (character < 0 || character > 255) { 34930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMapTable::NOTDEF; 35030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 35130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUByte(character + Offset::kFormat0GlyphIdArray); 35230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 35330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 35430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::CMapFormat0(ReadableFontData* data, 35530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 35630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMap(data, CMapFormat::kFormat0, cmap_id) { 35730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 35830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 35930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::CharacterIterator* CMapTable::CMapFormat0::Iterator() { 36030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return new CMapTable::CMapFormat0::CharacterIterator(0, 0xff); 36130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 36230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 36330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 36430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 36530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapFormat0::CharacterIterator 36630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 36730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::CharacterIterator::CharacterIterator(int32_t start, 36830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t end) 36930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : character_(start), 37030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun max_character_(end) { 37130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 37230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 37330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::CharacterIterator::~CharacterIterator() {} 37430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 37530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CMapTable::CMapFormat0::CharacterIterator::HasNext() { 37630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return character_ < max_character_; 37730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 37830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 37930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat0::CharacterIterator::Next() { 38030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (HasNext()) 38130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return character_++; 38230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifndef SFNTLY_NO_EXCEPTION 38330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw NoSuchElementException("No more characters to iterate."); 38430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 38530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return -1; 38630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 38730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 38830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 38930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapFormat0::Builder 39030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 39130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 39230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMapFormat0::Builder* 39330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::Builder::NewInstance(WritableFontData* data, 39430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 39530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) { 39630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontDataPtr wdata; 39730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (data) { 39830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun wdata.Attach(down_cast<WritableFontData*>( 39930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->Slice(offset, 40030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->ReadUShort(offset + Offset::kFormat0Length)))); 40130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 40230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return new Builder(wdata, CMapFormat::kFormat0, cmap_id); 40330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 40430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 40530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 40630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMapFormat0::Builder* 40730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::Builder::NewInstance(ReadableFontData* data, 40830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 40930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) { 41030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontDataPtr rdata; 41130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (data) { 41230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun rdata.Attach(down_cast<ReadableFontData*>( 41330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->Slice(offset, 41430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->ReadUShort(offset + Offset::kFormat0Length)))); 41530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 41630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return new Builder(rdata, CMapFormat::kFormat0, cmap_id); 41730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 41830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 41930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 42030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMapFormat0::Builder* 42130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::Builder::NewInstance(const CMapId& cmap_id) { 42230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return new Builder(cmap_id); 42330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 42430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 42530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Always call NewInstance instead of the constructor for creating a new builder 42630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// object! This refactoring avoids memory leaks when slicing the font data. 42730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::Builder::Builder(WritableFontData* data, int32_t offset, 42830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 42930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) { 43030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(offset); 43130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 43230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 43330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::Builder::Builder( 43430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data, 43530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 43630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 43730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) { 43830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(offset); 43930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 44030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 44130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::Builder::Builder(const CMapId& cmap_id) 44230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL), 44330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapFormat::kFormat0, 44430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cmap_id) { 44530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 44630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 44730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat0::Builder::~Builder() { 44830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 44930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 45030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH FontDataTable* 45130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapTable::CMapFormat0::Builder::SubBuildTable(ReadableFontData* data) { 45230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataTablePtr table = new CMapFormat0(data, cmap_id()); 45330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return table.Detach(); 45430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 45530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 45630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 45730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapFormat2 45830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 45930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat2::~CMapFormat2() { 46030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 46130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 46230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat2::Language() { 46330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 46430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 46530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 46630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat2::GlyphId(int32_t character) { 46730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (character > 0xffff) { 46830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMapTable::NOTDEF; 46930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 47030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 47130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun uint32_t c = ToBE32(character); 47230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun byte_t high_byte = (c >> 8) & 0xff; 47330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun byte_t low_byte = c & 0xff; 47430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset = SubHeaderOffset(high_byte); 47530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 47630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (offset == 0) { 47730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun low_byte = high_byte; 47830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun high_byte = 0; 47930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 48030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 48130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t first_code = FirstCode(high_byte); 48230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t entry_count = EntryCount(high_byte); 48330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 48430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (low_byte < first_code || low_byte >= first_code + entry_count) { 48530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMapTable::NOTDEF; 48630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 48730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 48830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t id_range_offset = IdRangeOffset(high_byte); 48930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 49030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // position of idRangeOffset + value of idRangeOffset + index for low byte 49130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // = firstcode 49230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t p_location = (offset + Offset::kFormat2SubHeader_idRangeOffset) + 49330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun id_range_offset + 49430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (low_byte - first_code) * DataSize::kUSHORT; 49530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int p = data_->ReadUShort(p_location); 49630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (p == 0) { 49730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMapTable::NOTDEF; 49830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 49930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 50030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (offset == 0) { 50130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return p; 50230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 50330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int id_delta = IdDelta(high_byte); 50430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return (p + id_delta) % 65536; 50530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 50630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 50730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat2::BytesConsumed(int32_t character) { 50830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun uint32_t c = ToBE32(character); 50930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t high_byte = (c >> 8) & 0xff; 51030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset = SubHeaderOffset(high_byte); 51130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return (offset == 0) ? 1 : 2; 51230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 51330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 51430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat2::CMapFormat2(ReadableFontData* data, 51530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 51630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMap(data, CMapFormat::kFormat2, cmap_id) { 51730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 51830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 51930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat2::SubHeaderOffset(int32_t sub_header_index) { 52030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(Offset::kFormat2SubHeaderKeys + 52130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sub_header_index * DataSize::kUSHORT); 52230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 52330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 52430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat2::FirstCode(int32_t sub_header_index) { 52530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t sub_header_offset = SubHeaderOffset(sub_header_index); 52630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(sub_header_offset + 52730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat2SubHeaderKeys + 52830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat2SubHeader_firstCode); 52930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 53030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 53130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat2::EntryCount(int32_t sub_header_index) { 53230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t sub_header_offset = SubHeaderOffset(sub_header_index); 53330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(sub_header_offset + 53430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat2SubHeaderKeys + 53530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat2SubHeader_entryCount); 53630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 53730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 53830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat2::IdRangeOffset(int32_t sub_header_index) { 53930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t sub_header_offset = SubHeaderOffset(sub_header_index); 54030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(sub_header_offset + 54130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat2SubHeaderKeys + 54230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat2SubHeader_idRangeOffset); 54330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 54430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 54530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat2::IdDelta(int32_t sub_header_index) { 54630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t sub_header_offset = SubHeaderOffset(sub_header_index); 54730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(sub_header_offset + 54830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat2SubHeaderKeys + 54930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat2SubHeader_idDelta); 55030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 55130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 55230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::CharacterIterator* CMapTable::CMapFormat2::Iterator() { 55330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // UNIMPLEMENTED 55430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 55530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 55630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 55730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 55830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapFormat2::Builder 55930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 56030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat2::Builder::Builder(WritableFontData* data, 56130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 56230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 56330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMapTable::CMap::Builder(data ? down_cast<WritableFontData*>( 56430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->Slice(offset, data->ReadUShort( 56530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun offset + Offset::kFormat0Length))) 56630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : reinterpret_cast<WritableFontData*>(NULL), 56730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapFormat::kFormat2, cmap_id) { 56830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix. 56930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 57030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 57130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat2::Builder::Builder(ReadableFontData* data, 57230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 57330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 57430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMapTable::CMap::Builder(data ? down_cast<ReadableFontData*>( 57530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->Slice(offset, data->ReadUShort( 57630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun offset + Offset::kFormat0Length))) 57730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : reinterpret_cast<ReadableFontData*>(NULL), 57830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapFormat::kFormat2, cmap_id) { 57930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix. 58030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 58130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 58230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat2::Builder::~Builder() { 58330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 58430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 58530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH FontDataTable* 58630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapTable::CMapFormat2::Builder::SubBuildTable(ReadableFontData* data) { 58730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataTablePtr table = new CMapFormat2(data, cmap_id()); 58830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return table.Detach(); 58930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 59030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 59130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 59230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapFormat4 59330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 59430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::CMapFormat4(ReadableFontData* data, 59530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 59630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMap(data, CMapFormat::kFormat4, cmap_id), 59730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun seg_count_(SegCount(data)), 59830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun start_code_offset_(StartCodeOffset(seg_count_)), 59930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun id_delta_offset_(IdDeltaOffset(seg_count_)), 60030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_id_array_offset_(GlyphIdArrayOffset(seg_count_)) { 60130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 60230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 60330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::~CMapFormat4() { 60430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 60530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 60630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::GlyphId(int32_t character) { 60730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t segment = data_->SearchUShort(StartCodeOffset(seg_count_), 60830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kUSHORT, 60930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat4EndCount, 61030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kUSHORT, 61130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun seg_count_, 61230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun character); 61330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (segment == -1) { 61430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMapTable::NOTDEF; 61530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 61630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t start_code = StartCode(segment); 61730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return RetrieveGlyphId(segment, start_code, character); 61830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 61930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 62030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::RetrieveGlyphId(int32_t segment, 62130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t start_code, 62230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t character) { 62330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (character < start_code) { 62430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMapTable::NOTDEF; 62530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 62630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t id_range_offset = IdRangeOffset(segment); 62730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (id_range_offset == 0) { 62830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return (character + IdDelta(segment)) % 65536; 62930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 63030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(id_range_offset + 63130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun IdRangeOffsetLocation(segment) + 63230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2 * (character - start_code)); 63330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 63430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 63530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::seg_count() { 63630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return seg_count_; 63730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 63830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 63930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::Length() { 64030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return Length(data_); 64130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 64230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 64330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::StartCode(int32_t segment) { 64430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!IsValidIndex(segment)) { 64530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return -1; 64630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 64730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return StartCode(data_.p_, seg_count_, segment); 64830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 64930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 65030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 65130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::Language(ReadableFontData* data) { 65230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t language = data->ReadUShort(Offset::kFormat4Language); 65330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return language; 65430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 65530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 65630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 65730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::Length(ReadableFontData* data) { 65830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t length = data->ReadUShort(Offset::kFormat4Length); 65930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return length; 66030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 66130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 66230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 66330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::SegCount(ReadableFontData* data) { 66430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t seg_count = data->ReadUShort(Offset::kFormat4SegCountX2) / 2; 66530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return seg_count; 66630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 66730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 66830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 66930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::StartCode(ReadableFontData* data, 67030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t seg_count, 67130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index) { 67230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t start_code = data->ReadUShort(StartCodeOffset(seg_count) + 67330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index * DataSize::kUSHORT); 67430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return start_code; 67530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 67630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 67730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 67830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::StartCodeOffset(int32_t seg_count) { 67930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t start_code_offset = Offset::kFormat4EndCount + 68030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (seg_count + 1) * DataSize::kUSHORT; 68130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return start_code_offset; 68230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 68330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 68430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 68530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::EndCode(ReadableFontData* data, 68630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t seg_count, 68730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index) { 68830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(seg_count); 68930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t end_code = data->ReadUShort(Offset::kFormat4EndCount + 69030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index * DataSize::kUSHORT); 69130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return end_code; 69230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 69330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 69430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 69530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::IdDelta(ReadableFontData* data, 69630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t seg_count, 69730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index) { 69830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t id_delta = data->ReadUShort(IdDeltaOffset(seg_count) + 69930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index * DataSize::kUSHORT); 70030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return id_delta; 70130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 70230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 70330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 70430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::IdDeltaOffset(int32_t seg_count) { 70530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t id_delta_offset = 70630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT; 70730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return id_delta_offset; 70830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 70930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 71030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 71130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::IdRangeOffset(ReadableFontData* data, 71230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t seg_count, 71330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index) { 71430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t id_range_offset = 71530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->ReadUShort(IdRangeOffsetOffset(seg_count) 71630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun + index * DataSize::kUSHORT); 71730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return id_range_offset; 71830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 71930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 72030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 72130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::IdRangeOffsetOffset(int32_t seg_count) { 72230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t id_range_offset_offset = 72330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT + 72430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun seg_count * DataSize::kSHORT; 72530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return id_range_offset_offset; 72630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 72730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 72830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 72930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::GlyphIdArrayOffset(int32_t seg_count) { 73030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t glyph_id_array_offset = 73130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kFormat4EndCount + (3 * seg_count + 1) * DataSize::kUSHORT + 73230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun seg_count * DataSize::kSHORT; 73330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return glyph_id_array_offset; 73430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 73530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 73630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::EndCode(int32_t segment) { 73730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (IsValidIndex(segment)) { 73830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return EndCode(data_, seg_count_, segment); 73930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 74030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_NO_EXCEPTION) 74130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return -1; 74230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 74330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IllegalArgumentException(); 74430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 74530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 74630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 74730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CMapTable::CMapFormat4::IsValidIndex(int32_t segment) { 74830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (segment < 0 || segment >= seg_count_) { 74930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_NO_EXCEPTION) 75030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 75130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 75230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IllegalArgumentException(); 75330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 75430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 75530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 75630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 75730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 75830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::IdDelta(int32_t segment) { 75930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (IsValidIndex(segment)) 76030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return IdDelta(data_, seg_count_, segment); 76130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return -1; 76230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 76330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 76430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::IdRangeOffset(int32_t segment) { 76530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (IsValidIndex(segment)) 76630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(IdRangeOffsetLocation(segment)); 76730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return -1; 76830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 76930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 77030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::IdRangeOffsetLocation(int32_t segment) { 77130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (IsValidIndex(segment)) 77230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return IdRangeOffsetOffset(seg_count_) + segment * DataSize::kUSHORT; 77330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return -1; 77430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 77530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 77630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::GlyphIdArray(int32_t index) { 77730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(glyph_id_array_offset_ + index * DataSize::kUSHORT); 77830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 77930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 78030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::Language() { 78130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return Language(data_); 78230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 78330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 78430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 78530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::CharacterIterator* CMapTable::CMapFormat4::Iterator() { 78630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return new CharacterIterator(this); 78730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 78830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 78930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 79030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapFormat4::CharacterIterator class 79130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 79230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::CharacterIterator::CharacterIterator( 79330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapFormat4* parent) 79430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : parent_(parent), 79530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segment_index_(0), 79630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun first_char_in_segment_(-1), 79730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun last_char_in_segment_(-1), 79830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun next_char_(-1), 79930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun next_char_set_(false) { 80030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 80130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 80230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CMapTable::CMapFormat4::CharacterIterator::HasNext() { 80330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (next_char_set_) 80430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 80530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun while (segment_index_ < parent_->seg_count_) { 80630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (first_char_in_segment_ < 0) { 80730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun first_char_in_segment_ = parent_->StartCode(segment_index_); 80830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun last_char_in_segment_ = parent_->EndCode(segment_index_); 80930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun next_char_ = first_char_in_segment_; 81030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun next_char_set_ = true; 81130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 81230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 81330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (next_char_ < last_char_in_segment_) { 81430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun next_char_++; 81530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun next_char_set_ = true; 81630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 81730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 81830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segment_index_++; 81930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun first_char_in_segment_ = -1; 82030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 82130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 82230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 82330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 82430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::CharacterIterator::Next() { 82530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!next_char_set_) { 82630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!HasNext()) { 82730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_NO_EXCEPTION) 82830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return -1; 82930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 83030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw NoSuchElementException("No more characters to iterate."); 83130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 83230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 83330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 83430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun next_char_set_ = false; 83530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return next_char_; 83630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 83730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 83830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 83930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapFormat4::Builder::Segment class 84030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 84130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Segment::Segment() {} 84230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 84330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Segment::Segment(Segment* other) 84430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : start_count_(other->start_count_), 84530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun end_count_(other->end_count_), 84630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun id_delta_(other->id_delta_), 84730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun id_range_offset_(other->id_range_offset_) { 84830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 84930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 85030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Segment::Segment(int32_t start_count, 85130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t end_count, 85230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t id_delta, 85330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t id_range_offset) 85430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : start_count_(start_count), 85530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun end_count_(end_count), 85630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun id_delta_(id_delta), 85730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun id_range_offset_(id_range_offset) { 85830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 85930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 86030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Segment::~Segment() {} 86130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 86230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::Builder::Segment::start_count() { 86330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return start_count_; 86430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 86530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 86630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid 86730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Segment::set_start_count(int32_t start_count) { 86830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun start_count_ = start_count; 86930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 87030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 87130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::Builder::Segment::end_count() { 87230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return end_count_; 87330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 87430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 87530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid 87630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Segment::set_end_count(int32_t end_count) { 87730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun end_count_ = end_count; 87830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 87930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 88030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::Builder::Segment::id_delta() { 88130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return id_delta_; 88230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 88330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 88430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid 88530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Segment::set_id_delta(int32_t id_delta) { 88630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun id_delta_ = id_delta; 88730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 88830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 88930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::Builder::Segment::id_range_offset() { 89030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return id_range_offset_; 89130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 89230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 89330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid 89430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Segment:: 89530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunset_id_range_offset(int32_t id_range_offset) { 89630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun id_range_offset_ = id_range_offset; 89730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 89830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 89930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 90030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH SegmentList* 90130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Segment::DeepCopy(SegmentList* original) { 90230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun SegmentList* list = new SegmentList; 90330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (SegmentList::iterator it = original->begin(), 90430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun e = original->end(); it != e; ++it) { 90530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun list->push_back(*it); 90630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 90730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return list; 90830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 90930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 91030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 91130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::CMapFormat4::Builder class 91230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 91330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMapFormat4::Builder* 91430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::NewInstance(ReadableFontData* data, 91530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 91630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) { 91730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontDataPtr rdata; 91830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (data) { 91930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun rdata.Attach 92030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (down_cast<ReadableFontData*> 92130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (data->Slice(offset, 92230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->ReadUShort(offset + Offset::kFormat4Length)))); 92330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 92430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return new Builder(rdata, CMapFormat::kFormat4, cmap_id); 92530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 92630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 92730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMapFormat4::Builder* 92830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::NewInstance(WritableFontData* data, 92930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 93030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) { 93130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontDataPtr wdata; 93230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (data) { 93330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun wdata.Attach 93430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (down_cast<WritableFontData*> 93530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (data->Slice(offset, 93630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->ReadUShort(offset + Offset::kFormat4Length)))); 93730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 93830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return new Builder(wdata, CMapFormat::kFormat4, cmap_id); 93930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 94030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 94130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMapFormat4::Builder* 94230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::NewInstance(const CMapId& cmap_id) { 94330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return new Builder(cmap_id); 94430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 94530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 94630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Builder(ReadableFontData* data, int32_t offset, 94730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 94830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) { 94930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(offset); 95030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 95130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 95230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Builder(WritableFontData* data, int32_t offset, 95330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 95430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) { 95530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(offset); 95630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 95730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 95830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Builder(SegmentList* segments, 95930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun IntegerList* glyph_id_array, 96030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id) 96130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL), 96230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapFormat::kFormat4, cmap_id), 96330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segments_(segments->begin(), segments->end()), 96430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_id_array_(glyph_id_array->begin(), glyph_id_array->end()) { 96530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 96630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 96730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 96830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::Builder(const CMapId& cmap_id) 96930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL), 97030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapFormat::kFormat4, cmap_id) { 97130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 97230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 97330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::~Builder() {} 97430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 97530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid CMapTable::CMapFormat4::Builder::Initialize(ReadableFontData* data) { 97630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (data == NULL || data->Length() == 0) 97730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 97830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 97930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // build segments 98030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t seg_count = CMapFormat4::SegCount(data); 98130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t index = 0; index < seg_count; ++index) { 98230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<Segment> segment = new Segment; 98330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segment->set_start_count(CMapFormat4::StartCode(data, seg_count, index)); 98430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined SFNTLY_DEBUG_CMAP 98530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "Segment %d; start %d\n", index, segment->start_count()); 98630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 98730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segment->set_end_count(CMapFormat4::EndCode(data, seg_count, index)); 98830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segment->set_id_delta(CMapFormat4::IdDelta(data, seg_count, index)); 98930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segment->set_id_range_offset(CMapFormat4::IdRangeOffset(data, 99030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun seg_count, 99130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index)); 99230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segments_.push_back(segment); 99330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 99430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 99530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // build glyph id array 99630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t glyph_id_array_offset = CMapFormat4::GlyphIdArrayOffset(seg_count); 99730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t glyph_id_array_length = 99830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (CMapFormat4::Length(data) - glyph_id_array_offset) 99930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun / DataSize::kUSHORT; 100030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "id array size %d\n", glyph_id_array_length); 100130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < glyph_id_array_length; i += DataSize::kUSHORT) { 100230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_id_array_.push_back(data->ReadUShort(glyph_id_array_offset + i)); 100330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 100430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 100530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 100630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunSegmentList* CMapTable::CMapFormat4::Builder::segments() { 100730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (segments_.empty()) { 100830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(InternalReadData()); 100930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 101030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 101130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return &segments_; 101230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 101330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 101430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid CMapTable::CMapFormat4::Builder::set_segments(SegmentList* segments) { 101530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segments_.assign(segments->begin(), segments->end()); 101630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 101730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 101830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 101930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunIntegerList* CMapTable::CMapFormat4::Builder::glyph_id_array() { 102030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (glyph_id_array_.empty()) { 102130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(InternalReadData()); 102230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 102330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 102430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return &glyph_id_array_; 102530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 102630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 102730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid CMapTable::CMapFormat4::Builder:: 102830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunset_glyph_id_array(IntegerList* glyph_id_array) { 102930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_id_array_.assign(glyph_id_array->begin(), glyph_id_array->end()); 103030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 103130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 103230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 103330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH FontDataTable* 103430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::SubBuildTable(ReadableFontData* data) { 103530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataTablePtr table = new CMapFormat4(data, cmap_id()); 103630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return table.Detach(); 103730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 103830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 103930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid CMapTable::CMapFormat4::Builder::SubDataSet() { 104030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun segments_.clear(); 104130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_id_array_.clear(); 104230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 104330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 104430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 104530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::CMapFormat4::Builder::SubDataSizeToSerialize() { 104630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!model_changed()) { 104730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMap::Builder::SubDataSizeToSerialize(); 104830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 104930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t size = Offset::kFormat4FixedSize + segments_.size() 105030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * (3 * DataSize::kUSHORT + DataSize::kSHORT) 105130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun + glyph_id_array_.size() * DataSize::kSHORT; 105230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return size; 105330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 105430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 105530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CMapTable::CMapFormat4::Builder::SubReadyToSerialize() { 105630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!model_changed()) { 105730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMap::Builder::SubReadyToSerialize(); 105830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 105930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!segments()->empty()) { 106030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 106130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 106230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 106330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 106430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 106530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t 106630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapFormat4::Builder::SubSerialize(WritableFontData* new_data) { 106730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!model_changed()) { 106830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMap::Builder::SubSerialize(new_data); 106930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 107030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index = 0; 107130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, CMapFormat::kFormat4); 107230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += DataSize::kUSHORT; // length - write this at the end 107330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, language()); 107430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 107530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t seg_count = segments_.size(); 107630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, seg_count * 2); 107730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t log2_seg_count = FontMath::Log2(seg_count); 107830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t search_range = 1 << (log2_seg_count + 1); 107930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, search_range); 108030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t entry_selector = log2_seg_count; 108130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, entry_selector); 108230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t range_shift = 2 * seg_count - search_range; 108330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, range_shift); 108430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 108530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < seg_count; ++i) { 108630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, segments_[i]->end_count()); 108730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 108830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, 0); // reserved ushort 108930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < seg_count; ++i) { 109030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined SFNTLY_DEBUG_CMAP 109130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "Segment %d; start %d\n", i, segments_[i]->start_count()); 109230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 109330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, segments_[i]->start_count()); 109430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 109530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < seg_count; ++i) { 109630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteShort(index, segments_[i]->id_delta()); 109730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 109830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < seg_count; ++i) { 109930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, segments_[i]->id_range_offset()); 110030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 110130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 110230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined SFNTLY_DEBUG_CMAP 110330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "Glyph id array size %lu\n", glyph_id_array_.size()); 110430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 110530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (size_t i = 0; i < glyph_id_array_.size(); ++i) { 110630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += new_data->WriteUShort(index, glyph_id_array_[i]); 110730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 110830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 110930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun new_data->WriteUShort(Offset::kFormat4Length, index); 111030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return index; 111130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 111230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 111330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 111430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * CMapTable::Builder class 111530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 111630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::Builder::Builder(Header* header, WritableFontData* data) 111730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTableContainerTable::Builder(header, data), version_(0) { 111830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 111930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 112030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::Builder::Builder(Header* header, ReadableFontData* data) 112130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTableContainerTable::Builder(header, data), version_(0) { 112230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 112330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 112430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::Builder::~Builder() { 112530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 112630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 112730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::Builder::SubSerialize(WritableFontData* new_data) { 112830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t size = new_data->WriteUShort(CMapTable::Offset::kVersion, 112930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun version_); 113030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size += new_data->WriteUShort(CMapTable::Offset::kNumTables, 113130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GetCMapBuilders()->size()); 113230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 113330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index_offset = size; 113430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size += GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize; 113530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(), 113630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun e = GetCMapBuilders()->end(); it != e; ++it) { 113730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapBuilderPtr b = it->second; 113830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // header entry 113930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index_offset += new_data->WriteUShort(index_offset, b->platform_id()); 114030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index_offset += new_data->WriteUShort(index_offset, b->encoding_id()); 114130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index_offset += new_data->WriteULong(index_offset, size); 114230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 114330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // cmap 114430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataPtr slice; 114530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun slice.Attach(new_data->Slice(size)); 114630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size += b->SubSerialize(down_cast<WritableFontData*>(slice.p_)); 114730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 114830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return size; 114930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 115030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 115130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CMapTable::Builder::SubReadyToSerialize() { 115230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (GetCMapBuilders()->empty()) 115330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 115430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 115530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // check each table 115630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(), 115730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun e = GetCMapBuilders()->end(); it != e; ++it) { 115830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!it->second->SubReadyToSerialize()) 115930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 116030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 116130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 116230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 116330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 116430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::Builder::SubDataSizeToSerialize() { 116530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (GetCMapBuilders()->empty()) 116630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 116730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 116830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun bool variable = false; 116930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t size = CMapTable::Offset::kEncodingRecordStart + 117030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize; 117130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 117230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // calculate size of each table 117330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(), 117430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun e = GetCMapBuilders()->end(); it != e; ++it) { 117530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t cmap_size = it->second->SubDataSizeToSerialize(); 117630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size += abs(cmap_size); 117730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun variable |= cmap_size <= 0; 117830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 117930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return variable ? -size : size; 118030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 118130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 118230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid CMapTable::Builder::SubDataSet() { 118330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GetCMapBuilders()->clear(); 118430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Table::Builder::set_model_changed(); 118530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 118630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 118730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH FontDataTable* 118830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapTable::Builder::SubBuildTable(ReadableFontData* data) { 118930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataTablePtr table = new CMapTable(header(), data); 119030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return table.Detach(); 119130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 119230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 119330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::Builder* 119430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapTable::Builder::CreateBuilder(Header* header, 119530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData* data) { 119630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<CMapTable::Builder> builder; 119730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder = new CMapTable::Builder(header, data); 119830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 119930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 120030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 120130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 120230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH CMapTable::CMap::Builder* 120330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapTable::Builder::CMapBuilder(ReadableFontData* data, int32_t index) { 120430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (index < 0 || index > NumCMaps(data)) { 120530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 120630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IndexOutOfBoundException( 120730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun "CMap table is outside of the bounds of the known tables."); 120830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 120930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 121030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 121130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 121230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t platform_id = data->ReadUShort(Offset::kEncodingRecordPlatformId + 121330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OffsetForEncodingRecord(index)); 121430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t encoding_id = data->ReadUShort(Offset::kEncodingRecordEncodingId + 121530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OffsetForEncodingRecord(index)); 121630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset = data->ReadULongAsInt(Offset::kEncodingRecordOffset + 121730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OffsetForEncodingRecord(index)); 121830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return CMap::Builder::GetBuilder(data, offset, 121930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun NewCMapId(platform_id, encoding_id)); 122030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 122130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 122230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 122330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::Builder::NumCMaps(ReadableFontData* data) { 122430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (data == NULL) { 122530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 122630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 122730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data->ReadUShort(Offset::kNumTables); 122830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 122930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 123030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t CMapTable::Builder::NumCMaps() { 123130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GetCMapBuilders()->size(); 123230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 123330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 123430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid CMapTable::Builder::Initialize(ReadableFontData* data) { 123530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t num_cmaps = NumCMaps(data); 123630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < num_cmaps; ++i) { 123730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapTable::CMap::Builder* cmap_builder = CMapBuilder(data, i); 123830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!cmap_builder) 123930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun continue; 124030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cmap_builders_[cmap_builder->cmap_id()] = cmap_builder; 124130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 124230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 124330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 124430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::Builder* CMapTable::Builder::NewCMapBuilder( 124530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const CMapId& cmap_id, 124630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data) { 124730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<WritableFontData> wfd; 124830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun wfd.Attach(WritableFontData::CreateWritableFontData(data->Size())); 124930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data->CopyTo(wfd.p_); 125030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapTable::CMapBuilderPtr builder; 125130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder.Attach(CMap::Builder::GetBuilder(wfd.p_, 0, cmap_id)); 125230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders(); 125330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cmap_builders->insert(std::make_pair(cmap_id, builder.p_)); 125430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 125530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 125630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 125730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::Builder* 125830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::Builder::NewCMapBuilder(int32_t format, const CMapId& cmap_id) { 125930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<CMapTable::CMap::Builder> cmap_builder; 126030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cmap_builder.Attach(CMap::Builder::GetBuilder(format, cmap_id)); 126130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders(); 126230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cmap_builders->insert(std::make_pair(cmap_id, cmap_builder.p_)); 126330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return cmap_builder.Detach(); 126430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 126530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 126630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMap::Builder* 126730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::Builder::CMapBuilder(const CMapId& cmap_id) { 126830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapBuilderMap* cmap_builders = this->GetCMapBuilders(); 126930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CMapBuilderMap::iterator builder = cmap_builders->find(cmap_id); 127030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (builder != cmap_builders->end()) 127130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder->second; 127230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifndef SFNTLY_NO_EXCEPTION 127330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw NoSuchElementException("No builder found for cmap_id"); 127430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 127530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 127630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 127730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 127830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 127930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapTable::CMapBuilderMap* CMapTable::Builder::GetCMapBuilders() { 128030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (cmap_builders_.empty()) { 128130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(InternalReadData()); 128230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 128330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 128430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return &cmap_builders_; 128530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 128630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 128730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} // namespace sfntly 1288