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#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
18#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
19
20#include "sfntly/port/lock.h"
21#include "sfntly/table/bitmap/big_glyph_metrics.h"
22#include "sfntly/table/bitmap/bitmap_glyph.h"
23#include "sfntly/table/bitmap/bitmap_size_table.h"
24#include "sfntly/table/subtable_container_table.h"
25
26namespace sfntly {
27
28class EblcTable : public SubTableContainerTable,
29                  public RefCounted<EblcTable> {
30 public:
31  struct Offset {
32    enum {
33      // header
34      kVersion = 0,
35      kNumSizes = 4,
36      kHeaderLength = kNumSizes + DataSize::kULONG,
37
38      // bitmapSizeTable
39      kBitmapSizeTableArrayStart = kHeaderLength,
40      kBitmapSizeTableLength = 48,
41      kBitmapSizeTable_indexSubTableArrayOffset = 0,
42      kBitmapSizeTable_indexTableSize = 4,
43      kBitmapSizeTable_numberOfIndexSubTables = 8,
44      kBitmapSizeTable_colorRef = 12,
45      kBitmapSizeTable_hori = 16,
46      kBitmapSizeTable_vert = 28,
47      kBitmapSizeTable_startGlyphIndex = 40,
48      kBitmapSizeTable_endGlyphIndex = 42,
49      kBitmapSizeTable_ppemX = 44,
50      kBitmapSizeTable_ppemY = 45,
51      kBitmapSizeTable_bitDepth = 46,
52      kBitmapSizeTable_flags = 47,
53
54      // sbitLineMetrics
55      kSbitLineMetricsLength = 12,
56      kSbitLineMetrics_ascender = 0,
57      kSbitLineMetrics_descender = 1,
58      kSbitLineMetrics_widthMax = 2,
59      kSbitLineMetrics_caretSlopeNumerator = 3,
60      kSbitLineMetrics_caretSlopeDenominator = 4,
61      kSbitLineMetrics_caretOffset = 5,
62      kSbitLineMetrics_minOriginSB = 6,
63      kSbitLineMetrics_minAdvanceSB = 7,
64      kSbitLineMetrics_maxBeforeBL = 8,
65      kSbitLineMetrics_minAfterBL = 9,
66      kSbitLineMetrics_pad1 = 10,
67      kSbitLineMetrics_pad2 = 11,
68
69      // indexSubTable
70      kIndexSubTableEntryLength = 8,
71      kIndexSubTableEntry_firstGlyphIndex = 0,
72      kIndexSubTableEntry_lastGlyphIndex = 2,
73      kIndexSubTableEntry_additionalOffsetToIndexSubTable = 4,
74
75      // indexSubHeader
76      kIndexSubHeaderLength = 8,
77      kIndexSubHeader_indexFormat = 0,
78      kIndexSubHeader_imageFormat = 2,
79      kIndexSubHeader_imageDataOffset = 4,
80
81      // indexSubTable - all offset relative to the subtable start
82
83      // indexSubTable1
84      kIndexSubTable1_offsetArray = kIndexSubHeaderLength,
85      kIndexSubTable1_builderDataSize = kIndexSubHeaderLength,
86
87      // kIndexSubTable2
88      kIndexSubTable2Length = kIndexSubHeaderLength +
89                              DataSize::kULONG +
90                              BitmapGlyph::Offset::kBigGlyphMetricsLength,
91      kIndexSubTable2_imageSize = kIndexSubHeaderLength,
92      kIndexSubTable2_bigGlyphMetrics = kIndexSubTable2_imageSize +
93                                        DataSize::kULONG,
94      kIndexSubTable2_builderDataSize = kIndexSubTable2_bigGlyphMetrics +
95                                        BigGlyphMetrics::Offset::kMetricsLength,
96
97      // kIndexSubTable3
98      kIndexSubTable3_offsetArray = kIndexSubHeaderLength,
99      kIndexSubTable3_builderDataSize = kIndexSubTable3_offsetArray,
100
101      // kIndexSubTable4
102      kIndexSubTable4_numGlyphs = kIndexSubHeaderLength,
103      kIndexSubTable4_glyphArray = kIndexSubTable4_numGlyphs +
104                                   DataSize::kULONG,
105      kIndexSubTable4_codeOffsetPairLength = 2 * DataSize::kUSHORT,
106      kIndexSubTable4_codeOffsetPair_glyphCode = 0,
107      kIndexSubTable4_codeOffsetPair_offset = DataSize::kUSHORT,
108      kIndexSubTable4_builderDataSize = kIndexSubTable4_glyphArray,
109
110      // kIndexSubTable5
111      kIndexSubTable5_imageSize = kIndexSubHeaderLength,
112      kIndexSubTable5_bigGlyphMetrics = kIndexSubTable5_imageSize +
113                                        DataSize::kULONG,
114      kIndexSubTable5_numGlyphs = kIndexSubTable5_bigGlyphMetrics +
115                                  BitmapGlyph::Offset::kBigGlyphMetricsLength,
116      kIndexSubTable5_glyphArray = kIndexSubTable5_numGlyphs +
117                                   DataSize::kULONG,
118      kIndexSubTable5_builderDataSize = kIndexSubTable5_glyphArray,
119
120      // codeOffsetPair
121      kCodeOffsetPairLength = 2 * DataSize::kUSHORT,
122      kCodeOffsetPair_glyphCode = 0,
123      kCodeOffsetPair_offset = DataSize::kUSHORT,
124    };
125  };
126
127  class Builder : public SubTableContainerTable::Builder,
128                  public RefCounted<Builder> {
129   public:
130    // Constructor scope altered to public because C++ does not allow base
131    // class to instantiate derived class with protected constructors.
132    Builder(Header* header, WritableFontData* data);
133    Builder(Header* header, ReadableFontData* data);
134    virtual ~Builder();
135
136    virtual int32_t SubSerialize(WritableFontData* new_data);
137    virtual bool SubReadyToSerialize();
138    virtual int32_t SubDataSizeToSerialize();
139    virtual void SubDataSet();
140    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
141
142    BitmapSizeTableBuilderList* BitmapSizeBuilders();
143    void Revert();
144
145    // Generates the loca list for the EBDT table. The list is intended to be
146    // used by the EBDT to allow it to parse the glyph data and generate glyph
147    // objects. After returning from this method the list belongs to the caller.
148    // The list entries are in the same order as the size table builders are at
149    // the time of this call.
150    // @return the list of loca maps with one for each size table builder
151    void GenerateLocaList(BitmapLocaList* output);
152
153    // Create a new builder using the header information and data provided.
154    // @param header the header information
155    // @param data the data holding the table
156    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
157                                                WritableFontData* data);
158    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
159                                                ReadableFontData* data);
160
161   private:
162    BitmapSizeTableBuilderList* GetSizeList();
163    void Initialize(ReadableFontData* data, BitmapSizeTableBuilderList* output);
164
165    static const int32_t kVersion = 0x00020000;
166    BitmapSizeTableBuilderList size_table_builders_;
167  };
168
169  int32_t Version();
170  int32_t NumSizes();
171  // UNIMPLEMENTED: toString()
172
173  BitmapSizeTable* GetBitmapSizeTable(int32_t index);
174
175  static const int32_t NOTDEF = -1;
176
177 protected:
178  EblcTable(Header* header, ReadableFontData* data);
179
180 private:
181  BitmapSizeTableList* GetBitmapSizeTableList();
182
183  static void CreateBitmapSizeTable(ReadableFontData* data,
184                                    int32_t num_sizes,
185                                    BitmapSizeTableList* output);
186
187  Lock bitmap_size_table_lock_;
188  BitmapSizeTableList bitmap_size_table_;
189};
190typedef Ptr<EblcTable> EblcTablePtr;
191typedef Ptr<EblcTable::Builder> EblcTableBuilderPtr;
192}
193
194#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
195