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/tools/subsetter/glyph_table_subsetter.h" 18 19#include "sfntly/table/truetype/glyph_table.h" 20#include "sfntly/table/truetype/loca_table.h" 21#include "sfntly/tag.h" 22#include "sfntly/tools/subsetter/subsetter.h" 23#include "sfntly/port/exception_type.h" 24 25namespace sfntly { 26 27const int32_t kGlyphTableSubsetterTags[2] = {Tag::glyf, Tag::loca}; 28 29GlyphTableSubsetter::GlyphTableSubsetter() 30 : TableSubsetterImpl(kGlyphTableSubsetterTags, 2) { 31} 32 33GlyphTableSubsetter::~GlyphTableSubsetter() {} 34 35bool GlyphTableSubsetter::Subset(Subsetter* subsetter, 36 Font* font, 37 Font::Builder* font_builder) { 38 assert(font); 39 assert(subsetter); 40 assert(font_builder); 41 42 IntegerList* permutation_table = subsetter->GlyphPermutationTable(); 43 if (!permutation_table || permutation_table->empty()) 44 return false; 45 46 GlyphTablePtr glyph_table = down_cast<GlyphTable*>(font->GetTable(Tag::glyf)); 47 LocaTablePtr loca_table = down_cast<LocaTable*>(font->GetTable(Tag::loca)); 48 if (glyph_table == NULL || loca_table == NULL) { 49#if !defined (SFNTLY_NO_EXCEPTION) 50 throw RuntimeException("Font to subset is not valid."); 51#endif 52 return false; 53 } 54 55 GlyphTableBuilderPtr glyph_table_builder = 56 down_cast<GlyphTable::Builder*> 57 (font_builder->NewTableBuilder(Tag::glyf)); 58 LocaTableBuilderPtr loca_table_builder = 59 down_cast<LocaTable::Builder*> 60 (font_builder->NewTableBuilder(Tag::loca)); 61 if (glyph_table_builder == NULL || loca_table_builder == NULL) { 62#if !defined (SFNTLY_NO_EXCEPTION) 63 throw RuntimeException("Builder for subset is not valid."); 64#endif 65 return false; 66 } 67 GlyphTable::GlyphBuilderList* glyph_builders = 68 glyph_table_builder->GlyphBuilders(); 69 for (IntegerList::iterator old_glyph_id = permutation_table->begin(), 70 old_glyph_id_end = permutation_table->end(); 71 old_glyph_id != old_glyph_id_end; ++old_glyph_id) { 72 int old_offset = loca_table->GlyphOffset(*old_glyph_id); 73 int old_length = loca_table->GlyphLength(*old_glyph_id); 74 GlyphPtr glyph; 75 glyph.Attach(glyph_table->GetGlyph(old_offset, old_length)); 76 ReadableFontDataPtr data = glyph->ReadFontData(); 77 WritableFontDataPtr copy_data; 78 copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length())); 79 data->CopyTo(copy_data); 80 GlyphBuilderPtr glyph_builder; 81 glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data)); 82 glyph_builders->push_back(glyph_builder); 83 } 84 IntegerList loca_list; 85 glyph_table_builder->GenerateLocaList(&loca_list); 86 loca_table_builder->SetLocaList(&loca_list); 87 return true; 88} 89 90} // namespace sfntly 91