Home | History | Annotate | Download | only in sfntly
      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.
    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 };
    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