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_FACTORY_H_
18#define SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_
19
20#include <vector>
21
22#include "sfntly/port/refcount.h"
23#include "sfntly/port/type.h"
24#include "sfntly/font.h"
25
26namespace sfntly {
27
28class FontFactory : public RefCounted<FontFactory> {
29 public:
30  virtual ~FontFactory();
31
32  // Factory method for the construction of a font factory.
33  static CALLER_ATTACH FontFactory* GetInstance();
34
35  // Toggle whether fonts that are loaded are fingerprinted with a SHA-1 hash.
36  // If a font is fingerprinted then a SHA-1 hash is generated at load time and
37  // stored in the font. This is useful for uniquely identifying fonts. By
38  // default this is turned on.
39  // @param fingerprint whether fingerprinting should be turned on or off
40  // TODO(arthurhsu): IMPLEMENT: C++ port currently don't do any SHA-1
41  void FingerprintFont(bool fingerprint);
42  bool FingerprintFont();
43
44  // Load the font(s) from the input stream. The current settings on the factory
45  // are used during the loading process. One or more fonts are returned if the
46  // stream contains valid font data. Some font container formats may have more
47  // than one font and in this case multiple font objects will be returned. If
48  // the data in the stream cannot be parsed or is invalid an array of size zero
49  // will be returned.
50  void LoadFonts(InputStream* is, FontArray* output);
51
52  // ByteArray font loading
53  // Load the font(s) from the byte array. The current settings on the factory
54  // are used during the loading process. One or more fonts are returned if the
55  // stream contains valid font data. Some font container formats may have more
56  // than one font and in this case multiple font objects will be returned. If
57  // the data in the stream cannot be parsed or is invalid an array of size zero
58  // will be returned.
59  void LoadFonts(ByteVector* b, FontArray* output);
60
61  // Load the font(s) from the input stream into font builders. The current
62  // settings on the factory are used during the loading process. One or more
63  // font builders are returned if the stream contains valid font data. Some
64  // font container formats may have more than one font and in this case
65  // multiple font builder objects will be returned. If the data in the stream
66  // cannot be parsed or is invalid an array of size zero will be returned.
67  void LoadFontsForBuilding(InputStream* is, FontBuilderArray* output);
68
69  // Load the font(s) from the byte array into font builders. The current
70  // settings on the factory are used during the loading process. One or more
71  // font builders are returned if the stream contains valid font data. Some
72  // font container formats may have more than one font and in this case
73  // multiple font builder objects will be returned. If the data in the stream
74  // cannot be parsed or is invalid an array of size zero will be returned.
75  void LoadFontsForBuilding(ByteVector* b, FontBuilderArray* output);
76
77  // Font serialization
78  // Serialize the font to the output stream.
79  // NOTE: in this port we attempted not to implement I/O stream because dealing
80  //       with cross-platform I/O stream itself is big enough as a project.
81  //       Byte buffer it is.
82  void SerializeFont(Font* font, OutputStream* os);
83
84  // Set the table ordering to be used in serializing a font. The table ordering
85  // is an ordered list of table ids and tables will be serialized in the order
86  // given. Any tables whose id is not listed in the ordering will be placed in
87  // an unspecified order following those listed.
88  void SetSerializationTableOrdering(const IntegerList& table_ordering);
89
90  // Get an empty font builder for creating a new font from scratch.
91  CALLER_ATTACH Font::Builder* NewFontBuilder();
92
93 private:
94  // Offsets to specific elements in the underlying data. These offsets are
95  // relative to the start of the table or the start of sub-blocks within the
96  // table.
97  struct Offset {
98    enum {
99      // Offsets within the main directory.
100      kTTCTag = 0,
101      kVersion = 4,
102      kNumFonts = 8,
103      kOffsetTable = 12,
104
105      // TTC Version 2.0 extensions.
106      // Offsets from end of OffsetTable.
107      kulDsigTag = 0,
108      kulDsigLength = 4,
109      kulDsigOffset = 8
110    };
111  };
112
113  FontFactory();
114
115  CALLER_ATTACH Font* LoadSingleOTF(InputStream* is);
116  CALLER_ATTACH Font* LoadSingleOTF(WritableFontData* wfd);
117
118  void LoadCollection(InputStream* is, FontArray* output);
119  void LoadCollection(WritableFontData* wfd, FontArray* output);
120
121  CALLER_ATTACH Font::Builder* LoadSingleOTFForBuilding(InputStream* is);
122  CALLER_ATTACH Font::Builder*
123      LoadSingleOTFForBuilding(WritableFontData* wfd,
124                               int32_t offset_to_offset_table);
125
126  void LoadCollectionForBuilding(InputStream* is, FontBuilderArray* builders);
127  void LoadCollectionForBuilding(WritableFontData* ba,
128                                 FontBuilderArray* builders);
129
130  static bool IsCollection(PushbackInputStream* pbis);
131  static bool IsCollection(ReadableFontData* wfd);
132
133  bool fingerprint_;
134  IntegerList table_ordering_;
135};
136typedef Ptr<FontFactory> FontFactoryPtr;
137
138}  // namespace sfntly
139
140#endif  // SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_
141