Line data Source code
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/index_sub_table.h"
18 :
19 : #include "sfntly/table/bitmap/eblc_table.h"
20 : #include "sfntly/table/bitmap/index_sub_table_format1.h"
21 : #include "sfntly/table/bitmap/index_sub_table_format2.h"
22 : #include "sfntly/table/bitmap/index_sub_table_format3.h"
23 : #include "sfntly/table/bitmap/index_sub_table_format4.h"
24 : #include "sfntly/table/bitmap/index_sub_table_format5.h"
25 :
26 : namespace sfntly {
27 : /******************************************************************************
28 : * IndexSubTable class
29 : ******************************************************************************/
30 0 : CALLER_ATTACH BitmapGlyphInfo* IndexSubTable::GlyphInfo(int32_t glyph_id) {
31 0 : int32_t loca = CheckGlyphRange(glyph_id);
32 0 : if (loca == -1) {
33 0 : return NULL;
34 : }
35 0 : if (GlyphStartOffset(glyph_id) == -1) {
36 0 : return NULL;
37 : }
38 : BitmapGlyphInfoPtr output = new BitmapGlyphInfo(glyph_id,
39 0 : image_data_offset(),
40 0 : GlyphStartOffset(glyph_id),
41 0 : GlyphLength(glyph_id),
42 0 : image_format());
43 0 : return output.Detach();
44 : }
45 :
46 0 : int32_t IndexSubTable::GlyphOffset(int32_t glyph_id) {
47 0 : int32_t glyph_start_offset = GlyphStartOffset(glyph_id);
48 0 : if (glyph_start_offset == -1) {
49 0 : return -1;
50 : }
51 0 : return image_data_offset() + glyph_start_offset;
52 : }
53 :
54 : // static
55 : CALLER_ATTACH IndexSubTable*
56 0 : IndexSubTable::CreateIndexSubTable(ReadableFontData* data,
57 : int32_t offset_to_index_sub_table_array,
58 : int32_t array_index) {
59 0 : IndexSubTableBuilderPtr builder;
60 0 : builder.Attach(IndexSubTable::Builder::CreateBuilder(
61 0 : data, offset_to_index_sub_table_array, array_index));
62 0 : return down_cast<IndexSubTable*>(builder->Build());
63 : }
64 :
65 0 : IndexSubTable::IndexSubTable(ReadableFontData* data,
66 : int32_t first_glyph_index,
67 0 : int32_t last_glyph_index)
68 : : SubTable(data),
69 : first_glyph_index_(first_glyph_index),
70 0 : last_glyph_index_(last_glyph_index) {
71 0 : index_format_ =
72 0 : data_->ReadUShort(EblcTable::Offset::kIndexSubHeader_indexFormat);
73 0 : image_format_ =
74 0 : data_->ReadUShort(EblcTable::Offset::kIndexSubHeader_imageFormat);
75 0 : image_data_offset_ =
76 0 : data_->ReadULongAsInt(EblcTable::Offset::kIndexSubHeader_imageDataOffset);
77 0 : }
78 :
79 0 : int32_t IndexSubTable::CheckGlyphRange(int32_t glyph_id) {
80 0 : return CheckGlyphRange(glyph_id, first_glyph_index(), last_glyph_index());
81 : }
82 :
83 : // static
84 0 : int32_t IndexSubTable::CheckGlyphRange(int32_t glyph_id,
85 : int32_t first_glyph_id,
86 : int32_t last_glyph_id) {
87 0 : if (glyph_id < first_glyph_id || glyph_id > last_glyph_id) {
88 : #if !defined (SFNTLY_NO_EXCEPTION)
89 : throw IndexOutOfBoundException("Glyph ID is outside of the allowed range.");
90 : #endif
91 0 : return -1;
92 : }
93 0 : return glyph_id - first_glyph_id;
94 : }
95 :
96 : /******************************************************************************
97 : * IndexSubTable::Builder class
98 : ******************************************************************************/
99 0 : IndexSubTable::Builder::~Builder() {
100 0 : }
101 :
102 0 : void IndexSubTable::Builder::Revert() {
103 0 : set_model_changed(false);
104 0 : Initialize(InternalReadData());
105 0 : }
106 :
107 0 : CALLER_ATTACH BitmapGlyphInfo* IndexSubTable::Builder::GlyphInfo(
108 : int32_t glyph_id) {
109 : BitmapGlyphInfoPtr glyph_info =
110 : new BitmapGlyphInfo(glyph_id,
111 0 : image_data_offset(),
112 0 : GlyphStartOffset(glyph_id),
113 0 : GlyphLength(glyph_id),
114 0 : image_format());
115 0 : return glyph_info.Detach();
116 : }
117 :
118 0 : int32_t IndexSubTable::Builder::GlyphOffset(int32_t glyph_id) {
119 0 : return image_data_offset() + GlyphStartOffset(glyph_id);
120 : }
121 :
122 : // static
123 : CALLER_ATTACH IndexSubTable::Builder*
124 0 : IndexSubTable::Builder::CreateBuilder(int32_t index_format) {
125 0 : switch (index_format) {
126 : case Format::FORMAT_1:
127 0 : return IndexSubTableFormat1::Builder::CreateBuilder();
128 : case Format::FORMAT_2:
129 0 : return IndexSubTableFormat2::Builder::CreateBuilder();
130 : case Format::FORMAT_3:
131 0 : return IndexSubTableFormat3::Builder::CreateBuilder();
132 : case Format::FORMAT_4:
133 0 : return IndexSubTableFormat4::Builder::CreateBuilder();
134 : case Format::FORMAT_5:
135 0 : return IndexSubTableFormat5::Builder::CreateBuilder();
136 : default:
137 : #if !defined (SFNTLY_NO_EXCEPTION)
138 : throw IllegalArgumentException("Invalid index subtable format");
139 : #endif
140 0 : return NULL;
141 : }
142 : }
143 :
144 : // static
145 : CALLER_ATTACH IndexSubTable::Builder*
146 0 : IndexSubTable::Builder::CreateBuilder(ReadableFontData* data,
147 : int32_t offset_to_index_sub_table_array, int32_t array_index) {
148 : int32_t index_sub_table_entry_offset =
149 : offset_to_index_sub_table_array +
150 0 : array_index * EblcTable::Offset::kIndexSubTableEntryLength;
151 : int32_t first_glyph_index =
152 : data->ReadUShort(index_sub_table_entry_offset +
153 0 : EblcTable::Offset::kIndexSubTableEntry_firstGlyphIndex);
154 : int32_t last_glyph_index =
155 0 : data->ReadUShort(index_sub_table_entry_offset +
156 0 : EblcTable::Offset::kIndexSubTableEntry_lastGlyphIndex);
157 0 : int32_t additional_offset_to_index_subtable = data->ReadULongAsInt(
158 : index_sub_table_entry_offset +
159 0 : EblcTable::Offset::kIndexSubTableEntry_additionalOffsetToIndexSubTable);
160 : int32_t index_sub_table_offset = offset_to_index_sub_table_array +
161 0 : additional_offset_to_index_subtable;
162 0 : int32_t index_format = data->ReadUShort(index_sub_table_offset);
163 0 : switch (index_format) {
164 : case 1:
165 : return IndexSubTableFormat1::Builder::CreateBuilder(
166 0 : data, index_sub_table_offset, first_glyph_index, last_glyph_index);
167 : case 2:
168 : return IndexSubTableFormat2::Builder::CreateBuilder(
169 0 : data, index_sub_table_offset, first_glyph_index, last_glyph_index);
170 : case 3:
171 : return IndexSubTableFormat3::Builder::CreateBuilder(
172 0 : data, index_sub_table_offset, first_glyph_index, last_glyph_index);
173 : case 4:
174 : return IndexSubTableFormat4::Builder::CreateBuilder(
175 0 : data, index_sub_table_offset, first_glyph_index, last_glyph_index);
176 : case 5:
177 : return IndexSubTableFormat5::Builder::CreateBuilder(
178 0 : data, index_sub_table_offset, first_glyph_index, last_glyph_index);
179 : default:
180 : // Unknown format and unable to process.
181 : #if !defined (SFNTLY_NO_EXCEPTION)
182 : throw IllegalArgumentException("Invalid Index Subtable Format");
183 : #endif
184 0 : break;
185 : }
186 0 : return NULL;
187 : }
188 :
189 : CALLER_ATTACH
190 0 : FontDataTable* IndexSubTable::Builder::SubBuildTable(ReadableFontData* data) {
191 : UNREFERENCED_PARAMETER(data);
192 0 : return NULL;
193 : }
194 :
195 0 : void IndexSubTable::Builder::SubDataSet() {
196 : // NOP
197 0 : }
198 :
199 0 : int32_t IndexSubTable::Builder::SubDataSizeToSerialize() {
200 0 : return 0;
201 : }
202 :
203 0 : bool IndexSubTable::Builder::SubReadyToSerialize() {
204 0 : return false;
205 : }
206 :
207 0 : int32_t IndexSubTable::Builder::SubSerialize(WritableFontData* new_data) {
208 : UNREFERENCED_PARAMETER(new_data);
209 0 : return 0;
210 : }
211 :
212 0 : IndexSubTable::Builder::Builder(int32_t data_size, int32_t index_format)
213 : : SubTable::Builder(data_size),
214 : first_glyph_index_(0),
215 : last_glyph_index_(0),
216 : index_format_(index_format),
217 : image_format_(0),
218 0 : image_data_offset_(0) {
219 0 : }
220 :
221 0 : IndexSubTable::Builder::Builder(int32_t index_format,
222 : int32_t image_format,
223 : int32_t image_data_offset,
224 0 : int32_t data_size)
225 : : SubTable::Builder(data_size),
226 : first_glyph_index_(0),
227 : last_glyph_index_(0),
228 : index_format_(index_format),
229 : image_format_(image_format),
230 0 : image_data_offset_(image_data_offset) {
231 0 : }
232 :
233 0 : IndexSubTable::Builder::Builder(WritableFontData* data,
234 : int32_t first_glyph_index,
235 0 : int32_t last_glyph_index)
236 : : SubTable::Builder(data),
237 : first_glyph_index_(first_glyph_index),
238 0 : last_glyph_index_(last_glyph_index) {
239 0 : Initialize(data);
240 0 : }
241 :
242 0 : IndexSubTable::Builder::Builder(ReadableFontData* data,
243 : int32_t first_glyph_index,
244 0 : int32_t last_glyph_index)
245 : : SubTable::Builder(data),
246 : first_glyph_index_(first_glyph_index),
247 0 : last_glyph_index_(last_glyph_index) {
248 0 : Initialize(data);
249 0 : }
250 :
251 0 : int32_t IndexSubTable::Builder::CheckGlyphRange(int32_t glyph_id) {
252 0 : return IndexSubTable::CheckGlyphRange(glyph_id,
253 : first_glyph_index(),
254 0 : last_glyph_index());
255 : }
256 :
257 0 : int32_t IndexSubTable::Builder::SerializeIndexSubHeader(
258 : WritableFontData* data) {
259 : int32_t size =
260 0 : data->WriteUShort(EblcTable::Offset::kIndexSubHeader_indexFormat,
261 0 : index_format());
262 0 : size += data->WriteUShort(EblcTable::Offset::kIndexSubHeader_imageFormat,
263 0 : image_format());
264 0 : size += data->WriteULong(EblcTable::Offset::kIndexSubHeader_imageDataOffset,
265 0 : image_data_offset());
266 0 : return size;
267 : }
268 :
269 0 : void IndexSubTable::Builder::Initialize(ReadableFontData* data) {
270 0 : index_format_ =
271 0 : data->ReadUShort(EblcTable::Offset::kIndexSubHeader_indexFormat);
272 0 : image_format_ =
273 0 : data->ReadUShort(EblcTable::Offset::kIndexSubHeader_imageFormat);
274 0 : image_data_offset_ =
275 0 : data->ReadULongAsInt(EblcTable::Offset::kIndexSubHeader_imageDataOffset);
276 0 : }
277 :
278 : } // namespace sfntly
|