130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/* 230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Copyright 2011 Google Inc. All Rights Reserved. 330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Licensed under the Apache License, Version 2.0 (the "License"); 530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * you may not use this file except in compliance with the License. 630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * You may obtain a copy of the License at 730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * http://www.apache.org/licenses/LICENSE-2.0 930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Unless required by applicable law or agreed to in writing, software 1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * distributed under the License is distributed on an "AS IS" BASIS, 1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * See the License for the specific language governing permissions and 1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * limitations under the License. 1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun */ 1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/truetype/loca_table.h" 1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/exception_type.h" 1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly { 2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * LocaTable class 2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunLocaTable::~LocaTable() {} 2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::GlyphOffset(int32_t glyph_id) { 2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (glyph_id < 0 || glyph_id >= num_glyphs_) { 2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IndexOutOfBoundException("Glyph ID is out of bounds."); 3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return Loca(glyph_id); 3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::GlyphLength(int32_t glyph_id) { 3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (glyph_id < 0 || glyph_id >= num_glyphs_) { 3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IndexOutOfBoundException("Glyph ID is out of bounds."); 4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return Loca(glyph_id + 1) - Loca(glyph_id); 4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::NumLocas() { 4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return num_glyphs_ + 1; 4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Loca(int32_t index) { 5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (index > num_glyphs_) { 5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IndexOutOfBoundException(); 5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (format_version_ == IndexToLocFormat::kShortOffset) { 5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 2 * data_->ReadUShort(index * DataSize::kUSHORT); 5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadULongAsInt(index * DataSize::kULONG); 6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunLocaTable::LocaTable(Header* header, 6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data, 6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t format_version, 6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t num_glyphs) 6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : Table(header, data), 6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun format_version_(format_version), 6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun num_glyphs_(num_glyphs) { 7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * LocaTable::Iterator class 7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunLocaTable::LocaIterator::LocaIterator(LocaTable* table) 7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : PODIterator<int32_t, LocaTable>(table), index_(-1) { 7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool LocaTable::LocaIterator::HasNext() { 8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return index_ <= container()->num_glyphs_; 8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::LocaIterator::Next() { 8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return container()->Loca(index_++); 8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * LocaTable::Builder class 8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunLocaTable::Builder::Builder(Header* header, WritableFontData* data) 9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : Table::Builder(header, data), 9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun format_version_(IndexToLocFormat::kLongOffset), 9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun num_glyphs_(-1) { 9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunLocaTable::Builder::Builder(Header* header, ReadableFontData* data) 9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : Table::Builder(header, data), 9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun format_version_(IndexToLocFormat::kLongOffset), 9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun num_glyphs_(-1) { 10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunLocaTable::Builder::~Builder() {} 10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH 10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunLocaTable::Builder* LocaTable::Builder::CreateBuilder(Header* header, 10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData* data) { 10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<LocaTable::Builder> builder; 10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder = new LocaTable::Builder(header, data); 10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunIntegerList* LocaTable::Builder::LocaList() { 11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GetLocaList(); 11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid LocaTable::Builder::SetLocaList(IntegerList* list) { 11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_.clear(); 11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (list) { 11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_ = *list; 12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Builder::GlyphOffset(int32_t glyph_id) { 12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (CheckGlyphRange(glyph_id) == -1) { 12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GetLocaList()->at(glyph_id); 12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Builder::GlyphLength(int32_t glyph_id) { 13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (CheckGlyphRange(glyph_id) == -1) { 13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GetLocaList()->at(glyph_id + 1) - GetLocaList()->at(glyph_id); 13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid LocaTable::Builder::SetNumGlyphs(int32_t num_glyphs) { 13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun num_glyphs_ = num_glyphs; 14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Builder::NumGlyphs() { 14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return LastGlyphIndex() - 1; 14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid LocaTable::Builder::Revert() { 14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_.clear(); 14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(false); 14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Builder::NumLocas() { 15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GetLocaList()->size(); 15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Builder::Loca(int32_t index) { 15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GetLocaList()->at(index); 15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH 16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFontDataTable* LocaTable::Builder::SubBuildTable(ReadableFontData* data) { 16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataTablePtr table = 16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun new LocaTable(header(), data, format_version_, num_glyphs_); 16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return table.Detach(); 16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid LocaTable::Builder::SubDataSet() { 16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(InternalReadData()); 16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Builder::SubDataSizeToSerialize() { 17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (loca_.empty()) { 17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (format_version_ == IndexToLocFormat::kLongOffset) { 17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return loca_.size() * DataSize::kULONG; 17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return loca_.size() * DataSize::kUSHORT; 17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool LocaTable::Builder::SubReadyToSerialize() { 18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return !loca_.empty(); 18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Builder::SubSerialize(WritableFontData* new_data) { 18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t size = 0; 18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (IntegerList::iterator l = loca_.begin(), end = loca_.end(); 18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun l != end; ++l) { 18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (format_version_ == IndexToLocFormat::kLongOffset) { 18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size += new_data->WriteULong(size, *l); 19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size += new_data->WriteUShort(size, *l / 2); 19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun num_glyphs_ = loca_.size() - 1; 19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return size; 19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid LocaTable::Builder::Initialize(ReadableFontData* data) { 19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ClearLoca(false); 20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (data) { 20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (NumGlyphs() < 0) { 20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IllegalStateException("numglyphs not set on LocaTable Builder."); 20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun LocaTablePtr table = 20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun new LocaTable(header(), data, format_version_, num_glyphs_); 20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<LocaTable::LocaIterator> loca_iter = 21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun new LocaTable::LocaIterator(table); 21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun while (loca_iter->HasNext()) { 21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_.push_back(loca_iter->Next()); 21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Builder::CheckGlyphRange(int32_t glyph_id) { 21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (glyph_id < 0 || glyph_id > LastGlyphIndex()) { 21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IndexOutOfBoundsException("Glyph ID is outside of the allowed range"); 22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return -1; 22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return glyph_id; 22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t LocaTable::Builder::LastGlyphIndex() { 22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return !loca_.empty() ? loca_.size() - 2 : num_glyphs_ - 1; 22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunIntegerList* LocaTable::Builder::GetLocaList() { 23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (loca_.empty()) { 23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(InternalReadData()); 23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return &loca_; 23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid LocaTable::Builder::ClearLoca(bool nullify) { 24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Note: in C++ port, nullify is not used at all. 24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(nullify); 24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_.clear(); 24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(false); 24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 24530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 24630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} // namespace sfntly 247