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#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <vector>
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/java_iterator.h"
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/subtable.h"
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/bitmap/bitmap_glyph_info.h"
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly {
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass IndexSubTable : public SubTable {
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public:
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  struct Format {
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    enum {
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      FORMAT_1 = 1,
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      FORMAT_2 = 2,
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      FORMAT_3 = 3,
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      FORMAT_4 = 4,
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      FORMAT_5 = 5,
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class Builder : public SubTable::Builder {
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual ~Builder();
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void Revert();
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t index_format() { return index_format_; }
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t first_glyph_index() { return first_glyph_index_; }
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void set_first_glyph_index(int32_t v) { first_glyph_index_ = v; }
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t last_glyph_index() { return last_glyph_index_; }
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void set_last_glyph_index(int32_t v) { last_glyph_index_ = v; }
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t image_format() { return image_format_; }
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void set_image_format(int32_t v) { image_format_ = v; }
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t image_data_offset() { return image_data_offset_; }
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void set_image_data_offset(int32_t v) { image_data_offset_ = v; }
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t NumGlyphs() = 0;
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Gets the glyph info for the specified glyph id.
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param glyphId the glyph id to look up
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the glyph info
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CALLER_ATTACH virtual BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Gets the full offset of the glyph within the EBDT table.
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param glyphId the glyph id
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the glyph offset
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t GlyphOffset(int32_t glyph_id);
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Gets the offset of the glyph relative to the block for this index
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // subtable.
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param glyphId the glyph id
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the glyph offset
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t GlyphStartOffset(int32_t glyph_id) = 0;
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Gets the length of the glyph within the EBDT table.
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param glyphId the glyph id
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the glyph offset
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t GlyphLength(int32_t glyph_id) = 0;
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Note: renamed from java iterator()
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CALLER_ATTACH virtual Iterator<BitmapGlyphInfo, IndexSubTable::Builder>*
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        GetIterator() = 0;
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Static instantiation function.
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static CALLER_ATTACH Builder* CreateBuilder(int32_t index_format);
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static CALLER_ATTACH Builder*
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        CreateBuilder(ReadableFontData* data,
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                      int32_t offset_to_index_sub_table_array,
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                      int32_t array_index);
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // The following methods will never be called but they need to be here to
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // allow the BitmapSizeTable to see these methods through an abstract
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // reference.
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual void SubDataSet();
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t SubDataSizeToSerialize();
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual bool SubReadyToSerialize();
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t SubSerialize(WritableFontData* new_data);
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   protected:
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Builder(int32_t data_size, int32_t index_format);
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Builder(int32_t index_format,
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t image_format,
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t image_data_offset,
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t data_size);
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Builder(WritableFontData* data,
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t first_glyph_index,
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t last_glyph_index);
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Builder(ReadableFontData* data,
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t first_glyph_index,
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t last_glyph_index);
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Checks that the glyph id is within the correct range. If it returns the
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // offset of the glyph id from the start of the range.
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param glyphId
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the offset of the glyphId from the start of the glyph range
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @throws IndexOutOfBoundsException if the glyph id is not within the
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    //         correct range
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t CheckGlyphRange(int32_t glyph_id);
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t SerializeIndexSubHeader(WritableFontData* data);
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   private:
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void Initialize(ReadableFontData* data);
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t first_glyph_index_;
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t last_glyph_index_;
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t index_format_;
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t image_format_;
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t image_data_offset_;
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t index_format() { return index_format_; }
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t first_glyph_index() { return first_glyph_index_; }
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t last_glyph_index() { return last_glyph_index_; }
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t image_format() { return image_format_; }
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t image_data_offset() { return image_data_offset_; }
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t GlyphOffset(int32_t glyph_id);
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t GlyphStartOffset(int32_t glyph_id) = 0;
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t GlyphLength(int32_t glyph_id) = 0;
14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t NumGlyphs() = 0;
14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static CALLER_ATTACH IndexSubTable*
14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CreateIndexSubTable(ReadableFontData* data,
14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                          int32_t offset_to_index_sub_table_array,
14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                          int32_t array_index);
14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun protected:
14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Note: the constructor does not implement offset/length form provided in
15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  //       Java to avoid heavy lifting in constructors.  Callers to call
15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  //       GetDataLength() static method of the derived class to get proper
15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  //       length and slice ahead.
15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  IndexSubTable(ReadableFontData* data,
15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                int32_t first_glyph_index,
15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                int32_t last_glyph_index);
15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t CheckGlyphRange(int32_t glyph_id);
15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static int32_t CheckGlyphRange(int32_t glyph_id,
15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                 int32_t first_glyph_id,
16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                 int32_t last_glyph_id);
16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun private:
16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t first_glyph_index_;
16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t last_glyph_index_;
16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t index_format_;
16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t image_format_;
16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t image_data_offset_;
16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef Ptr<IndexSubTable> IndexSubTablePtr;
17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef std::vector<IndexSubTablePtr> IndexSubTableList;
17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef Ptr<IndexSubTable::Builder> IndexSubTableBuilderPtr;
17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef std::vector<IndexSubTableBuilderPtr> IndexSubTableBuilderList;
17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef Iterator<BitmapGlyphInfo, IndexSubTable::Builder> BitmapGlyphInfoIter;
17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef Ptr<BitmapGlyphInfoIter> BitmapGlyphInfoIterPtr;
17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}  // namespace sfntly
17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
179