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