Home | History | Annotate | Download | only in core
      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_TABLE_CORE_NAME_TABLE_H_
     18 #define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
     19 
     20 // Must include this before ICU to avoid stdint redefinition issue.
     21 #include "sfntly/port/type.h"
     22 
     23 #include <unicode/ucnv.h>
     24 #include <unicode/ustring.h>
     25 
     26 #include <map>
     27 #include <utility>
     28 
     29 #include "sfntly/port/java_iterator.h"
     30 #include "sfntly/table/subtable_container_table.h"
     31 
     32 namespace sfntly {
     33 
     34 // The following code implements the name table defined in TTF/OTF spec, which
     35 // can be found at http://www.microsoft.com/typography/otspec/name.htm.
     36 
     37 // Name IDs defined in TTF/OTF spec.
     38 struct NameId {
     39   enum {
     40     kUnknown = -1,
     41     kCopyrightNotice = 0,
     42     kFontFamilyName = 1,
     43     kFontSubfamilyName = 2,
     44     kUniqueFontIdentifier = 3,
     45     kFullFontName = 4,
     46     kVersionString = 5,
     47     kPostscriptName = 6,
     48     kTrademark = 7,
     49     kManufacturerName = 8,
     50     kDesigner = 9,
     51     kDescription = 10,
     52     kVendorURL = 11,
     53     kDesignerURL = 12,
     54     kLicenseDescription = 13,
     55     kLicenseInfoURL = 14,
     56     kReserved15 = 15,
     57     kPreferredFamily = 16,
     58     kPreferredSubfamily = 17,
     59     kCompatibleFullName = 18,
     60     kSampleText = 19,
     61     kPostscriptCID = 20,
     62     kWWSFamilyName = 21,
     63     kWWSSubfamilyName = 22
     64   };
     65 };
     66 
     67 // Unicode language IDs used in Name Records.
     68 struct UnicodeLanguageId {
     69   enum {
     70     kUnknown = -1,
     71     kAll = 0
     72   };
     73 };
     74 
     75 // Macintosh Language IDs (platform ID = 1)
     76 struct MacintoshLanguageId {
     77   enum {
     78     kUnknown = -1,
     79     kEnglish = 0,
     80     kFrench = 1,
     81     kGerman = 2,
     82     kItalian = 3,
     83     kDutch = 4,
     84     kSwedish = 5,
     85     kSpanish = 6,
     86     kDanish = 7,
     87     kPortuguese = 8,
     88     kNorwegian = 9,
     89     kHebrew = 10,
     90     kJapanese = 11,
     91     kArabic = 12,
     92     kFinnish = 13,
     93     kGreek = 14,
     94     kIcelandic = 15,
     95     kMaltese = 16,
     96     kTurkish = 17,
     97     kCroatian = 18,
     98     kChinese_Traditional = 19,
     99     kUrdu = 20,
    100     kHindi = 21,
    101     kThai = 22,
    102     kKorean = 23,
    103     kLithuanian = 24,
    104     kPolish = 25,
    105     kHungarian = 26,
    106     kEstonian = 27,
    107     kLatvian = 28,
    108     kSami = 29,
    109     kFaroese = 30,
    110     kFarsiPersian = 31,
    111     kRussian = 32,
    112     kChinese_Simplified = 33,
    113     kFlemish = 34,
    114     kIrishGaelic = 35,
    115     kAlbanian = 36,
    116     kRomanian = 37,
    117     kCzech = 38,
    118     kSlovak = 39,
    119     kSlovenian = 40,
    120     kYiddish = 41,
    121     kSerbian = 42,
    122     kMacedonian = 43,
    123     kBulgarian = 44,
    124     kUkrainian = 45,
    125     kByelorussian = 46,
    126     kUzbek = 47,
    127     kKazakh = 48,
    128     kAzerbaijani_Cyrillic = 49,
    129     kAzerbaijani_Arabic = 50,
    130     kArmenian = 51,
    131     kGeorgian = 52,
    132     kMoldavian = 53,
    133     kKirghiz = 54,
    134     kTajiki = 55,
    135     kTurkmen = 56,
    136     kMongolian_Mongolian = 57,
    137     kMongolian_Cyrillic = 58,
    138     kPashto = 59,
    139     kKurdish = 60,
    140     kKashmiri = 61,
    141     kSindhi = 62,
    142     kTibetan = 63,
    143     kNepali = 64,
    144     kSanskrit = 65,
    145     kMarathi = 66,
    146     kBengali = 67,
    147     kAssamese = 68,
    148     kGujarati = 69,
    149     kPunjabi = 70,
    150     kOriya = 71,
    151     kMalayalam = 72,
    152     kKannada = 73,
    153     kTamil = 74,
    154     kTelugu = 75,
    155     kSinhalese = 76,
    156     kBurmese = 77,
    157     kKhmer = 78,
    158     kLao = 79,
    159     kVietnamese = 80,
    160     kIndonesian = 81,
    161     kTagalong = 82,
    162     kMalay_Roman = 83,
    163     kMalay_Arabic = 84,
    164     kAmharic = 85,
    165     kTigrinya = 86,
    166     kGalla = 87,
    167     kSomali = 88,
    168     kSwahili = 89,
    169     kKinyarwandaRuanda = 90,
    170     kRundi = 91,
    171     kNyanjaChewa = 92,
    172     kMalagasy = 93,
    173     kEsperanto = 94,
    174     kWelsh = 128,
    175     kBasque = 129,
    176     kCatalan = 130,
    177     kLatin = 131,
    178     kQuenchua = 132,
    179     kGuarani = 133,
    180     kAymara = 134,
    181     kTatar = 135,
    182     kUighur = 136,
    183     kDzongkha = 137,
    184     kJavanese_Roman = 138,
    185     kSundanese_Roman = 139,
    186     kGalician = 140,
    187     kAfrikaans = 141,
    188     kBreton = 142,
    189     kInuktitut = 143,
    190     kScottishGaelic = 144,
    191     kManxGaelic = 145,
    192     kIrishGaelic_WithDotAbove = 146,
    193     kTongan = 147,
    194     kGreek_Polytonic = 148,
    195     kGreenlandic = 149,
    196     kAzerbaijani_Roman = 150
    197   };
    198 };
    199 
    200 // Windows Language IDs (platformID = 3)
    201 struct WindowsLanguageId {
    202   enum {
    203     kUnknown = -1,
    204     kAfrikaans_SouthAfrica = 0x0436,
    205     kAlbanian_Albania = 0x041C,
    206     kAlsatian_France = 0x0484,
    207     kAmharic_Ethiopia = 0x045E,
    208     kArabic_Algeria = 0x1401,
    209     kArabic_Bahrain = 0x3C01,
    210     kArabic_Egypt = 0x0C01,
    211     kArabic_Iraq = 0x0801,
    212     kArabic_Jordan = 0x2C01,
    213     kArabic_Kuwait = 0x3401,
    214     kArabic_Lebanon = 0x3001,
    215     kArabic_Libya = 0x1001,
    216     kArabic_Morocco = 0x1801,
    217     kArabic_Oman = 0x2001,
    218     kArabic_Qatar = 0x4001,
    219     kArabic_SaudiArabia = 0x0401,
    220     kArabic_Syria = 0x2801,
    221     kArabic_Tunisia = 0x1C01,
    222     kArabic_UAE = 0x3801,
    223     kArabic_Yemen = 0x2401,
    224     kArmenian_Armenia = 0x042B,
    225     kAssamese_India = 0x044D,
    226     kAzeri_Cyrillic_Azerbaijan = 0x082C,
    227     kAzeri_Latin_Azerbaijan = 0x042C,
    228     kBashkir_Russia = 0x046D,
    229     kBasque_Basque = 0x042D,
    230     kBelarusian_Belarus = 0x0423,
    231     kBengali_Bangladesh = 0x0845,
    232     kBengali_India = 0x0445,
    233     kBosnian_Cyrillic_BosniaAndHerzegovina = 0x201A,
    234     kBosnian_Latin_BosniaAndHerzegovina = 0x141A,
    235     kBreton_France = 0x047E,
    236     kBulgarian_Bulgaria = 0x0402,
    237     kCatalan_Catalan = 0x0403,
    238     kChinese_HongKongSAR = 0x0C04,
    239     kChinese_MacaoSAR = 0x1404,
    240     kChinese_PeoplesRepublicOfChina = 0x0804,
    241     kChinese_Singapore = 0x1004,
    242     kChinese_Taiwan = 0x0404,
    243     kCorsican_France = 0x0483,
    244     kCroatian_Croatia = 0x041A,
    245     kCroatian_Latin_BosniaAndHerzegovina = 0x101A,
    246     kCzech_CzechRepublic = 0x0405,
    247     kDanish_Denmark = 0x0406,
    248     kDari_Afghanistan = 0x048C,
    249     kDivehi_Maldives = 0x0465,
    250     kDutch_Belgium = 0x0813,
    251     kDutch_Netherlands = 0x0413,
    252     kEnglish_Australia = 0x0C09,
    253     kEnglish_Belize = 0x2809,
    254     kEnglish_Canada = 0x1009,
    255     kEnglish_Caribbean = 0x2409,
    256     kEnglish_India = 0x4009,
    257     kEnglish_Ireland = 0x1809,
    258     kEnglish_Jamaica = 0x2009,
    259     kEnglish_Malaysia = 0x4409,
    260     kEnglish_NewZealand = 0x1409,
    261     kEnglish_RepublicOfThePhilippines = 0x3409,
    262     kEnglish_Singapore = 0x4809,
    263     kEnglish_SouthAfrica = 0x1C09,
    264     kEnglish_TrinidadAndTobago = 0x2C09,
    265     kEnglish_UnitedKingdom = 0x0809,
    266     kEnglish_UnitedStates = 0x0409,
    267     kEnglish_Zimbabwe = 0x3009,
    268     kEstonian_Estonia = 0x0425,
    269     kFaroese_FaroeIslands = 0x0438,
    270     kFilipino_Philippines = 0x0464,
    271     kFinnish_Finland = 0x040B,
    272     kFrench_Belgium = 0x080C,
    273     kFrench_Canada = 0x0C0C,
    274     kFrench_France = 0x040C,
    275     kFrench_Luxembourg = 0x140c,
    276     kFrench_PrincipalityOfMonoco = 0x180C,
    277     kFrench_Switzerland = 0x100C,
    278     kFrisian_Netherlands = 0x0462,
    279     kGalician_Galician = 0x0456,
    280     kGeorgian_Georgia = 0x0437,
    281     kGerman_Austria = 0x0C07,
    282     kGerman_Germany = 0x0407,
    283     kGerman_Liechtenstein = 0x1407,
    284     kGerman_Luxembourg = 0x1007,
    285     kGerman_Switzerland = 0x0807,
    286     kGreek_Greece = 0x0408,
    287     kGreenlandic_Greenland = 0x046F,
    288     kGujarati_India = 0x0447,
    289     kHausa_Latin_Nigeria = 0x0468,
    290     kHebrew_Israel = 0x040D,
    291     kHindi_India = 0x0439,
    292     kHungarian_Hungary = 0x040E,
    293     kIcelandic_Iceland = 0x040F,
    294     kIgbo_Nigeria = 0x0470,
    295     kIndonesian_Indonesia = 0x0421,
    296     kInuktitut_Canada = 0x045D,
    297     kInuktitut_Latin_Canada = 0x085D,
    298     kIrish_Ireland = 0x083C,
    299     kisiXhosa_SouthAfrica = 0x0434,
    300     kisiZulu_SouthAfrica = 0x0435,
    301     kItalian_Italy = 0x0410,
    302     kItalian_Switzerland = 0x0810,
    303     kJapanese_Japan = 0x0411,
    304     kKannada_India = 0x044B,
    305     kKazakh_Kazakhstan = 0x043F,
    306     kKhmer_Cambodia = 0x0453,
    307     kKiche_Guatemala = 0x0486,
    308     kKinyarwanda_Rwanda = 0x0487,
    309     kKiswahili_Kenya = 0x0441,
    310     kKonkani_India = 0x0457,
    311     kKorean_Korea = 0x0412,
    312     kKyrgyz_Kyrgyzstan = 0x0440,
    313     kLao_LaoPDR = 0x0454,
    314     kLatvian_Latvia = 0x0426,
    315     kLithuanian_Lithuania = 0x0427,
    316     kLowerSorbian_Germany = 0x082E,
    317     kLuxembourgish_Luxembourg = 0x046E,
    318     kMacedonian_FYROM_FormerYugoslavRepublicOfMacedonia = 0x042F,
    319     kMalay_BruneiDarussalam = 0x083E,
    320     kMalay_Malaysia = 0x043E,
    321     kMalayalam_India = 0x044C,
    322     kMaltese_Malta = 0x043A,
    323     kMaori_NewZealand = 0x0481,
    324     kMapudungun_Chile = 0x047A,
    325     kMarathi_India = 0x044E,
    326     kMohawk_Mohawk = 0x047C,
    327     kMongolian_Cyrillic_Mongolia = 0x0450,
    328     kMongolian_Traditional_PeoplesRepublicOfChina = 0x0850,
    329     kNepali_Nepal = 0x0461,
    330     kNorwegian_Bokmal_Norway = 0x0414,
    331     kNorwegian_Nynorsk_Norway = 0x0814,
    332     kOccitan_France = 0x0482,
    333     kOriya_India = 0x0448,
    334     kPashto_Afghanistan = 0x0463,
    335     kPolish_Poland = 0x0415,
    336     kPortuguese_Brazil = 0x0416,
    337     kPortuguese_Portugal = 0x0816,
    338     kPunjabi_India = 0x0446,
    339     kQuechua_Bolivia = 0x046B,
    340     kQuechua_Ecuador = 0x086B,
    341     kQuechua_Peru = 0x0C6B,
    342     kRomanian_Romania = 0x0418,
    343     kRomansh_Switzerland = 0x0417,
    344     kRussian_Russia = 0x0419,
    345     kSami_Inari_Finland = 0x243B,
    346     kSami_Lule_Norway = 0x103B,
    347     kSami_Lule_Sweden = 0x143B,
    348     kSami_Northern_Finland = 0x0C3B,
    349     kSami_Northern_Norway = 0x043B,
    350     kSami_Northern_Sweden = 0x083B,
    351     kSami_Skolt_Finland = 0x203B,
    352     kSami_Southern_Norway = 0x183B,
    353     kSami_Southern_Sweden = 0x1C3B,
    354     kSanskrit_India = 0x044F,
    355     kSerbian_Cyrillic_BosniaAndHerzegovina = 0x1C1A,
    356     kSerbian_Cyrillic_Serbia = 0x0C1A,
    357     kSerbian_Latin_BosniaAndHerzegovina = 0x181A,
    358     kSerbian_Latin_Serbia = 0x081A,
    359     kSesothoSaLeboa_SouthAfrica = 0x046C,
    360     kSetswana_SouthAfrica = 0x0432,
    361     kSinhala_SriLanka = 0x045B,
    362     kSlovak_Slovakia = 0x041B,
    363     kSlovenian_Slovenia = 0x0424,
    364     kSpanish_Argentina = 0x2C0A,
    365     kSpanish_Bolivia = 0x400A,
    366     kSpanish_Chile = 0x340A,
    367     kSpanish_Colombia = 0x240A,
    368     kSpanish_CostaRica = 0x140A,
    369     kSpanish_DominicanRepublic = 0x1C0A,
    370     kSpanish_Ecuador = 0x300A,
    371     kSpanish_ElSalvador = 0x440A,
    372     kSpanish_Guatemala = 0x100A,
    373     kSpanish_Honduras = 0x480A,
    374     kSpanish_Mexico = 0x080A,
    375     kSpanish_Nicaragua = 0x4C0A,
    376     kSpanish_Panama = 0x180A,
    377     kSpanish_Paraguay = 0x3C0A,
    378     kSpanish_Peru = 0x280A,
    379     kSpanish_PuertoRico = 0x500A,
    380     kSpanish_ModernSort_Spain = 0x0C0A,
    381     kSpanish_TraditionalSort_Spain = 0x040A,
    382     kSpanish_UnitedStates = 0x540A,
    383     kSpanish_Uruguay = 0x380A,
    384     kSpanish_Venezuela = 0x200A,
    385     kSweden_Finland = 0x081D,
    386     kSwedish_Sweden = 0x041D,
    387     kSyriac_Syria = 0x045A,
    388     kTajik_Cyrillic_Tajikistan = 0x0428,
    389     kTamazight_Latin_Algeria = 0x085F,
    390     kTamil_India = 0x0449,
    391     kTatar_Russia = 0x0444,
    392     kTelugu_India = 0x044A,
    393     kThai_Thailand = 0x041E,
    394     kTibetan_PRC = 0x0451,
    395     kTurkish_Turkey = 0x041F,
    396     kTurkmen_Turkmenistan = 0x0442,
    397     kUighur_PRC = 0x0480,
    398     kUkrainian_Ukraine = 0x0422,
    399     kUpperSorbian_Germany = 0x042E,
    400     kUrdu_IslamicRepublicOfPakistan = 0x0420,
    401     kUzbek_Cyrillic_Uzbekistan = 0x0843,
    402     kUzbek_Latin_Uzbekistan = 0x0443,
    403     kVietnamese_Vietnam = 0x042A,
    404     kWelsh_UnitedKingdom = 0x0452,
    405     kWolof_Senegal = 0x0448,
    406     kYakut_Russia = 0x0485,
    407     kYi_PRC = 0x0478,
    408     kYoruba_Nigeria = 0x046A
    409   };
    410 };
    411 
    412 class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
    413  public:
    414   // Unique identifier for a given name record.
    415   class NameEntryId {
    416    public:
    417     NameEntryId();  // C++ port only, must provide default constructor.
    418     NameEntryId(int32_t platform_id, int32_t encoding_id, int32_t language_id,
    419                 int32_t name_id);
    420     NameEntryId(const NameEntryId&);
    421     // Make gcc -Wnon-virtual-dtor happy.
    422     virtual ~NameEntryId() {}
    423 
    424     int32_t platform_id() const { return platform_id_; }
    425     int32_t encoding_id() const { return encoding_id_; }
    426     int32_t language_id() const { return language_id_; }
    427     int32_t name_id() const { return name_id_; }
    428 
    429     const NameEntryId& operator=(const NameEntryId& rhs) const;
    430     bool operator==(const NameEntryId& rhs) const;
    431     bool operator<(const NameEntryId& rhs) const;
    432 
    433     // UNIMPLEMENTED: int hashCode()
    434     //                String toString()
    435 
    436    private:
    437     mutable int32_t platform_id_;
    438     mutable int32_t encoding_id_;
    439     mutable int32_t language_id_;
    440     mutable int32_t name_id_;
    441   };
    442 
    443   class NameEntryBuilder;
    444 
    445   // Class to represent a name entry in the name table.
    446   class NameEntry : public RefCounted<NameEntry> {
    447    public:
    448     NameEntry();
    449     NameEntry(const NameEntryId& name_entry_id, const ByteVector& name_bytes);
    450     NameEntry(int32_t platform_id,
    451               int32_t encoding_id,
    452               int32_t language_id,
    453               int32_t name_id,
    454               const ByteVector& name_bytes);
    455     virtual ~NameEntry();
    456 
    457     NameEntryId& name_entry_id() { return name_entry_id_; }
    458     int32_t platform_id() const { return name_entry_id_.platform_id(); }
    459     int32_t encoding_id() const { return name_entry_id_.encoding_id(); }
    460     int32_t language_id() const { return name_entry_id_.language_id(); }
    461     int32_t name_id() const { return name_entry_id_.name_id(); }
    462 
    463     // Get the bytes for name.  Returned pointer is the address of private
    464     // member of this class, do not attempt to delete.
    465     ByteVector* NameAsBytes();
    466 
    467     // C++ port only: get the length of NameAsBytes.
    468     int32_t NameBytesLength();
    469 
    470     // Returns the name in Unicode as UChar array.
    471     // Note: ICU UChar* convention requires caller to delete[] it.
    472     UChar* Name();
    473     bool operator==(const NameEntry& rhs) const;
    474 
    475     // UNIMPLEMENTED: String toString()
    476     //                int hashCode()
    477 
    478    private:
    479     void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
    480               int32_t name_id, const ByteVector* name_bytes);
    481 
    482     NameEntryId name_entry_id_;
    483     ByteVector name_bytes_;
    484 
    485     friend class NameEntryBuilder;
    486   };
    487 
    488   // Builder of a name entry.
    489   // C++ port: original Java hierarchy inherits from NameEntry.  In C++ port, we
    490   // opted not doing so to avoid ref count issues and nasty protected members.
    491   class NameEntryBuilder : public RefCounted<NameEntryBuilder> {
    492    public:
    493     NameEntryBuilder();
    494     NameEntryBuilder(const NameEntryId& name_entry_id,
    495                      const ByteVector& name_bytes);
    496     explicit NameEntryBuilder(const NameEntryId& name_entry_id);
    497     explicit NameEntryBuilder(NameEntry* entry);
    498     virtual ~NameEntryBuilder();
    499 
    500     virtual void SetName(const UChar* name);
    501     virtual void SetName(const ByteVector& name_bytes);
    502     virtual void SetName(const ByteVector& name_bytes,
    503                          int32_t offset,
    504                          int32_t length);
    505 
    506     // C++ port only. CALLER_ATTACH is not added because the lifetime shall be
    507     // controlled by this class, therefore the caller shall not increase the ref
    508     // count.
    509     NameEntry* name_entry() { return name_entry_; }
    510 
    511    private:
    512     void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
    513               int32_t name_id, const ByteVector* name_bytes);
    514 
    515     Ptr<NameEntry> name_entry_;
    516   };
    517   typedef std::map<NameEntryId, Ptr<NameEntryBuilder> > NameEntryBuilderMap;
    518 
    519   // An interface for a filter to use with the name entry iterator. This allows
    520   // name entries to be iterated and only those acceptable to the filter will be
    521   // returned.
    522   class NameEntryFilter {
    523    public:
    524     virtual bool Accept(int32_t platform_id,
    525                         int32_t encoding_id,
    526                         int32_t language_id,
    527                         int32_t name_id) = 0;
    528     // Make gcc -Wnon-virtual-dtor happy.
    529     virtual ~NameEntryFilter() {}
    530   };
    531 
    532   // C++ port only: an in-place filter to mimic Java Iterator's filtering.
    533   class NameEntryFilterInPlace : public NameEntryFilter {
    534    public:
    535     NameEntryFilterInPlace(int32_t platform_id,
    536                            int32_t encoding_id,
    537                            int32_t language_id,
    538                            int32_t name_id);
    539     // Make gcc -Wnon-virtual-dtor happy.
    540     virtual ~NameEntryFilterInPlace() {}
    541 
    542     virtual bool Accept(int32_t platform_id,
    543                         int32_t encoding_id,
    544                         int32_t language_id,
    545                         int32_t name_id);
    546 
    547    private:
    548     int32_t platform_id_;
    549     int32_t encoding_id_;
    550     int32_t language_id_;
    551     int32_t name_id_;
    552   };
    553 
    554   class NameEntryIterator : public RefIterator<NameEntry, NameTable> {
    555    public:
    556     // If filter is NULL, filter through all tables.
    557     explicit NameEntryIterator(NameTable* table);
    558     NameEntryIterator(NameTable* table, NameEntryFilter* filter);
    559     virtual ~NameEntryIterator() {}
    560 
    561     virtual bool HasNext();
    562     virtual CALLER_ATTACH NameEntry* Next();
    563 
    564    private:
    565     int32_t name_index_;
    566     NameEntryFilter* filter_;
    567   };
    568 
    569   // The builder to construct name table for outputting.
    570   class Builder : public SubTableContainerTable::Builder,
    571                   public RefCounted<Builder> {
    572    public:
    573     // Constructor scope altered to public because C++ does not allow base
    574     // class to instantiate derived class with protected constructors.
    575     Builder(Header* header, WritableFontData* data);
    576     Builder(Header* header, ReadableFontData* data);
    577 
    578     static CALLER_ATTACH Builder* CreateBuilder(Header* header,
    579                                                 WritableFontData* data);
    580 
    581     // Revert the name builders for the name table to the last version that came
    582     // from data.
    583     void RevertNames();
    584 
    585     // Number of name entry builders contained.
    586     int32_t BuilderCount();
    587 
    588     // Note: For C++ port, clear() is not implemented.  The clear() function
    589     //       implies completely remove name entry builders, which is easy in
    590     //       Java but will take a lot of efforts in C++ to release the builders
    591     //       nicely and correctly.
    592     // TODO(arthurhsu): IMPLEMENT
    593     // Clear the name builders for the name table.
    594     // void clear();
    595 
    596     // Check the existance of a name entry builder by key.
    597     bool Has(int32_t platform_id, int32_t encoding_id, int32_t language_id,
    598              int32_t name_id);
    599 
    600     // Get name entry builder by key.
    601     CALLER_ATTACH NameEntryBuilder* NameBuilder(int32_t platform_id,
    602         int32_t encoding_id, int32_t language_id, int32_t name_id);
    603 
    604     // Remove name entry builder by key.
    605     bool Remove(int32_t platform_id, int32_t encoding_id, int32_t language_id,
    606                 int32_t name_id);
    607 
    608     // FontDataTable::Builder API implementation
    609     virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
    610     virtual void SubDataSet();
    611     virtual int32_t SubDataSizeToSerialize();
    612     virtual bool SubReadyToSerialize();
    613     virtual int32_t SubSerialize(WritableFontData* new_data);
    614 
    615    private:
    616     void Initialize(ReadableFontData* data);
    617     NameEntryBuilderMap* GetNameBuilders();
    618 
    619     // Note: callers should use the getter funtion provided above to ensure that
    620     // this is lazily initialized instead of accessing directly.
    621     NameEntryBuilderMap name_entry_map_;
    622   };
    623 
    624   /****************************************************************************
    625    * public methods of NameTable class
    626    ****************************************************************************/
    627   virtual ~NameTable();
    628 
    629   // Get the format used in the name table.
    630   virtual int32_t Format();
    631 
    632   // Get the number of names in the name table.
    633   virtual int32_t NameCount();
    634 
    635   // Get the platform id for the given name record.
    636   virtual int32_t PlatformId(int32_t index);
    637 
    638   // Get the encoding id for the given name record.
    639   // see MacintoshEncodingId, WindowsEncodingId, UnicodeEncodingId
    640   virtual int32_t EncodingId(int32_t index);
    641 
    642   // Get the language id for the given name record.
    643   virtual int32_t LanguageId(int32_t index);
    644 
    645   // Get the name id for given name record.
    646   virtual int32_t NameId(int32_t index);
    647 
    648   // Get the name as bytes for the specified name. If there is no entry for the
    649   // requested name, then empty vector is returned.
    650   virtual void NameAsBytes(int32_t index, ByteVector* b);
    651   virtual void NameAsBytes(int32_t platform_id, int32_t encoding_id,
    652                            int32_t language_id, int32_t name_id,
    653                            ByteVector* b);
    654 
    655   // Get the name as a UChar* for the given name record. If there is no
    656   // encoding conversion available for the name record then a best attempt
    657   // UChar* will be returned.
    658   // Note: ICU UChar* convention requires caller to delete[] it.
    659   virtual UChar* Name(int32_t index);
    660 
    661   // Get the name as a UChar* for the specified name. If there is no entry for
    662   // the requested name then NULL is returned. If there is no encoding
    663   // conversion available for the name then a best attempt UChar* will be
    664   // returned.
    665   // Note: ICU UChar* convention requires caller to delete[] it.
    666   virtual UChar* Name(int32_t platform_id, int32_t encoding_id,
    667                       int32_t language_id, int32_t name_id);
    668 
    669   // Note: These functions are renamed in C++ port.  Their original Java name is
    670   // nameEntry().
    671   virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t index);
    672   virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t platform_id,
    673       int32_t encoding_id, int32_t language_id, int32_t name_id);
    674 
    675   // Note: Not implemented in C++ port due to complexity and low usage.
    676   // virtual void names(std::set<NameEntryPtr>*);
    677 
    678   // Get the iterator to iterate through all name entries.
    679   virtual CALLER_ATTACH NameEntryIterator* Iterator();
    680   virtual CALLER_ATTACH NameEntryIterator* Iterator(NameEntryFilter* filter);
    681 
    682  private:
    683   struct Offset {
    684     enum {
    685       kFormat = 0,
    686       kCount = 2,
    687       kStringOffset = 4,
    688       kNameRecordStart = 6,
    689 
    690       // Format 1 - offset from the end of the name records
    691       kLangTagCount = 0,
    692       kLangTagRecord = 2,
    693 
    694       kNameRecordSize = 12,
    695       // Name Records
    696       kNameRecordPlatformId = 0,
    697       kNameRecordEncodingId = 2,
    698       kNameRecordLanguageId = 4,
    699       kNameRecordNameId = 6,
    700       kNameRecordStringLength = 8,
    701       kNameRecordStringOffset = 10
    702     };
    703   };
    704 
    705   // The table shall be constructed using Builder, no direct instantiation.
    706   NameTable(Header* header, ReadableFontData* data);
    707 
    708   // Get the offset to the string data in the name table.
    709   int32_t StringOffset();
    710 
    711   // Get the offset for the given name record.
    712   int32_t OffsetForNameRecord(int32_t index);
    713 
    714   // Get the length of the string data for the given name record.
    715   int32_t NameLength(int32_t index);
    716 
    717   // Get the offset of the string data for the given name record.
    718   int32_t NameOffset(int32_t index);
    719 
    720   // Note: string literals are returned.  Caller shall not attempt to manipulate
    721   // the returned pointer.
    722   static const char* GetEncodingName(int32_t platform_id, int32_t encoding_id);
    723 
    724   // Note: ICU UConverter* convention requires caller to ucnv_close() it.
    725   static UConverter* GetCharset(int32_t platform_id, int32_t encoding_id);
    726 
    727   // Note: Output will be stored in ByteVector* b.  Original data in b will be
    728   // erased and replaced with converted name bytes.
    729   static void ConvertToNameBytes(const UChar* name, int32_t platform_id,
    730                                  int32_t encoding_id, ByteVector* b);
    731 
    732   // Note: ICU UChar* convention requires caller to delete[] it.
    733   static UChar* ConvertFromNameBytes(ByteVector* name_bytes,
    734                                      int32_t platform_id, int32_t encoding_id);
    735 };  // class NameTable
    736 typedef Ptr<NameTable> NameTablePtr;
    737 typedef Ptr<NameTable::NameEntry> NameEntryPtr;
    738 typedef Ptr<NameTable::Builder> NameTableBuilderPtr;
    739 typedef Ptr<NameTable::NameEntryBuilder> NameEntryBuilderPtr;
    740 
    741 }  // namespace sfntly
    742 
    743 #endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
    744