OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. All Rights Reserved. | 2 * Copyright 2011 Google Inc. All Rights Reserved. |
3 * | 3 * |
4 * Licensed under the Apache License, Version 2.0 (the "License"); | 4 * Licensed under the Apache License, Version 2.0 (the "License"); |
5 * you may not use this file except in compliance with 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 | 6 * You may obtain a copy of the License at |
7 * | 7 * |
8 * http://www.apache.org/licenses/LICENSE-2.0 | 8 * http://www.apache.org/licenses/LICENSE-2.0 |
9 * | 9 * |
10 * Unless required by applicable law or agreed to in writing, software | 10 * Unless required by applicable law or agreed to in writing, software |
11 * distributed under the License is distributed on an "AS IS" BASIS, | 11 * distributed under the License is distributed on an "AS IS" BASIS, |
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 * See the License for the specific language governing permissions and | 13 * See the License for the specific language governing permissions and |
14 * limitations under the License. | 14 * limitations under the License. |
15 */ | 15 */ |
16 | 16 |
17 #include "third_party/sfntly/src/subsetter/subsetter_impl.h" | 17 #include "third_party/sfntly/src/subsetter/subsetter_impl.h" |
18 | 18 |
19 #include <string.h> | 19 #include <string.h> |
20 | 20 |
21 #include <map> | 21 #include <map> |
22 #include <set> | 22 #include <set> |
23 | 23 |
24 #include "third_party/sfntly/src/sfntly/glyph_table.h" | 24 #include "third_party/sfntly/src/sfntly/table/core/name_table.h" |
25 #include "third_party/sfntly/src/sfntly/loca_table.h" | 25 #include "third_party/sfntly/src/sfntly/table/truetype/glyph_table.h" |
26 #include "third_party/sfntly/src/sfntly/name_table.h" | 26 #include "third_party/sfntly/src/sfntly/table/truetype/loca_table.h" |
27 #include "third_party/sfntly/src/sfntly/tag.h" | 27 #include "third_party/sfntly/src/sfntly/tag.h" |
28 #include "third_party/sfntly/src/sfntly/data/memory_byte_array.h" | 28 #include "third_party/sfntly/src/sfntly/data/memory_byte_array.h" |
| 29 #include "third_party/sfntly/src/sfntly/port/memory_input_stream.h" |
29 #include "third_party/sfntly/src/sfntly/port/memory_output_stream.h" | 30 #include "third_party/sfntly/src/sfntly/port/memory_output_stream.h" |
30 | 31 |
31 namespace sfntly { | 32 namespace sfntly { |
32 | 33 |
33 void ConstructName(UChar* name_part, UnicodeString* name, int32_t name_id) { | 34 void ConstructName(UChar* name_part, UnicodeString* name, int32_t name_id) { |
34 switch(name_id) { | 35 switch(name_id) { |
35 case NameId::kFullFontName: | 36 case NameId::kFullFontName: |
36 *name = name_part; | 37 *name = name_part; |
37 break; | 38 break; |
38 case NameId::kFontFamilyName: | 39 case NameId::kFontFamilyName: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 | 73 |
73 SubsetterImpl::SubsetterImpl() { | 74 SubsetterImpl::SubsetterImpl() { |
74 } | 75 } |
75 | 76 |
76 SubsetterImpl::~SubsetterImpl() { | 77 SubsetterImpl::~SubsetterImpl() { |
77 } | 78 } |
78 | 79 |
79 bool SubsetterImpl::LoadFont(const char* font_name, | 80 bool SubsetterImpl::LoadFont(const char* font_name, |
80 const unsigned char* original_font, | 81 const unsigned char* original_font, |
81 size_t font_size) { | 82 size_t font_size) { |
82 ByteArrayPtr raw_font = | 83 MemoryInputStream mis; |
83 new MemoryByteArray((byte_t*)original_font, font_size); | 84 mis.Attach(original_font, font_size); |
84 if (factory_ == NULL) { | 85 if (factory_ == NULL) { |
85 factory_.Attach(FontFactory::GetInstance()); | 86 factory_.Attach(FontFactory::GetInstance()); |
86 } | 87 } |
87 | 88 |
88 FontArray font_array; | 89 FontArray font_array; |
89 factory_->LoadFonts(raw_font, &font_array); | 90 factory_->LoadFonts(&mis, &font_array); |
90 font_ = FindFont(font_name, font_array); | 91 font_ = FindFont(font_name, font_array); |
91 if (font_ == NULL) { | 92 if (font_ == NULL) { |
92 return false; | 93 return false; |
93 } | 94 } |
94 | 95 |
95 return true; | 96 return true; |
96 } | 97 } |
97 | 98 |
98 int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids, | 99 int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids, |
99 size_t glyph_count, | 100 size_t glyph_count, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 for (size_t i = 0; i < glyph_count; ++i) { | 215 for (size_t i = 0; i < glyph_count; ++i) { |
215 glyph_id_remaining.insert(glyph_ids[i]); | 216 glyph_id_remaining.insert(glyph_ids[i]); |
216 } | 217 } |
217 | 218 |
218 // Identify if any given glyph id maps to a composite glyph. If so, include | 219 // Identify if any given glyph id maps to a composite glyph. If so, include |
219 // the glyphs referenced by that composite glyph. | 220 // the glyphs referenced by that composite glyph. |
220 while (!glyph_id_remaining.empty()) { | 221 while (!glyph_id_remaining.empty()) { |
221 IntegerSet comp_glyph_id; | 222 IntegerSet comp_glyph_id; |
222 for (IntegerSet::iterator i = glyph_id_remaining.begin(), | 223 for (IntegerSet::iterator i = glyph_id_remaining.begin(), |
223 e = glyph_id_remaining.end(); i != e; ++i) { | 224 e = glyph_id_remaining.end(); i != e; ++i) { |
224 if (*i < 0 || *i >= loca_table->NumGlyphs()) { | 225 if (*i < 0 || *i >= loca_table->num_glyphs()) { |
225 // Invalid glyph id, ignore. | 226 // Invalid glyph id, ignore. |
226 continue; | 227 continue; |
227 } | 228 } |
228 | 229 |
229 int32_t length = loca_table->GlyphLength(*i); | 230 int32_t length = loca_table->GlyphLength(*i); |
230 if (length == 0) { | 231 if (length == 0) { |
231 // Empty glyph, ignore. | 232 // Empty glyph, ignore. |
232 continue; | 233 continue; |
233 } | 234 } |
234 int32_t offset = loca_table->GlyphOffset(*i); | 235 int32_t offset = loca_table->GlyphOffset(*i); |
(...skipping 30 matching lines...) Expand all Loading... |
265 CALLER_ATTACH Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids) { | 266 CALLER_ATTACH Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids) { |
266 // The tables are already checked in ResolveCompositeGlyphs(). | 267 // The tables are already checked in ResolveCompositeGlyphs(). |
267 GlyphTablePtr glyph_table = | 268 GlyphTablePtr glyph_table = |
268 down_cast<GlyphTable*>(font_->GetTable(Tag::glyf)); | 269 down_cast<GlyphTable*>(font_->GetTable(Tag::glyf)); |
269 LocaTablePtr loca_table = down_cast<LocaTable*>(font_->GetTable(Tag::loca)); | 270 LocaTablePtr loca_table = down_cast<LocaTable*>(font_->GetTable(Tag::loca)); |
270 | 271 |
271 // Setup font builders we need. | 272 // Setup font builders we need. |
272 FontBuilderPtr font_builder; | 273 FontBuilderPtr font_builder; |
273 font_builder.Attach(factory_->NewFontBuilder()); | 274 font_builder.Attach(factory_->NewFontBuilder()); |
274 | 275 |
275 GlyphTableBuilderPtr glyph_table_builder; | 276 GlyphTableBuilderPtr glyph_table_builder = |
276 glyph_table_builder.Attach(down_cast<GlyphTable::Builder*>( | 277 down_cast<GlyphTable::Builder*>(font_builder->NewTableBuilder(Tag::glyf)); |
277 font_builder->NewTableBuilder(Tag::glyf))); | 278 LocaTableBuilderPtr loca_table_builder = |
278 LocaTableBuilderPtr loca_table_builder; | 279 down_cast<LocaTable::Builder*>(font_builder->NewTableBuilder(Tag::loca)); |
279 loca_table_builder.Attach(down_cast<LocaTable::Builder*>( | |
280 font_builder->NewTableBuilder(Tag::loca))); | |
281 if (glyph_table_builder == NULL || loca_table_builder == NULL) { | 280 if (glyph_table_builder == NULL || loca_table_builder == NULL) { |
282 // Out of memory. | 281 // Out of memory. |
283 return NULL; | 282 return NULL; |
284 } | 283 } |
285 | 284 |
286 // Extract glyphs and setup loca list. | 285 // Extract glyphs and setup loca list. |
287 IntegerList loca_list; | 286 IntegerList loca_list; |
288 loca_list.resize(loca_table->NumGlyphs()); | 287 loca_list.resize(loca_table->num_glyphs()); |
289 loca_list.push_back(0); | 288 loca_list.push_back(0); |
290 int32_t last_glyph_id = 0; | 289 int32_t last_glyph_id = 0; |
291 int32_t last_offset = 0; | 290 int32_t last_offset = 0; |
292 GlyphTable::GlyphBuilderList* glyph_builders = | 291 GlyphTable::GlyphBuilderList* glyph_builders = |
293 glyph_table_builder->GlyphBuilders(); | 292 glyph_table_builder->GlyphBuilders(); |
294 for (IntegerSet::const_iterator i = glyph_ids.begin(), e = glyph_ids.end(); | 293 for (IntegerSet::const_iterator i = glyph_ids.begin(), e = glyph_ids.end(); |
295 i != e; ++i) { | 294 i != e; ++i) { |
296 int32_t length = loca_table->GlyphLength(*i); | 295 int32_t length = loca_table->GlyphLength(*i); |
297 int32_t offset = loca_table->GlyphOffset(*i); | 296 int32_t offset = loca_table->GlyphOffset(*i); |
298 | 297 |
299 GlyphPtr glyph; | 298 GlyphPtr glyph; |
300 glyph.Attach(glyph_table->GetGlyph(offset, length)); | 299 glyph.Attach(glyph_table->GetGlyph(offset, length)); |
301 | 300 |
302 // Add glyph to new glyf table. | 301 // Add glyph to new glyf table. |
303 ReadableFontDataPtr data = glyph->ReadFontData(); | 302 ReadableFontDataPtr data = glyph->ReadFontData(); |
304 WritableFontDataPtr copy_data; | 303 WritableFontDataPtr copy_data; |
305 copy_data.Attach(font_builder->GetNewData(data->Length())); | 304 copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length())); |
306 data->CopyTo(copy_data); | 305 data->CopyTo(copy_data); |
307 GlyphBuilderPtr glyph_builder; | 306 GlyphBuilderPtr glyph_builder; |
308 glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data)); | 307 glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data)); |
309 glyph_builders->push_back(glyph_builder); | 308 glyph_builders->push_back(glyph_builder); |
310 | 309 |
311 // Configure loca list. | 310 // Configure loca list. |
312 for (int32_t j = last_glyph_id + 1; j <= *i; ++j) { | 311 for (int32_t j = last_glyph_id + 1; j <= *i; ++j) { |
313 loca_list[j] = last_offset; | 312 loca_list[j] = last_offset; |
314 } | 313 } |
315 last_offset += length; | 314 last_offset += length; |
316 loca_list[*i + 1] = last_offset; | 315 loca_list[*i + 1] = last_offset; |
317 last_glyph_id = *i; | 316 last_glyph_id = *i; |
318 } | 317 } |
319 for (int32_t j = last_glyph_id + 1; j <= loca_table->NumGlyphs(); ++j) { | 318 for (int32_t j = last_glyph_id + 1; j <= loca_table->num_glyphs(); ++j) { |
320 loca_list[j] = last_offset; | 319 loca_list[j] = last_offset; |
321 } | 320 } |
322 loca_table_builder->SetLocaList(&loca_list); | 321 loca_table_builder->SetLocaList(&loca_list); |
323 | 322 |
324 // Setup remaining builders. | 323 // Setup remaining builders. |
325 for (TableMap::iterator i = font_->Tables()->begin(), | 324 for (TableMap::const_iterator i = font_->GetTableMap()->begin(), |
326 e = font_->Tables()->end(); i != e; ++i) { | 325 e = font_->GetTableMap()->end(); i != e; ++i) { |
327 // We already build the builder for glyph and loca. | 326 // We already build the builder for glyph and loca. |
328 if (i->first != Tag::glyf && i->first != Tag::loca) { | 327 if (i->first != Tag::glyf && i->first != Tag::loca) { |
329 // The newTableBuilder() call will alter internal state of font_builder | 328 font_builder->NewTableBuilder(i->first, i->second->ReadFontData()); |
330 // AND the reference count of returned object. Therefore we need to | |
331 // dereference it. | |
332 TableBuilderPtr dereference; | |
333 dereference.Attach( | |
334 font_builder->NewTableBuilder(i->first, i->second->ReadFontData())); | |
335 } | 329 } |
336 } | 330 } |
337 | 331 |
338 return font_builder->Build(); | 332 return font_builder->Build(); |
339 } | 333 } |
340 | 334 |
341 } // namespace sfntly | 335 } // namespace sfntly |
OLD | NEW |