1 /*
2 * Copyright 2011 Google Inc. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 = the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "sfntly/table/bitmap/bitmap_size_table.h"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include "sfntly/math/font_math.h"
23 #include "sfntly/table/bitmap/eblc_table.h"
24 #include "sfntly/table/bitmap/index_sub_table_format1.h"
25 #include "sfntly/table/bitmap/index_sub_table_format2.h"
26 #include "sfntly/table/bitmap/index_sub_table_format3.h"
27 #include "sfntly/table/bitmap/index_sub_table_format4.h"
28 #include "sfntly/table/bitmap/index_sub_table_format5.h"
29
30 namespace sfntly {
31 /******************************************************************************
32 * BitmapSizeTable class
33 ******************************************************************************/
~BitmapSizeTable()34 BitmapSizeTable::~BitmapSizeTable() {
35 }
36
IndexSubTableArrayOffset()37 int32_t BitmapSizeTable::IndexSubTableArrayOffset() {
38 return data_->ReadULongAsInt(
39 EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset);
40 }
41
IndexTableSize()42 int32_t BitmapSizeTable::IndexTableSize() {
43 return data_->ReadULongAsInt(
44 EblcTable::Offset::kBitmapSizeTable_indexTableSize);
45 }
46
NumberOfIndexSubTables()47 int32_t BitmapSizeTable::NumberOfIndexSubTables() {
48 return NumberOfIndexSubTables(data_, 0);
49 }
50
ColorRef()51 int32_t BitmapSizeTable::ColorRef() {
52 return data_->ReadULongAsInt(EblcTable::Offset::kBitmapSizeTable_colorRef);
53 }
54
StartGlyphIndex()55 int32_t BitmapSizeTable::StartGlyphIndex() {
56 return data_->ReadUShort(EblcTable::Offset::kBitmapSizeTable_startGlyphIndex);
57 }
58
EndGlyphIndex()59 int32_t BitmapSizeTable::EndGlyphIndex() {
60 return data_->ReadUShort(EblcTable::Offset::kBitmapSizeTable_endGlyphIndex);
61 }
62
PpemX()63 int32_t BitmapSizeTable::PpemX() {
64 return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_ppemX);
65 }
66
PpemY()67 int32_t BitmapSizeTable::PpemY() {
68 return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_ppemY);
69 }
70
BitDepth()71 int32_t BitmapSizeTable::BitDepth() {
72 return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_bitDepth);
73 }
74
FlagsAsInt()75 int32_t BitmapSizeTable::FlagsAsInt() {
76 return data_->ReadChar(EblcTable::Offset::kBitmapSizeTable_flags);
77 }
78
GetIndexSubTable(int32_t index)79 IndexSubTable* BitmapSizeTable::GetIndexSubTable(int32_t index) {
80 IndexSubTableList* subtable_list = GetIndexSubTableList();
81 if (index >= 0 && (size_t)index < subtable_list->size()) {
82 return (*subtable_list)[index];
83 }
84 return NULL;
85 }
86
GlyphOffset(int32_t glyph_id)87 int32_t BitmapSizeTable::GlyphOffset(int32_t glyph_id) {
88 IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
89 if (subtable == NULL) {
90 return -1;
91 }
92 return subtable->GlyphOffset(glyph_id);
93 }
94
GlyphLength(int32_t glyph_id)95 int32_t BitmapSizeTable::GlyphLength(int32_t glyph_id) {
96 IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
97 if (subtable == NULL) {
98 return -1;
99 }
100 return subtable->GlyphLength(glyph_id);
101 }
102
GlyphInfo(int32_t glyph_id)103 CALLER_ATTACH BitmapGlyphInfo* BitmapSizeTable::GlyphInfo(int32_t glyph_id) {
104 IndexSubTable* sub_table = SearchIndexSubTables(glyph_id);
105 if (sub_table == NULL) {
106 return NULL;
107 }
108 return sub_table->GlyphInfo(glyph_id);
109 }
110
GlyphFormat(int32_t glyph_id)111 int32_t BitmapSizeTable::GlyphFormat(int32_t glyph_id) {
112 IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
113 if (subtable == NULL) {
114 return -1;
115 }
116 return subtable->image_format();
117 }
118
BitmapSizeTable(ReadableFontData * data,ReadableFontData * master_data)119 BitmapSizeTable::BitmapSizeTable(ReadableFontData* data,
120 ReadableFontData* master_data)
121 : SubTable(data, master_data) {
122 }
123
124 // static
NumberOfIndexSubTables(ReadableFontData * data,int32_t table_offset)125 int32_t BitmapSizeTable::NumberOfIndexSubTables(ReadableFontData* data,
126 int32_t table_offset) {
127 return data->ReadULongAsInt(table_offset +
128 EblcTable::Offset::kBitmapSizeTable_numberOfIndexSubTables);
129 }
130
SearchIndexSubTables(int32_t glyph_id)131 IndexSubTable* BitmapSizeTable::SearchIndexSubTables(int32_t glyph_id) {
132 // would be faster to binary search but too many size tables don't have
133 // sorted subtables
134 #if (SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH)
135 return BinarySearchIndexSubTables(glyph_id);
136 #else
137 return LinearSearchIndexSubTables(glyph_id);
138 #endif
139 }
140
LinearSearchIndexSubTables(int32_t glyph_id)141 IndexSubTable* BitmapSizeTable::LinearSearchIndexSubTables(int32_t glyph_id) {
142 IndexSubTableList* subtable_list = GetIndexSubTableList();
143 for (IndexSubTableList::iterator b = subtable_list->begin(),
144 e = subtable_list->end(); b != e; b++) {
145 if ((*b)->first_glyph_index() <= glyph_id &&
146 (*b)->last_glyph_index() >= glyph_id) {
147 return *b;
148 }
149 }
150 return NULL;
151 }
152
BinarySearchIndexSubTables(int32_t glyph_id)153 IndexSubTable* BitmapSizeTable::BinarySearchIndexSubTables(int32_t glyph_id) {
154 IndexSubTableList* subtable_list = GetIndexSubTableList();
155 int32_t index = 0;
156 int32_t bottom = 0;
157 int32_t top = subtable_list->size();
158 while (top != bottom) {
159 index = (top + bottom) / 2;
160 IndexSubTable* subtable = (*subtable_list)[index];
161 if (glyph_id < subtable->first_glyph_index()) {
162 // Location beow current location
163 top = index;
164 } else {
165 if (glyph_id <= subtable->last_glyph_index()) {
166 return subtable;
167 } else {
168 bottom = index + 1;
169 }
170 }
171 }
172 return NULL;
173 }
174
175 CALLER_ATTACH
CreateIndexSubTable(int32_t index)176 IndexSubTable* BitmapSizeTable::CreateIndexSubTable(int32_t index) {
177 return IndexSubTable::CreateIndexSubTable(master_read_data(),
178 IndexSubTableArrayOffset(),
179 index);
180 }
181
GetIndexSubTableList()182 IndexSubTableList* BitmapSizeTable::GetIndexSubTableList() {
183 AutoLock lock(index_subtables_lock_);
184 if (index_subtables_.empty()) {
185 for (int32_t i = 0; i < NumberOfIndexSubTables(); ++i) {
186 IndexSubTablePtr table;
187 table.Attach(CreateIndexSubTable(i));
188 index_subtables_.push_back(table);
189 }
190 }
191 return &index_subtables_;
192 }
193
194 /******************************************************************************
195 * BitmapSizeTable::Builder class
196 ******************************************************************************/
~Builder()197 BitmapSizeTable::Builder::~Builder() {
198 }
199
200 CALLER_ATTACH
SubBuildTable(ReadableFontData * data)201 FontDataTable* BitmapSizeTable::Builder::SubBuildTable(ReadableFontData* data) {
202 BitmapSizeTablePtr output = new BitmapSizeTable(data, master_read_data());
203 return output.Detach();
204 }
205
SubDataSet()206 void BitmapSizeTable::Builder::SubDataSet() {
207 Revert();
208 }
209
SubDataSizeToSerialize()210 int32_t BitmapSizeTable::Builder::SubDataSizeToSerialize() {
211 IndexSubTableBuilderList* builders = IndexSubTableBuilders();
212 if (builders->empty()) {
213 return 0;
214 }
215 int32_t size = EblcTable::Offset::kBitmapSizeTableLength;
216 bool variable = false;
217 for (IndexSubTableBuilderList::iterator b = builders->begin(),
218 e = builders->end(); b != e; b++) {
219 size += EblcTable::Offset::kIndexSubTableEntryLength;
220 int32_t sub_table_size = (*b)->SubDataSizeToSerialize();
221 int32_t padding = FontMath::PaddingRequired(abs(sub_table_size),
222 DataSize::kULONG);
223 #if defined (SFNTLY_DEBUG_BITMAP)
224 fprintf(stderr, "subtable size=%d\n", sub_table_size);
225 #endif
226 variable = (sub_table_size > 0) ? variable : true;
227 size += abs(sub_table_size) + padding;
228 }
229 #if defined (SFNTLY_DEBUG_BITMAP)
230 fprintf(stderr, "bitmap table size=%d\n", variable ? -size : size);
231 #endif
232 return variable ? -size : size;
233 }
234
SubReadyToSerialize()235 bool BitmapSizeTable::Builder::SubReadyToSerialize() {
236 if (IndexSubTableBuilders()->empty()) {
237 return false;
238 }
239 return true;
240 }
241
SubSerialize(WritableFontData * new_data)242 int32_t BitmapSizeTable::Builder::SubSerialize(WritableFontData* new_data) {
243 SetNumberOfIndexSubTables(IndexSubTableBuilders()->size());
244 int32_t size = InternalReadData()->CopyTo(new_data);
245 return size;
246 }
247
248 CALLER_ATTACH BitmapSizeTable::Builder*
CreateBuilder(WritableFontData * data,ReadableFontData * master_data)249 BitmapSizeTable::Builder::CreateBuilder(WritableFontData* data,
250 ReadableFontData* master_data) {
251 BitmapSizeTableBuilderPtr output =
252 new BitmapSizeTable::Builder(data, master_data);
253 return output.Detach();
254 }
255
256 CALLER_ATTACH BitmapSizeTable::Builder*
CreateBuilder(ReadableFontData * data,ReadableFontData * master_data)257 BitmapSizeTable::Builder::CreateBuilder(ReadableFontData* data,
258 ReadableFontData* master_data) {
259 BitmapSizeTableBuilderPtr output =
260 new BitmapSizeTable::Builder(data, master_data);
261 return output.Detach();
262 }
263
IndexSubTableArrayOffset()264 int32_t BitmapSizeTable::Builder::IndexSubTableArrayOffset() {
265 return InternalReadData()->ReadULongAsInt(
266 EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset);
267 }
268
SetIndexSubTableArrayOffset(int32_t offset)269 void BitmapSizeTable::Builder::SetIndexSubTableArrayOffset(int32_t offset) {
270 InternalWriteData()->WriteULong(
271 EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset, offset);
272 }
273
IndexTableSize()274 int32_t BitmapSizeTable::Builder::IndexTableSize() {
275 return InternalReadData()->ReadULongAsInt(
276 EblcTable::Offset::kBitmapSizeTable_indexTableSize);
277 }
278
SetIndexTableSize(int32_t size)279 void BitmapSizeTable::Builder::SetIndexTableSize(int32_t size) {
280 InternalWriteData()->WriteULong(
281 EblcTable::Offset::kBitmapSizeTable_indexTableSize, size);
282 }
283
NumberOfIndexSubTables()284 int32_t BitmapSizeTable::Builder::NumberOfIndexSubTables() {
285 return GetIndexSubTableBuilders()->size();
286 }
287
ColorRef()288 int32_t BitmapSizeTable::Builder::ColorRef() {
289 return InternalReadData()->ReadULongAsInt(
290 EblcTable::Offset::kBitmapSizeTable_colorRef);
291 }
292
StartGlyphIndex()293 int32_t BitmapSizeTable::Builder::StartGlyphIndex() {
294 return InternalReadData()->ReadUShort(
295 EblcTable::Offset::kBitmapSizeTable_startGlyphIndex);
296 }
297
EndGlyphIndex()298 int32_t BitmapSizeTable::Builder::EndGlyphIndex() {
299 return InternalReadData()->ReadUShort(
300 EblcTable::Offset::kBitmapSizeTable_endGlyphIndex);
301 }
302
PpemX()303 int32_t BitmapSizeTable::Builder::PpemX() {
304 return InternalReadData()->ReadByte(
305 EblcTable::Offset::kBitmapSizeTable_ppemX);
306 }
307
PpemY()308 int32_t BitmapSizeTable::Builder::PpemY() {
309 return InternalReadData()->ReadByte(
310 EblcTable::Offset::kBitmapSizeTable_ppemY);
311 }
312
BitDepth()313 int32_t BitmapSizeTable::Builder::BitDepth() {
314 return InternalReadData()->ReadByte(
315 EblcTable::Offset::kBitmapSizeTable_bitDepth);
316 }
317
FlagsAsInt()318 int32_t BitmapSizeTable::Builder::FlagsAsInt() {
319 return InternalReadData()->ReadChar(
320 EblcTable::Offset::kBitmapSizeTable_flags);
321 }
322
IndexSubTableBuilder(int32_t index)323 IndexSubTable::Builder* BitmapSizeTable::Builder::IndexSubTableBuilder(
324 int32_t index) {
325 IndexSubTableBuilderList* sub_table_list = GetIndexSubTableBuilders();
326 return sub_table_list->at(index);
327 }
328
GlyphInfo(int32_t glyph_id)329 CALLER_ATTACH BitmapGlyphInfo* BitmapSizeTable::Builder::GlyphInfo(
330 int32_t glyph_id) {
331 IndexSubTable::Builder* sub_table = SearchIndexSubTables(glyph_id);
332 if (sub_table == NULL) {
333 return NULL;
334 }
335 return sub_table->GlyphInfo(glyph_id);
336 }
337
GlyphOffset(int32_t glyph_id)338 int32_t BitmapSizeTable::Builder::GlyphOffset(int32_t glyph_id) {
339 IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
340 if (subtable == NULL) {
341 return -1;
342 }
343 return subtable->GlyphOffset(glyph_id);
344 }
345
GlyphLength(int32_t glyph_id)346 int32_t BitmapSizeTable::Builder::GlyphLength(int32_t glyph_id) {
347 IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
348 if (subtable == NULL) {
349 return -1;
350 }
351 return subtable->GlyphLength(glyph_id);
352 }
353
GlyphFormat(int32_t glyph_id)354 int32_t BitmapSizeTable::Builder::GlyphFormat(int32_t glyph_id) {
355 IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
356 if (subtable == NULL) {
357 return -1;
358 }
359 return subtable->image_format();
360 }
361
IndexSubTableBuilders()362 IndexSubTableBuilderList* BitmapSizeTable::Builder::IndexSubTableBuilders() {
363 return GetIndexSubTableBuilders();
364 }
365
366 CALLER_ATTACH BitmapSizeTable::Builder::BitmapGlyphInfoIterator*
GetIterator()367 BitmapSizeTable::Builder::GetIterator() {
368 Ptr<BitmapSizeTable::Builder::BitmapGlyphInfoIterator> output =
369 new BitmapSizeTable::Builder::BitmapGlyphInfoIterator(this);
370 return output.Detach();
371 }
372
GenerateLocaMap(BitmapGlyphInfoMap * output)373 void BitmapSizeTable::Builder::GenerateLocaMap(BitmapGlyphInfoMap* output) {
374 assert(output);
375 Ptr<BitmapSizeTable::Builder::BitmapGlyphInfoIterator> it;
376 it.Attach(GetIterator());
377 while (it->HasNext()) {
378 BitmapGlyphInfoPtr info;
379 info.Attach(it->Next());
380 (*output)[info->glyph_id()] = info;
381 }
382 }
383
Revert()384 void BitmapSizeTable::Builder::Revert() {
385 index_sub_tables_.clear();
386 set_model_changed(false);
387 }
388
Builder(WritableFontData * data,ReadableFontData * master_data)389 BitmapSizeTable::Builder::Builder(WritableFontData* data,
390 ReadableFontData* master_data)
391 : SubTable::Builder(data, master_data) {
392 }
393
Builder(ReadableFontData * data,ReadableFontData * master_data)394 BitmapSizeTable::Builder::Builder(ReadableFontData* data,
395 ReadableFontData* master_data)
396 : SubTable::Builder(data, master_data) {
397 }
398
SetNumberOfIndexSubTables(int32_t count)399 void BitmapSizeTable::Builder::SetNumberOfIndexSubTables(int32_t count) {
400 InternalWriteData()->WriteULong(
401 EblcTable::Offset::kBitmapSizeTable_numberOfIndexSubTables, count);
402 }
403
SearchIndexSubTables(int32_t glyph_id)404 IndexSubTable::Builder* BitmapSizeTable::Builder::SearchIndexSubTables(
405 int32_t glyph_id) {
406 // would be faster to binary search but too many size tables don't have
407 // sorted subtables
408 #if (SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH)
409 return BinarySearchIndexSubTables(glyph_id);
410 #else
411 return LinearSearchIndexSubTables(glyph_id);
412 #endif
413 }
414
LinearSearchIndexSubTables(int32_t glyph_id)415 IndexSubTable::Builder* BitmapSizeTable::Builder::LinearSearchIndexSubTables(
416 int32_t glyph_id) {
417 IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
418 for (IndexSubTableBuilderList::iterator b = subtable_list->begin(),
419 e = subtable_list->end();
420 b != e; b++) {
421 if ((*b)->first_glyph_index() <= glyph_id &&
422 (*b)->last_glyph_index() >= glyph_id) {
423 return *b;
424 }
425 }
426 return NULL;
427 }
428
BinarySearchIndexSubTables(int32_t glyph_id)429 IndexSubTable::Builder* BitmapSizeTable::Builder::BinarySearchIndexSubTables(
430 int32_t glyph_id) {
431 IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
432 int32_t index = 0;
433 int32_t bottom = 0;
434 int32_t top = subtable_list->size();
435 while (top != bottom) {
436 index = (top + bottom) / 2;
437 IndexSubTable::Builder* subtable = subtable_list->at(index);
438 if (glyph_id < subtable->first_glyph_index()) {
439 // Location beow current location
440 top = index;
441 } else {
442 if (glyph_id <= subtable->last_glyph_index()) {
443 return subtable;
444 } else {
445 bottom = index + 1;
446 }
447 }
448 }
449 return NULL;
450 }
451
GetIndexSubTableBuilders()452 IndexSubTableBuilderList* BitmapSizeTable::Builder::GetIndexSubTableBuilders() {
453 if (index_sub_tables_.empty()) {
454 Initialize(InternalReadData());
455 set_model_changed();
456 }
457 return &index_sub_tables_;
458 }
459
Initialize(ReadableFontData * data)460 void BitmapSizeTable::Builder::Initialize(ReadableFontData* data) {
461 index_sub_tables_.clear();
462 if (data) {
463 int32_t number_of_index_subtables =
464 BitmapSizeTable::NumberOfIndexSubTables(data, 0);
465 index_sub_tables_.resize(number_of_index_subtables);
466 for (int32_t i = 0; i < number_of_index_subtables; ++i) {
467 index_sub_tables_[i].Attach(CreateIndexSubTableBuilder(i));
468 }
469 }
470 }
471
472 CALLER_ATTACH IndexSubTable::Builder*
CreateIndexSubTableBuilder(int32_t index)473 BitmapSizeTable::Builder::CreateIndexSubTableBuilder(int32_t index) {
474 return IndexSubTable::Builder::CreateBuilder(master_read_data(),
475 IndexSubTableArrayOffset(),
476 index);
477 }
478
479 /******************************************************************************
480 * BitmapSizeTable::Builder::BitmapGlyphInfoIterator class
481 ******************************************************************************/
BitmapGlyphInfoIterator(BitmapSizeTable::Builder * container)482 BitmapSizeTable::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
483 BitmapSizeTable::Builder* container)
484 : RefIterator<BitmapGlyphInfo, BitmapSizeTable::Builder>(container) {
485 sub_table_iter_ = container->IndexSubTableBuilders()->begin();
486 sub_table_glyph_info_iter_.Attach((*sub_table_iter_)->GetIterator());
487 }
488
HasNext()489 bool BitmapSizeTable::Builder::BitmapGlyphInfoIterator::HasNext() {
490 if (sub_table_glyph_info_iter_ && HasNext(sub_table_glyph_info_iter_)) {
491 return true;
492 }
493 while (++sub_table_iter_ != container()->IndexSubTableBuilders()->end()) {
494 sub_table_glyph_info_iter_.Attach((*sub_table_iter_)->GetIterator());
495 if (HasNext(sub_table_glyph_info_iter_)) {
496 return true;
497 }
498 }
499 return false;
500 }
501
502 CALLER_ATTACH
Next()503 BitmapGlyphInfo* BitmapSizeTable::Builder::BitmapGlyphInfoIterator::Next() {
504 if (!HasNext()) {
505 // Note: In C++, we do not throw exception when there's no element.
506 return NULL;
507 }
508 return Next(sub_table_glyph_info_iter_);
509 }
510
HasNext(BitmapGlyphInfoIter * iterator_base)511 bool BitmapSizeTable::Builder::BitmapGlyphInfoIterator::HasNext(
512 BitmapGlyphInfoIter* iterator_base) {
513 if (iterator_base) {
514 switch (iterator_base->container_base()->index_format()) {
515 case 1: {
516 IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator* it =
517 down_cast<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*>(
518 iterator_base);
519 return it->HasNext();
520 }
521
522 case 2: {
523 IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator* it =
524 down_cast<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*>(
525 iterator_base);
526 return it->HasNext();
527 }
528
529 case 3: {
530 IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator* it =
531 down_cast<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*>(
532 iterator_base);
533 return it->HasNext();
534 }
535
536 case 4: {
537 IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator* it =
538 down_cast<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*>(
539 iterator_base);
540 return it->HasNext();
541 }
542
543 case 5: {
544 IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator* it =
545 down_cast<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*>(
546 iterator_base);
547 return it->HasNext();
548 }
549
550 default:
551 break;
552 }
553 }
554 return false;
555 }
556
557 CALLER_ATTACH
Next(BitmapGlyphInfoIter * iterator_base)558 BitmapGlyphInfo* BitmapSizeTable::Builder::BitmapGlyphInfoIterator::Next(
559 BitmapGlyphInfoIter* iterator_base) {
560 if (iterator_base) {
561 switch (iterator_base->container_base()->index_format()) {
562 case 1: {
563 IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator* it =
564 down_cast<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*>(
565 iterator_base);
566 return it->Next();
567 }
568
569 case 2: {
570 IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator* it =
571 down_cast<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*>(
572 iterator_base);
573 return it->Next();
574 }
575
576 case 3: {
577 IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator* it =
578 down_cast<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*>(
579 iterator_base);
580 return it->Next();
581 }
582
583 case 4: {
584 IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator* it =
585 down_cast<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*>(
586 iterator_base);
587 return it->Next();
588 }
589
590 case 5: {
591 IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator* it =
592 down_cast<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*>(
593 iterator_base);
594 return it->Next();
595 }
596
597 default:
598 break;
599 }
600 }
601 return NULL;
602 }
603
604 } // namespace sfntly
605