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_format3.h"
18 :
19 : #include "sfntly/table/bitmap/eblc_table.h"
20 :
21 : namespace sfntly {
22 : /******************************************************************************
23 : * IndexSubTableFormat3 class
24 : ******************************************************************************/
25 0 : IndexSubTableFormat3::~IndexSubTableFormat3() {
26 0 : }
27 :
28 0 : int32_t IndexSubTableFormat3::NumGlyphs() {
29 0 : return last_glyph_index() - first_glyph_index() + 1;
30 : }
31 :
32 0 : int32_t IndexSubTableFormat3::GlyphStartOffset(int32_t glyph_id) {
33 0 : int32_t loca = CheckGlyphRange(glyph_id);
34 0 : if (loca != -1) {
35 0 : return Loca(loca);
36 : }
37 0 : return -1;
38 : }
39 :
40 0 : int32_t IndexSubTableFormat3::GlyphLength(int32_t glyph_id) {
41 0 : int32_t loca = CheckGlyphRange(glyph_id);
42 0 : if (loca != -1) {
43 0 : return Loca(glyph_id + 1) - Loca(glyph_id);
44 : }
45 0 : return 0;
46 : }
47 :
48 : // static
49 0 : int32_t IndexSubTableFormat3::GetDataLength(ReadableFontData* data,
50 : int32_t offset,
51 : int32_t first,
52 : int32_t last) {
53 : UNREFERENCED_PARAMETER(data);
54 : UNREFERENCED_PARAMETER(offset);
55 0 : return (last - first + 1 + 1) * DataSize::kUSHORT;
56 : }
57 :
58 0 : IndexSubTableFormat3::IndexSubTableFormat3(ReadableFontData* data,
59 : int32_t first_glyph_index,
60 0 : int32_t last_glyph_index)
61 0 : : IndexSubTable(data, first_glyph_index, last_glyph_index) {
62 0 : }
63 :
64 0 : int32_t IndexSubTableFormat3::Loca(int32_t loca) {
65 : int32_t read_offset =
66 0 : data_->ReadUShort(EblcTable::Offset::kIndexSubTable3_offsetArray +
67 0 : loca * DataSize::kUSHORT);
68 0 : return read_offset;
69 : }
70 :
71 : /******************************************************************************
72 : * IndexSubTableFormat3::Builder class
73 : ******************************************************************************/
74 0 : IndexSubTableFormat3::Builder::~Builder() {
75 0 : }
76 :
77 0 : int32_t IndexSubTableFormat3::Builder::NumGlyphs() {
78 0 : return GetOffsetArray()->size() - 1;
79 : }
80 :
81 0 : int32_t IndexSubTableFormat3::Builder::GlyphStartOffset(int32_t glyph_id) {
82 0 : int32_t loca = CheckGlyphRange(glyph_id);
83 0 : if (loca == -1) {
84 0 : return -1;
85 : }
86 0 : return GetOffsetArray()->at(loca);
87 : }
88 :
89 0 : int32_t IndexSubTableFormat3::Builder::GlyphLength(int32_t glyph_id) {
90 0 : int32_t loca = CheckGlyphRange(glyph_id);
91 0 : if (loca == -1) {
92 0 : return 0;
93 : }
94 0 : IntegerList* offset_array = GetOffsetArray();
95 0 : return offset_array->at(loca + 1) - offset_array->at(loca);
96 : }
97 :
98 : CALLER_ATTACH IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*
99 0 : IndexSubTableFormat3::Builder::GetIterator() {
100 : Ptr<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator> it =
101 0 : new IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator(this);
102 0 : return it.Detach();
103 : }
104 :
105 0 : void IndexSubTableFormat3::Builder::Revert() {
106 0 : offset_array_.clear();
107 0 : IndexSubTable::Builder::Revert();
108 0 : }
109 :
110 0 : void IndexSubTableFormat3::Builder::SetOffsetArray(
111 : const IntegerList& offset_array) {
112 0 : offset_array_.clear();
113 0 : offset_array_ = offset_array;
114 0 : set_model_changed();
115 0 : }
116 :
117 : // static
118 : CALLER_ATTACH IndexSubTableFormat3::Builder*
119 0 : IndexSubTableFormat3::Builder::CreateBuilder() {
120 0 : IndexSubTableFormat3BuilderPtr output = new IndexSubTableFormat3::Builder();
121 0 : return output.Detach();
122 : }
123 :
124 : // static
125 : CALLER_ATTACH IndexSubTableFormat3::Builder*
126 0 : IndexSubTableFormat3::Builder::CreateBuilder(ReadableFontData* data,
127 : int32_t index_sub_table_offset,
128 : int32_t first_glyph_index,
129 : int32_t last_glyph_index) {
130 : int32_t length = Builder::DataLength(data,
131 : index_sub_table_offset,
132 : first_glyph_index,
133 0 : last_glyph_index);
134 0 : ReadableFontDataPtr new_data;
135 0 : new_data.Attach(down_cast<ReadableFontData*>(
136 0 : data->Slice(index_sub_table_offset, length)));
137 0 : if (new_data == NULL) {
138 0 : return NULL;
139 : }
140 : IndexSubTableFormat3BuilderPtr output =
141 : new IndexSubTableFormat3::Builder(new_data,
142 : first_glyph_index,
143 0 : last_glyph_index);
144 0 : return output.Detach();
145 : }
146 :
147 : // static
148 : CALLER_ATTACH IndexSubTableFormat3::Builder*
149 0 : IndexSubTableFormat3::Builder::CreateBuilder(WritableFontData* data,
150 : int32_t index_sub_table_offset,
151 : int32_t first_glyph_index,
152 : int32_t last_glyph_index) {
153 : int32_t length = Builder::DataLength(data,
154 : index_sub_table_offset,
155 : first_glyph_index,
156 0 : last_glyph_index);
157 0 : WritableFontDataPtr new_data;
158 0 : new_data.Attach(down_cast<WritableFontData*>(
159 0 : data->Slice(index_sub_table_offset, length)));
160 : IndexSubTableFormat3BuilderPtr output =
161 : new IndexSubTableFormat3::Builder(new_data,
162 : first_glyph_index,
163 0 : last_glyph_index);
164 0 : return output.Detach();
165 : }
166 :
167 0 : CALLER_ATTACH FontDataTable* IndexSubTableFormat3::Builder::SubBuildTable(
168 : ReadableFontData* data) {
169 : IndexSubTableFormat3Ptr output = new IndexSubTableFormat3(
170 0 : data, first_glyph_index(), last_glyph_index());
171 0 : return output.Detach();
172 : }
173 :
174 0 : void IndexSubTableFormat3::Builder::SubDataSet() {
175 0 : Revert();
176 0 : }
177 :
178 0 : int32_t IndexSubTableFormat3::Builder::SubDataSizeToSerialize() {
179 0 : if (offset_array_.empty()) {
180 0 : return InternalReadData()->Length();
181 : }
182 : return EblcTable::Offset::kIndexSubHeaderLength +
183 0 : offset_array_.size() * DataSize::kULONG;
184 : }
185 :
186 0 : bool IndexSubTableFormat3::Builder::SubReadyToSerialize() {
187 0 : if (!offset_array_.empty()) {
188 0 : return true;
189 : }
190 0 : return false;
191 : }
192 :
193 0 : int32_t IndexSubTableFormat3::Builder::SubSerialize(
194 : WritableFontData* new_data) {
195 0 : int32_t size = SerializeIndexSubHeader(new_data);
196 0 : if (!model_changed()) {
197 0 : if (InternalReadData() == NULL) {
198 0 : return size;
199 : }
200 0 : ReadableFontDataPtr source;
201 0 : WritableFontDataPtr target;
202 0 : source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
203 0 : EblcTable::Offset::kIndexSubTable3_offsetArray)));
204 0 : target.Attach(down_cast<WritableFontData*>(new_data->Slice(
205 0 : EblcTable::Offset::kIndexSubTable3_offsetArray)));
206 0 : size += source->CopyTo(target);
207 : } else {
208 0 : for (IntegerList::iterator b = GetOffsetArray()->begin(),
209 0 : e = GetOffsetArray()->end(); b != e; b++) {
210 0 : size += new_data->WriteUShort(size, *b);
211 : }
212 : }
213 0 : return size;
214 : }
215 :
216 0 : IndexSubTableFormat3::Builder::Builder()
217 : : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable3_builderDataSize,
218 0 : IndexSubTable::Format::FORMAT_3) {
219 0 : }
220 :
221 0 : IndexSubTableFormat3::Builder::Builder(WritableFontData* data,
222 : int32_t first_glyph_index,
223 0 : int32_t last_glyph_index)
224 0 : : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
225 0 : }
226 :
227 0 : IndexSubTableFormat3::Builder::Builder(ReadableFontData* data,
228 : int32_t first_glyph_index,
229 0 : int32_t last_glyph_index)
230 0 : : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
231 0 : }
232 :
233 0 : IntegerList* IndexSubTableFormat3::Builder::GetOffsetArray() {
234 0 : if (offset_array_.empty()) {
235 0 : Initialize(InternalReadData());
236 0 : set_model_changed();
237 : }
238 0 : return &offset_array_;
239 : }
240 :
241 0 : void IndexSubTableFormat3::Builder::Initialize(ReadableFontData* data) {
242 0 : offset_array_.clear();
243 0 : if (data) {
244 0 : int32_t num_offsets = (last_glyph_index() - first_glyph_index() + 1) + 1;
245 0 : for (int32_t i = 0; i < num_offsets; ++i) {
246 0 : offset_array_.push_back(data->ReadUShort(
247 0 : EblcTable::Offset::kIndexSubTable3_offsetArray +
248 0 : i * DataSize::kUSHORT));
249 : }
250 : }
251 0 : }
252 :
253 : // static
254 0 : int32_t IndexSubTableFormat3::Builder::DataLength(
255 : ReadableFontData* data,
256 : int32_t index_sub_table_offset,
257 : int32_t first_glyph_index,
258 : int32_t last_glyph_index) {
259 : UNREFERENCED_PARAMETER(data);
260 : UNREFERENCED_PARAMETER(index_sub_table_offset);
261 0 : return EblcTable::Offset::kIndexSubHeaderLength +
262 0 : (last_glyph_index - first_glyph_index + 1 + 1) * DataSize::kUSHORT;
263 : }
264 :
265 : /******************************************************************************
266 : * IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator class
267 : ******************************************************************************/
268 0 : IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
269 0 : IndexSubTableFormat3::Builder* container)
270 : : RefIterator<BitmapGlyphInfo, IndexSubTableFormat3::Builder,
271 0 : IndexSubTable::Builder>(container) {
272 0 : glyph_id_ = container->first_glyph_index();
273 0 : }
274 :
275 0 : bool IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::HasNext() {
276 0 : if (glyph_id_ <= container()->last_glyph_index()) {
277 0 : return true;
278 : }
279 0 : return false;
280 : }
281 :
282 : CALLER_ATTACH BitmapGlyphInfo*
283 0 : IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::Next() {
284 0 : BitmapGlyphInfoPtr output;
285 0 : if (!HasNext()) {
286 : // Note: In C++, we do not throw exception when there's no element.
287 0 : return NULL;
288 : }
289 : output = new BitmapGlyphInfo(glyph_id_,
290 0 : container()->image_data_offset(),
291 0 : container()->GlyphStartOffset(glyph_id_),
292 0 : container()->GlyphLength(glyph_id_),
293 0 : container()->image_format());
294 0 : glyph_id_++;
295 0 : return output.Detach();
296 : }
297 :
298 : } // namespace sfntly
|