• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
~FontFactory()25 FontFactory::~FontFactory() {
26 }
27 
GetInstance()28 CALLER_ATTACH FontFactory* FontFactory::GetInstance() {
29   FontFactoryPtr instance = new FontFactory();
30   return instance.Detach();
31 }
32 
FingerprintFont(bool fingerprint)33 void FontFactory::FingerprintFont(bool fingerprint) {
34   fingerprint_ = fingerprint;
35 }
36 
FingerprintFont()37 bool FontFactory::FingerprintFont() {
38   return fingerprint_;
39 }
40 
LoadFonts(InputStream * is,FontArray * output)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 
LoadFonts(std::vector<uint8_t> * b,FontArray * output)55 void FontFactory::LoadFonts(std::vector<uint8_t>* 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 
LoadFontsForBuilding(InputStream * is,FontBuilderArray * output)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 
LoadFontsForBuilding(std::vector<uint8_t> * b,FontBuilderArray * output)83 void FontFactory::LoadFontsForBuilding(std::vector<uint8_t>* 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 
SerializeFont(Font * font,OutputStream * os)98 void FontFactory::SerializeFont(Font* font, OutputStream* os) {
99   std::vector<int32_t> table_ordering;
100   font->Serialize(os, &table_ordering);
101 }
102 
NewFontBuilder()103 CALLER_ATTACH Font::Builder* FontFactory::NewFontBuilder() {
104   return Font::Builder::GetOTFBuilder(this);
105 }
106 
LoadSingleOTF(InputStream * is)107 CALLER_ATTACH Font* FontFactory::LoadSingleOTF(InputStream* is) {
108   FontBuilderPtr builder;
109   builder.Attach(LoadSingleOTFForBuilding(is));
110   return builder->Build();
111 }
112 
LoadSingleOTF(WritableFontData * wfd)113 CALLER_ATTACH Font* FontFactory::LoadSingleOTF(WritableFontData* wfd) {
114   FontBuilderPtr builder;
115   builder.Attach(LoadSingleOTFForBuilding(wfd, 0));
116   return builder->Build();
117 }
118 
LoadCollection(InputStream * is,FontArray * output)119 void FontFactory::LoadCollection(InputStream* is, FontArray* output) {
120   FontBuilderArray ba;
121   LoadCollectionForBuilding(is, &ba);
122   output->reserve(ba.size());
123   for (FontBuilderArray::iterator builder = ba.begin(), builders_end = ba.end();
124                                   builder != builders_end; ++builder) {
125       FontPtr font;
126       font.Attach((*builder)->Build());
127       output->push_back(font);
128   }
129 }
130 
LoadCollection(WritableFontData * wfd,FontArray * output)131 void FontFactory::LoadCollection(WritableFontData* wfd, FontArray* output) {
132   FontBuilderArray builders;
133   LoadCollectionForBuilding(wfd, &builders);
134   output->reserve(builders.size());
135   for (FontBuilderArray::iterator builder = builders.begin(),
136                                   builders_end = builders.end();
137                                   builder != builders_end; ++builder) {
138     FontPtr font;
139     font.Attach((*builder)->Build());
140     output->push_back(font);
141   }
142 }
143 
144 CALLER_ATTACH
LoadSingleOTFForBuilding(InputStream * is)145 Font::Builder* FontFactory::LoadSingleOTFForBuilding(InputStream* is) {
146   // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream
147   Font::Builder* builder = Font::Builder::GetOTFBuilder(this, is);
148   // UNIMPLEMENTED: setDigest
149   return builder;
150 }
151 
152 CALLER_ATTACH Font::Builder*
LoadSingleOTFForBuilding(WritableFontData * wfd,int32_t offset_to_offset_table)153     FontFactory::LoadSingleOTFForBuilding(WritableFontData* wfd,
154                                           int32_t offset_to_offset_table) {
155   // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream
156   Font::Builder* builder =
157       Font::Builder::GetOTFBuilder(this, wfd, offset_to_offset_table);
158   // UNIMPLEMENTED: setDigest
159   return builder;
160 }
161 
LoadCollectionForBuilding(InputStream * is,FontBuilderArray * builders)162 void FontFactory::LoadCollectionForBuilding(InputStream* is,
163                                             FontBuilderArray* builders) {
164   assert(is);
165   assert(builders);
166   WritableFontDataPtr wfd;
167   wfd.Attach(WritableFontData::CreateWritableFontData(is->Available()));
168   wfd->CopyFrom(is);
169   LoadCollectionForBuilding(wfd, builders);
170 }
171 
LoadCollectionForBuilding(WritableFontData * wfd,FontBuilderArray * builders)172 void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd,
173                                             FontBuilderArray* builders) {
174   int32_t ttc_tag = wfd->ReadULongAsInt(Offset::kTTCTag);
175   UNREFERENCED_PARAMETER(ttc_tag);
176   int32_t version = wfd->ReadFixed(Offset::kVersion);
177   UNREFERENCED_PARAMETER(version);
178   int32_t num_fonts = wfd->ReadULongAsInt(Offset::kNumFonts);
179   if (num_fonts < 0)
180     return;
181   if (num_fonts > wfd->Length() / 4)
182     return;
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     if (offset < 0 || offset >= wfd->Length())
191       continue;
192 
193     FontBuilderPtr builder;
194     builder.Attach(LoadSingleOTFForBuilding(wfd, offset));
195     builders->push_back(builder);
196   }
197 }
198 
IsCollection(PushbackInputStream * pbis)199 bool FontFactory::IsCollection(PushbackInputStream* pbis) {
200   std::vector<uint8_t> tag(4);
201   pbis->Read(&tag);
202   pbis->Unread(&tag);
203   return Tag::ttcf == GenerateTag(tag[0], tag[1], tag[2], tag[3]);
204 }
205 
IsCollection(ReadableFontData * rfd)206 bool FontFactory::IsCollection(ReadableFontData* rfd) {
207   std::vector<uint8_t> tag(4);
208   rfd->ReadBytes(0, &(tag[0]), 0, tag.size());
209   return Tag::ttcf ==
210          GenerateTag(tag[0], tag[1], tag[2], tag[3]);
211 }
212 
FontFactory()213 FontFactory::FontFactory()
214     : fingerprint_(false) {
215 }
216 
217 }  // namespace sfntly
218