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_FORMAT4_H_
1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/bitmap/index_sub_table.h"
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly {
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass IndexSubTableFormat4 : public IndexSubTable,
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                             public RefCounted<IndexSubTableFormat4> {
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public:
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CodeOffsetPair {
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t glyph_code() const { return glyph_code_; }
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t offset() const { return offset_; }
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   protected:
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CodeOffsetPair(int32_t glyph_code, int32_t offset);
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // TODO(arthurhsu): C++ style guide prohibits protected members.
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t glyph_code_;
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t offset_;
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CodeOffsetPairBuilder : public CodeOffsetPair {
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CodeOffsetPairBuilder();
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CodeOffsetPairBuilder(int32_t glyph_code, int32_t offset);
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void set_glyph_code(int32_t v) { glyph_code_ = v; }
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void set_offset(int32_t v) { offset_ = v; }
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CodeOffsetPairGlyphCodeComparator {
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    bool operator()(const CodeOffsetPair& lhs, const CodeOffsetPair& rhs);
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class Builder : public IndexSubTable::Builder,
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                  public RefCounted<Builder> {
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    class BitmapGlyphInfoIterator
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     public:
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      explicit BitmapGlyphInfoIterator(Builder* container);
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual ~BitmapGlyphInfoIterator() {}
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual bool HasNext();
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CALLER_ATTACH virtual BitmapGlyphInfo* Next();
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     private:
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t code_offset_pair_index_;
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual ~Builder();
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t NumGlyphs();
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t GlyphLength(int32_t glyph_id);
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t GlyphStartOffset(int32_t glyph_id);
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual void SubDataSet();
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t SubDataSizeToSerialize();
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual bool SubReadyToSerialize();
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t SubSerialize(WritableFontData* new_data);
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void Revert();
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void SetOffsetArray(const std::vector<CodeOffsetPairBuilder>& pair_array);
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static CALLER_ATTACH Builder* CreateBuilder();
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t index_sub_table_offset,
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t first_glyph_index,
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t last_glyph_index);
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t index_sub_table_offset,
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t first_glyph_index,
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t last_glyph_index);
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   private:
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Builder();
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Builder(WritableFontData* data,
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t first_glyph_index,
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t last_glyph_index);
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Builder(ReadableFontData* data,
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t first_glyph_index,
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            int32_t last_glyph_index);
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    std::vector<CodeOffsetPairBuilder>* GetOffsetArray();
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void Initialize(ReadableFontData* data);
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t FindCodeOffsetPair(int32_t glyph_id);
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t DataLength(ReadableFontData* data,
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                              int32_t index_sub_table_offset,
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                              int32_t first_glyph_index,
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                              int32_t last_glyph_index);
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    std::vector<CodeOffsetPairBuilder> offset_pair_array_;
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual ~IndexSubTableFormat4();
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t NumGlyphs();
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t GlyphStartOffset(int32_t glyph_id);
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t GlyphLength(int32_t glyph_id);
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun private:
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  IndexSubTableFormat4(ReadableFontData* data,
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                       int32_t first_glyph_index,
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                       int32_t last_glyph_index);
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t FindCodeOffsetPair(int32_t glyph_id);
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static int32_t NumGlyphs(ReadableFontData* data, int32_t table_offset);
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  friend class Builder;
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef Ptr<IndexSubTableFormat4> IndexSubTableFormat4Ptr;
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef Ptr<IndexSubTableFormat4::Builder> IndexSubTableFormat4BuilderPtr;
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef std::vector<IndexSubTableFormat4::CodeOffsetPairBuilder>
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            CodeOffsetPairBuilderList;
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}  // namespace sfntly
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
136