diff options
Diffstat (limited to 'sfntly/font_factory.cc')
-rw-r--r-- | sfntly/font_factory.cc | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/sfntly/font_factory.cc b/sfntly/font_factory.cc new file mode 100644 index 0000000..c162a77 --- /dev/null +++ b/sfntly/font_factory.cc @@ -0,0 +1,214 @@ +/* + * Copyright 2011 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sfntly/font_factory.h" + +#include <string.h> + +#include "sfntly/tag.h" + +namespace sfntly { + +FontFactory::~FontFactory() { +} + +CALLER_ATTACH FontFactory* FontFactory::GetInstance() { + FontFactoryPtr instance = new FontFactory(); + return instance.Detach(); +} + +void FontFactory::FingerprintFont(bool fingerprint) { + fingerprint_ = fingerprint; +} + +bool FontFactory::FingerprintFont() { + return fingerprint_; +} + +void FontFactory::LoadFonts(InputStream* is, FontArray* output) { + assert(output); + PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is); + if (IsCollection(pbis)) { + LoadCollection(pbis, output); + return; + } + FontPtr font; + font.Attach(LoadSingleOTF(pbis)); + if (font) { + output->push_back(font); + } +} + +void FontFactory::LoadFonts(ByteVector* b, FontArray* output) { + WritableFontDataPtr wfd; + wfd.Attach(WritableFontData::CreateWritableFontData(b)); + if (IsCollection(wfd)) { + LoadCollection(wfd, output); + return; + } + FontPtr font; + font.Attach(LoadSingleOTF(wfd)); + if (font) { + output->push_back(font); + } +} + +void FontFactory::LoadFontsForBuilding(InputStream* is, + FontBuilderArray* output) { + PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is); + if (IsCollection(pbis)) { + LoadCollectionForBuilding(pbis, output); + return; + } + FontBuilderPtr builder; + builder.Attach(LoadSingleOTFForBuilding(pbis)); + if (builder) { + output->push_back(builder); + } +} + +void FontFactory::LoadFontsForBuilding(ByteVector* b, + FontBuilderArray* output) { + WritableFontDataPtr wfd; + wfd.Attach(WritableFontData::CreateWritableFontData(b)); + if (IsCollection(wfd)) { + LoadCollectionForBuilding(wfd, output); + return; + } + FontBuilderPtr builder; + builder.Attach(LoadSingleOTFForBuilding(wfd, 0)); + if (builder) { + output->push_back(builder); + } +} + +void FontFactory::SerializeFont(Font* font, OutputStream* os) { + font->Serialize(os, &table_ordering_); +} + +void FontFactory::SetSerializationTableOrdering( + const IntegerList& table_ordering) { + table_ordering_ = table_ordering; +} + +CALLER_ATTACH Font::Builder* FontFactory::NewFontBuilder() { + return Font::Builder::GetOTFBuilder(this); +} + +CALLER_ATTACH Font* FontFactory::LoadSingleOTF(InputStream* is) { + FontBuilderPtr builder; + builder.Attach(LoadSingleOTFForBuilding(is)); + return builder->Build(); +} + +CALLER_ATTACH Font* FontFactory::LoadSingleOTF(WritableFontData* wfd) { + FontBuilderPtr builder; + builder.Attach(LoadSingleOTFForBuilding(wfd, 0)); + return builder->Build(); +} + +void FontFactory::LoadCollection(InputStream* is, FontArray* output) { + FontBuilderArray ba; + LoadCollectionForBuilding(is, &ba); + output->reserve(ba.size()); + for (FontBuilderArray::iterator builder = ba.begin(), builders_end = ba.end(); + builder != builders_end; ++builder) { + FontPtr font; + font.Attach((*builder)->Build()); + output->push_back(font); + } +} + +void FontFactory::LoadCollection(WritableFontData* wfd, FontArray* output) { + FontBuilderArray builders; + LoadCollectionForBuilding(wfd, &builders); + output->reserve(builders.size()); + for (FontBuilderArray::iterator builder = builders.begin(), + builders_end = builders.end(); + builder != builders_end; ++builder) { + FontPtr font; + font.Attach((*builder)->Build()); + output->push_back(font); + } +} + +CALLER_ATTACH +Font::Builder* FontFactory::LoadSingleOTFForBuilding(InputStream* is) { + // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream + Font::Builder* builder = Font::Builder::GetOTFBuilder(this, is); + // UNIMPLEMENTED: setDigest + return builder; +} + +CALLER_ATTACH Font::Builder* + FontFactory::LoadSingleOTFForBuilding(WritableFontData* wfd, + int32_t offset_to_offset_table) { + // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream + Font::Builder* builder = + Font::Builder::GetOTFBuilder(this, wfd, offset_to_offset_table); + // UNIMPLEMENTED: setDigest + return builder; +} + +void FontFactory::LoadCollectionForBuilding(InputStream* is, + FontBuilderArray* builders) { + assert(is); + assert(builders); + WritableFontDataPtr wfd; + wfd.Attach(WritableFontData::CreateWritableFontData(is->Available())); + wfd->CopyFrom(is); + LoadCollectionForBuilding(wfd, builders); +} + +void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd, + FontBuilderArray* builders) { + int32_t ttc_tag = wfd->ReadULongAsInt(Offset::kTTCTag); + UNREFERENCED_PARAMETER(ttc_tag); + int32_t version = wfd->ReadFixed(Offset::kVersion); + UNREFERENCED_PARAMETER(version); + int32_t num_fonts = wfd->ReadULongAsInt(Offset::kNumFonts); + + builders->reserve(num_fonts); + int32_t offset_table_offset = Offset::kOffsetTable; + for (int32_t font_number = 0; + font_number < num_fonts; + font_number++, offset_table_offset += DataSize::kULONG) { + int32_t offset = wfd->ReadULongAsInt(offset_table_offset); + FontBuilderPtr builder; + builder.Attach(LoadSingleOTFForBuilding(wfd, offset)); + builders->push_back(builder); + } +} + +bool FontFactory::IsCollection(PushbackInputStream* pbis) { + ByteVector tag(4); + pbis->Read(&tag); + pbis->Unread(&tag); + return Tag::ttcf == GenerateTag(tag[0], tag[1], tag[2], tag[3]); +} + +bool FontFactory::IsCollection(ReadableFontData* rfd) { + ByteVector tag(4); + rfd->ReadBytes(0, &(tag[0]), 0, tag.size()); + return Tag::ttcf == + GenerateTag(tag[0], tag[1], tag[2], tag[3]); +} + +FontFactory::FontFactory() + : fingerprint_(false) { +} + +} // namespace sfntly |