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