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/font_factory.h" 18 19 #include <string.h> 20 21 #include "sfntly/tag.h" 22 23 namespace sfntly { 24 25 FontFactory::~FontFactory() { 26 } 27 28 CALLER_ATTACH FontFactory* FontFactory::GetInstance() { 29 FontFactoryPtr instance = new FontFactory(); 30 return instance.Detach(); 31 } 32 33 void FontFactory::FingerprintFont(bool fingerprint) { 34 fingerprint_ = fingerprint; 35 } 36 37 bool FontFactory::FingerprintFont() { 38 return fingerprint_; 39 } 40 41 void FontFactory::LoadFonts(InputStream* is, FontArray* output) { 42 assert(output); 43 PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is); 44 if (IsCollection(pbis)) { 45 LoadCollection(pbis, output); 46 return; 47 } 48 FontPtr font; 49 font.Attach(LoadSingleOTF(pbis)); 50 if (font) { 51 output->push_back(font); 52 } 53 } 54 55 void FontFactory::LoadFonts(ByteVector* b, FontArray* output) { 56 WritableFontDataPtr wfd; 57 wfd.Attach(WritableFontData::CreateWritableFontData(b)); 58 if (IsCollection(wfd)) { 59 LoadCollection(wfd, output); 60 return; 61 } 62 FontPtr font; 63 font.Attach(LoadSingleOTF(wfd)); 64 if (font) { 65 output->push_back(font); 66 } 67 } 68 69 void FontFactory::LoadFontsForBuilding(InputStream* is, 70 FontBuilderArray* output) { 71 PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is); 72 if (IsCollection(pbis)) { 73 LoadCollectionForBuilding(pbis, output); 74 return; 75 } 76 FontBuilderPtr builder; 77 builder.Attach(LoadSingleOTFForBuilding(pbis)); 78 if (builder) { 79 output->push_back(builder); 80 } 81 } 82 83 void FontFactory::LoadFontsForBuilding(ByteVector* b, 84 FontBuilderArray* output) { 85 WritableFontDataPtr wfd; 86 wfd.Attach(WritableFontData::CreateWritableFontData(b)); 87 if (IsCollection(wfd)) { 88 LoadCollectionForBuilding(wfd, output); 89 return; 90 } 91 FontBuilderPtr builder; 92 builder.Attach(LoadSingleOTFForBuilding(wfd, 0)); 93 if (builder) { 94 output->push_back(builder); 95 } 96 } 97 98 void FontFactory::SerializeFont(Font* font, OutputStream* os) { 99 font->Serialize(os, &table_ordering_); 100 } 101 102 void FontFactory::SetSerializationTableOrdering( 103 const IntegerList& table_ordering) { 104 table_ordering_ = table_ordering; 105 } 106 107 CALLER_ATTACH Font::Builder* FontFactory::NewFontBuilder() { 108 return Font::Builder::GetOTFBuilder(this); 109 } 110 111 CALLER_ATTACH Font* FontFactory::LoadSingleOTF(InputStream* is) { 112 FontBuilderPtr builder; 113 builder.Attach(LoadSingleOTFForBuilding(is)); 114 return builder->Build(); 115 } 116 117 CALLER_ATTACH Font* FontFactory::LoadSingleOTF(WritableFontData* wfd) { 118 FontBuilderPtr builder; 119 builder.Attach(LoadSingleOTFForBuilding(wfd, 0)); 120 return builder->Build(); 121 } 122 123 void FontFactory::LoadCollection(InputStream* is, FontArray* output) { 124 FontBuilderArray ba; 125 LoadCollectionForBuilding(is, &ba); 126 output->reserve(ba.size()); 127 for (FontBuilderArray::iterator builder = ba.begin(), builders_end = ba.end(); 128 builder != builders_end; ++builder) { 129 FontPtr font; 130 font.Attach((*builder)->Build()); 131 output->push_back(font); 132 } 133 } 134 135 void FontFactory::LoadCollection(WritableFontData* wfd, FontArray* output) { 136 FontBuilderArray builders; 137 LoadCollectionForBuilding(wfd, &builders); 138 output->reserve(builders.size()); 139 for (FontBuilderArray::iterator builder = builders.begin(), 140 builders_end = builders.end(); 141 builder != builders_end; ++builder) { 142 FontPtr font; 143 font.Attach((*builder)->Build()); 144 output->push_back(font); 145 } 146 } 147 148 CALLER_ATTACH 149 Font::Builder* FontFactory::LoadSingleOTFForBuilding(InputStream* is) { 150 // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream 151 Font::Builder* builder = Font::Builder::GetOTFBuilder(this, is); 152 // UNIMPLEMENTED: setDigest 153 return builder; 154 } 155 156 CALLER_ATTACH Font::Builder* 157 FontFactory::LoadSingleOTFForBuilding(WritableFontData* wfd, 158 int32_t offset_to_offset_table) { 159 // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream 160 Font::Builder* builder = 161 Font::Builder::GetOTFBuilder(this, wfd, offset_to_offset_table); 162 // UNIMPLEMENTED: setDigest 163 return builder; 164 } 165 166 void FontFactory::LoadCollectionForBuilding(InputStream* is, 167 FontBuilderArray* builders) { 168 assert(is); 169 assert(builders); 170 WritableFontDataPtr wfd; 171 wfd.Attach(WritableFontData::CreateWritableFontData(is->Available())); 172 wfd->CopyFrom(is); 173 LoadCollectionForBuilding(wfd, builders); 174 } 175 176 void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd, 177 FontBuilderArray* builders) { 178 int32_t ttc_tag = wfd->ReadULongAsInt(Offset::kTTCTag); 179 UNREFERENCED_PARAMETER(ttc_tag); 180 int32_t version = wfd->ReadFixed(Offset::kVersion); 181 UNREFERENCED_PARAMETER(version); 182 int32_t num_fonts = wfd->ReadULongAsInt(Offset::kNumFonts); 183 184 builders->reserve(num_fonts); 185 int32_t offset_table_offset = Offset::kOffsetTable; 186 for (int32_t font_number = 0; 187 font_number < num_fonts; 188 font_number++, offset_table_offset += DataSize::kULONG) { 189 int32_t offset = wfd->ReadULongAsInt(offset_table_offset); 190 FontBuilderPtr builder; 191 builder.Attach(LoadSingleOTFForBuilding(wfd, offset)); 192 builders->push_back(builder); 193 } 194 } 195 196 bool FontFactory::IsCollection(PushbackInputStream* pbis) { 197 ByteVector tag(4); 198 pbis->Read(&tag); 199 pbis->Unread(&tag); 200 return Tag::ttcf == GenerateTag(tag[0], tag[1], tag[2], tag[3]); 201 } 202 203 bool FontFactory::IsCollection(ReadableFontData* rfd) { 204 ByteVector tag(4); 205 rfd->ReadBytes(0, &(tag[0]), 0, tag.size()); 206 return Tag::ttcf == 207 GenerateTag(tag[0], tag[1], tag[2], tag[3]); 208 } 209 210 FontFactory::FontFactory() 211 : fingerprint_(false) { 212 } 213 214 } // namespace sfntly 215