• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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