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 #ifndef SFNTLY_CPP_SRC_SFNTLY_FONT_H_
18 #define SFNTLY_CPP_SRC_SFNTLY_FONT_H_
19 
20 #include <vector>
21 
22 #include "sfntly/port/refcount.h"
23 #include "sfntly/port/type.h"
24 #include "sfntly/port/endian.h"
25 #include "sfntly/data/font_input_stream.h"
26 #include "sfntly/data/font_output_stream.h"
27 #include "sfntly/data/writable_font_data.h"
28 #include "sfntly/table/table.h"
29 
30 namespace sfntly {
31 
32 // Note: following constants are embedded in Font class in Java.  They are
33 //       extracted out for easier reference from other classes.  Offset is the
34 //       one that is kept within class.
35 // Platform ids. These are used in a number of places within the font whenever
36 // the platform needs to be specified.
37 struct PlatformId {
38   enum {
39     kUnknown = -1,
40     kUnicode = 0,
41     kMacintosh = 1,
42     kISO = 2,
43     kWindows = 3,
44     kCustom = 4
45   };
46 };
47 
48 // Unicode encoding ids. These are used in a number of places within the font
49 // whenever character encodings need to be specified.
50 struct UnicodeEncodingId {
51   enum {
52     kUnknown = -1,
53     kUnicode1_0 = 0,
54     kUnicode1_1 = 1,
55     kISO10646 = 2,
56     kUnicode2_0_BMP = 3,
57     kUnicode2_0 = 4,
58     kUnicodeVariationSequences = 5
59   };
60 };
61 
62 // Windows encoding ids. These are used in a number of places within the font
63 // whenever character encodings need to be specified.
64 struct WindowsEncodingId {
65   enum {
66     kUnknown = 0xffffffff,
67     kSymbol = 0,
68     kUnicodeUCS2 = 1,
69     kShiftJIS = 2,
70     kPRC = 3,
71     kBig5 = 4,
72     kWansung = 5,
73     kJohab = 6,
74     kUnicodeUCS4 = 10
75   };
76 };
77 
78 // Macintosh encoding ids. These are used in a number of places within the
79 // font whenever character encodings need to be specified.
80 struct MacintoshEncodingId {
81   // Macintosh Platform Encodings
82   enum {
83     kUnknown = -1,
84     kRoman = 0,
85     kJapanese = 1,
86     kChineseTraditional = 2,
87     kKorean = 3,
88     kArabic = 4,
89     kHebrew = 5,
90     kGreek = 6,
91     kRussian = 7,
92     kRSymbol = 8,
93     kDevanagari = 9,
94     kGurmukhi = 10,
95     kGujarati = 11,
96     kOriya = 12,
97     kBengali = 13,
98     kTamil = 14,
99     kTelugu = 15,
100     kKannada = 16,
101     kMalayalam = 17,
102     kSinhalese = 18,
103     kBurmese = 19,
104     kKhmer = 20,
105     kThai = 21,
106     kLaotian = 22,
107     kGeorgian = 23,
108     kArmenian = 24,
109     kChineseSimplified = 25,
110     kTibetan = 26,
111     kMongolian = 27,
112     kGeez = 28,
113     kSlavic = 29,
114     kVietnamese = 30,
115     kSindhi = 31,
116     kUninterpreted = 32
117   };
118 };
119 
120 class FontFactory;
121 
122 // An sfnt container font object. This object is immutable and thread safe. To
123 // construct one use an instance of Font::Builder.
124 class Font : public RefCounted<Font> {
125  public:
126   // A builder for a font object. The builder allows the for the creation of
127   // immutable Font objects. The builder is a one use non-thread safe object and
128   // once the Font object has been created it is no longer usable. To create a
129   // further Font object new builder will be required.
130   class Builder : public RefCounted<Builder> {
131    public:
132     virtual ~Builder();
133 
134     static CALLER_ATTACH Builder*
135         GetOTFBuilder(FontFactory* factory, InputStream* is);
136     static CALLER_ATTACH Builder*
137         GetOTFBuilder(FontFactory* factory,
138                       WritableFontData* ba,
139                       int32_t offset_to_offset_table);
140     static CALLER_ATTACH Builder* GetOTFBuilder(FontFactory* factory);
141 
142     // Get the font factory that created this font builder.
GetFontFactory()143     FontFactory* GetFontFactory() { return factory_; }
144 
145     // Is the font ready to build?
146     bool ReadyToBuild();
147 
148     // Build the Font. After this call this builder will no longer be usable.
149     CALLER_ATTACH Font* Build();
150 
151     // Set a unique fingerprint for the font object.
152     void SetDigest(std::vector<uint8_t>* digest);
153 
154     // Clear all table builders.
155     void ClearTableBuilders();
156 
157     // Does this font builder have the specified table builder.
158     bool HasTableBuilder(int32_t tag);
159 
160     // Get the table builder for the given tag. If there is no builder for that
161     // tag then return a null.
162     Table::Builder* GetTableBuilder(int32_t tag);
163 
164     // Creates a new table builder for the table type given by the table id tag.
165     // This new table has been added to the font and will replace any existing
166     // builder for that table.
167     // @return new empty table of the type specified by tag; if tag is not known
168     //         then a generic OpenTypeTable is returned
169     virtual Table::Builder* NewTableBuilder(int32_t tag);
170 
171     // Creates a new table builder for the table type given by the table id tag.
172     // It makes a copy of the data provided and uses that copy for the table.
173     // This new table has been added to the font and will replace any existing
174     // builder for that table.
175     virtual Table::Builder* NewTableBuilder(int32_t tag,
176                                             ReadableFontData* src_data);
177 
178     // Get a map of the table builders in this font builder accessed by table
179     // tag.
table_builders()180     virtual TableBuilderMap* table_builders() { return &table_builders_; }
181 
182     // Remove the specified table builder from the font builder.
183     // Note: different from Java: we don't return object in removeTableBuilder
184     virtual void RemoveTableBuilder(int32_t tag);
185 
186     // Get the number of table builders in the font builder.
number_of_table_builders()187     virtual int32_t number_of_table_builders() {
188       return (int32_t)table_builders_.size();
189     }
190 
191    private:
192     explicit Builder(FontFactory* factory);
193     virtual void LoadFont(InputStream* is);
194     virtual void LoadFont(WritableFontData* wfd,
195                           int32_t offset_to_offset_table);
196     int32_t SfntWrapperSize();
197     void BuildAllTableBuilders(DataBlockMap* table_data,
198                                TableBuilderMap* builder_map);
199     CALLER_ATTACH Table::Builder*
200         GetTableBuilder(Header* header, WritableFontData* data);
201     void BuildTablesFromBuilders(Font* font,
202                                  TableBuilderMap* builder_map,
203                                  TableMap* tables);
204     static void InterRelateBuilders(TableBuilderMap* builder_map);
205 
206     void ReadHeader(FontInputStream* is,
207                     HeaderOffsetSortedSet* records);
208 
209     void ReadHeader(ReadableFontData* fd,
210                     int32_t offset,
211                     HeaderOffsetSortedSet* records);
212 
213     void LoadTableData(HeaderOffsetSortedSet* headers,
214                        FontInputStream* is,
215                        DataBlockMap* table_data);
216 
217     void LoadTableData(HeaderOffsetSortedSet* headers,
218                        WritableFontData* fd,
219                        DataBlockMap* table_data);
220 
221     TableBuilderMap table_builders_;
222     FontFactory* factory_;  // dumb pointer, avoid circular refcounting
223     int32_t sfnt_version_;
224     int32_t num_tables_;
225     int32_t search_range_;
226     int32_t entry_selector_;
227     int32_t range_shift_;
228     DataBlockMap data_blocks_;
229     std::vector<uint8_t> digest_;
230   };
231 
232   virtual ~Font();
233 
234   // Gets the sfnt version set in the sfnt wrapper of the font.
sfnt_version()235   int32_t sfnt_version() { return sfnt_version_; }
236 
237   // Gets a copy of the fonts digest that was created when the font was read. If
238   // no digest was set at creation time then the return result will be null.
digest()239   std::vector<uint8_t>* digest() { return &digest_; }
240 
241   // Get the checksum for this font.
checksum()242   int64_t checksum() { return checksum_; }
243 
244   // Get the number of tables in this font.
num_tables()245   int32_t num_tables() { return (int32_t)tables_.size(); }
246 
247   // Whether the font has a particular table.
248   bool HasTable(int32_t tag) const;
249 
250   // UNIMPLEMENTED: public Iterator<? extends Table> iterator
251 
252   // Get the table in this font with the specified id.
253   // @param tag the identifier of the table
254   // @return the table specified if it exists; null otherwise
255   // C++ port: rename table() to GetTable()
256   Table* GetTable(int32_t tag);
257 
258   // Get a map of the tables in this font accessed by table tag.
259   // @return an unmodifiable view of the tables in this font
260   // Note: renamed tableMap() to GetTableMap()
261   const TableMap* GetTableMap();
262 
263   // UNIMPLEMENTED: toString()
264 
265   // Serialize the font to the output stream.
266   // @param os the destination for the font serialization
267   // @param tableOrdering the table ordering to apply
268   void Serialize(OutputStream* os, std::vector<int32_t>* table_ordering);
269 
270  private:
271   // Offsets to specific elements in the underlying data. These offsets are
272   // relative to the start of the table or the start of sub-blocks within the
273   // table.
274   struct Offset {
275     enum {
276       // Offsets within the main directory
277       kSfntVersion = 0,
278       kNumTables = 4,
279       kSearchRange = 6,
280       kEntrySelector = 8,
281       kRangeShift = 10,
282       kTableRecordBegin = 12,
283       kSfntHeaderSize = 12,
284 
285       // Offsets within a specific table record
286       kTableTag = 0,
287       kTableCheckSum = 4,
288       kTableOffset = 8,
289       kTableLength = 12,
290       kTableRecordSize = 16
291     };
292   };
293 
294   // Note: the two constants are moved to tag.h to avoid VC++ bug.
295 //  static const int32_t CFF_TABLE_ORDERING[];
296 //  static const int32_t TRUE_TYPE_TABLE_ORDERING[];
297 
298   // Constructor.
299   // @param sfntVersion the sfnt version
300   // @param digest the computed digest for the font; null if digest was not
301   //        computed
302   // Note: Current C++ port does not support SHA digest validation.
303   Font(int32_t sfnt_version, std::vector<uint8_t>* digest);
304 
305   // Build the table headers to be used for serialization. These headers will be
306   // filled out with the data required for serialization. The headers will be
307   // sorted in the order specified and only those specified will have headers
308   // generated.
309   // @param tableOrdering the tables to generate headers for and the order to
310   //        sort them
311   // @return a list of table headers ready for serialization
312   void BuildTableHeadersForSerialization(std::vector<int32_t>* table_ordering,
313                                          TableHeaderList* table_headers);
314 
315   // Searialize the headers.
316   // @param fos the destination stream for the headers
317   // @param tableHeaders the headers to serialize
318   // @throws IOException
319   void SerializeHeader(FontOutputStream* fos, TableHeaderList* table_headers);
320 
321   // Serialize the tables.
322   // @param fos the destination stream for the headers
323   // @param tableHeaders the headers for the tables to serialize
324   // @throws IOException
325   void SerializeTables(FontOutputStream* fos, TableHeaderList* table_headers);
326 
327   // Generate the full table ordering to used for serialization. The full
328   // ordering uses the partial ordering as a seed and then adds all remaining
329   // tables in the font in an undefined order.
330   // @param defaultTableOrdering the partial ordering to be used as a seed for
331   //        the full ordering
332   // @param (out) table_ordering the full ordering for serialization
333   void GenerateTableOrdering(std::vector<int32_t>* default_table_ordering,
334                              std::vector<int32_t>* table_ordering);
335 
336   // Get the default table ordering based on the type of the font.
337   // @param (out) default_table_ordering the default table ordering
338   void DefaultTableOrdering(std::vector<int32_t>* default_table_ordering);
339 
340   int32_t sfnt_version_;
341   std::vector<uint8_t> digest_;
342   int64_t checksum_;
343   TableMap tables_;
344 };
345 typedef Ptr<Font> FontPtr;
346 typedef std::vector<FontPtr> FontArray;
347 typedef Ptr<Font::Builder> FontBuilderPtr;
348 typedef std::vector<FontBuilderPtr> FontBuilderArray;
349 
350 }  // namespace sfntly
351 
352 #endif  // SFNTLY_CPP_SRC_SFNTLY_FONT_H_
353