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 
26 namespace sfntly {
27 
28 class 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 };
190 typedef Ptr<EblcTable> EblcTablePtr;
191 typedef Ptr<EblcTable::Builder> EblcTableBuilderPtr;
192 }
193 
194 #endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
195