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
30namespace 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.
37struct 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.
50struct 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.
64struct 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.
80struct 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
120class 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.
124class 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.
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(ByteVector* 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.
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.
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    ByteVector digest_;
230  };
231
232  virtual ~Font();
233
234  // Gets the sfnt version set in the sfnt wrapper of the font.
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.
239  ByteVector* digest() { return &digest_; }
240
241  // Get the checksum for this font.
242  int64_t checksum() { return checksum_; }
243
244  // Get the number of tables in this font.
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);
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, IntegerList* 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, ByteVector* 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(IntegerList* 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(IntegerList* default_table_ordering,
334                             IntegerList* 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(IntegerList* default_table_ordering);
339
340  int32_t sfnt_version_;
341  ByteVector digest_;
342  int64_t checksum_;
343  TableMap tables_;
344};
345typedef Ptr<Font> FontPtr;
346typedef std::vector<FontPtr> FontArray;
347typedef Ptr<Font::Builder> FontBuilderPtr;
348typedef std::vector<FontBuilderPtr> FontBuilderArray;
349
350}  // namespace sfntly
351
352#endif  // SFNTLY_CPP_SRC_SFNTLY_FONT_H_
353