/* * Copyright 2011 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_ #define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_ // Must include this before ICU to avoid stdint redefinition issue. #include "sfntly/port/type.h" #include #include #include #include #include "sfntly/port/java_iterator.h" #include "sfntly/table/subtable_container_table.h" #if defined U_USING_ICU_NAMESPACE U_NAMESPACE_USE #endif namespace sfntly { // The following code implements the name table defined in TTF/OTF spec, which // can be found at http://www.microsoft.com/typography/otspec/name.htm. // Name IDs defined in TTF/OTF spec. struct NameId { enum { kUnknown = -1, kCopyrightNotice = 0, kFontFamilyName = 1, kFontSubfamilyName = 2, kUniqueFontIdentifier = 3, kFullFontName = 4, kVersionString = 5, kPostscriptName = 6, kTrademark = 7, kManufacturerName = 8, kDesigner = 9, kDescription = 10, kVendorURL = 11, kDesignerURL = 12, kLicenseDescription = 13, kLicenseInfoURL = 14, kReserved15 = 15, kPreferredFamily = 16, kPreferredSubfamily = 17, kCompatibleFullName = 18, kSampleText = 19, kPostscriptCID = 20, kWWSFamilyName = 21, kWWSSubfamilyName = 22 }; }; // Unicode language IDs used in Name Records. struct UnicodeLanguageId { enum { kUnknown = -1, kAll = 0 }; }; // Macintosh Language IDs (platform ID = 1) struct MacintoshLanguageId { enum { kUnknown = -1, kEnglish = 0, kFrench = 1, kGerman = 2, kItalian = 3, kDutch = 4, kSwedish = 5, kSpanish = 6, kDanish = 7, kPortuguese = 8, kNorwegian = 9, kHebrew = 10, kJapanese = 11, kArabic = 12, kFinnish = 13, kGreek = 14, kIcelandic = 15, kMaltese = 16, kTurkish = 17, kCroatian = 18, kChinese_Traditional = 19, kUrdu = 20, kHindi = 21, kThai = 22, kKorean = 23, kLithuanian = 24, kPolish = 25, kHungarian = 26, kEstonian = 27, kLatvian = 28, kSami = 29, kFaroese = 30, kFarsiPersian = 31, kRussian = 32, kChinese_Simplified = 33, kFlemish = 34, kIrishGaelic = 35, kAlbanian = 36, kRomanian = 37, kCzech = 38, kSlovak = 39, kSlovenian = 40, kYiddish = 41, kSerbian = 42, kMacedonian = 43, kBulgarian = 44, kUkrainian = 45, kByelorussian = 46, kUzbek = 47, kKazakh = 48, kAzerbaijani_Cyrillic = 49, kAzerbaijani_Arabic = 50, kArmenian = 51, kGeorgian = 52, kMoldavian = 53, kKirghiz = 54, kTajiki = 55, kTurkmen = 56, kMongolian_Mongolian = 57, kMongolian_Cyrillic = 58, kPashto = 59, kKurdish = 60, kKashmiri = 61, kSindhi = 62, kTibetan = 63, kNepali = 64, kSanskrit = 65, kMarathi = 66, kBengali = 67, kAssamese = 68, kGujarati = 69, kPunjabi = 70, kOriya = 71, kMalayalam = 72, kKannada = 73, kTamil = 74, kTelugu = 75, kSinhalese = 76, kBurmese = 77, kKhmer = 78, kLao = 79, kVietnamese = 80, kIndonesian = 81, kTagalong = 82, kMalay_Roman = 83, kMalay_Arabic = 84, kAmharic = 85, kTigrinya = 86, kGalla = 87, kSomali = 88, kSwahili = 89, kKinyarwandaRuanda = 90, kRundi = 91, kNyanjaChewa = 92, kMalagasy = 93, kEsperanto = 94, kWelsh = 128, kBasque = 129, kCatalan = 130, kLatin = 131, kQuenchua = 132, kGuarani = 133, kAymara = 134, kTatar = 135, kUighur = 136, kDzongkha = 137, kJavanese_Roman = 138, kSundanese_Roman = 139, kGalician = 140, kAfrikaans = 141, kBreton = 142, kInuktitut = 143, kScottishGaelic = 144, kManxGaelic = 145, kIrishGaelic_WithDotAbove = 146, kTongan = 147, kGreek_Polytonic = 148, kGreenlandic = 149, kAzerbaijani_Roman = 150 }; }; // Windows Language IDs (platformID = 3) struct WindowsLanguageId { enum { kUnknown = -1, kAfrikaans_SouthAfrica = 0x0436, kAlbanian_Albania = 0x041C, kAlsatian_France = 0x0484, kAmharic_Ethiopia = 0x045E, kArabic_Algeria = 0x1401, kArabic_Bahrain = 0x3C01, kArabic_Egypt = 0x0C01, kArabic_Iraq = 0x0801, kArabic_Jordan = 0x2C01, kArabic_Kuwait = 0x3401, kArabic_Lebanon = 0x3001, kArabic_Libya = 0x1001, kArabic_Morocco = 0x1801, kArabic_Oman = 0x2001, kArabic_Qatar = 0x4001, kArabic_SaudiArabia = 0x0401, kArabic_Syria = 0x2801, kArabic_Tunisia = 0x1C01, kArabic_UAE = 0x3801, kArabic_Yemen = 0x2401, kArmenian_Armenia = 0x042B, kAssamese_India = 0x044D, kAzeri_Cyrillic_Azerbaijan = 0x082C, kAzeri_Latin_Azerbaijan = 0x042C, kBashkir_Russia = 0x046D, kBasque_Basque = 0x042D, kBelarusian_Belarus = 0x0423, kBengali_Bangladesh = 0x0845, kBengali_India = 0x0445, kBosnian_Cyrillic_BosniaAndHerzegovina = 0x201A, kBosnian_Latin_BosniaAndHerzegovina = 0x141A, kBreton_France = 0x047E, kBulgarian_Bulgaria = 0x0402, kCatalan_Catalan = 0x0403, kChinese_HongKongSAR = 0x0C04, kChinese_MacaoSAR = 0x1404, kChinese_PeoplesRepublicOfChina = 0x0804, kChinese_Singapore = 0x1004, kChinese_Taiwan = 0x0404, kCorsican_France = 0x0483, kCroatian_Croatia = 0x041A, kCroatian_Latin_BosniaAndHerzegovina = 0x101A, kCzech_CzechRepublic = 0x0405, kDanish_Denmark = 0x0406, kDari_Afghanistan = 0x048C, kDivehi_Maldives = 0x0465, kDutch_Belgium = 0x0813, kDutch_Netherlands = 0x0413, kEnglish_Australia = 0x0C09, kEnglish_Belize = 0x2809, kEnglish_Canada = 0x1009, kEnglish_Caribbean = 0x2409, kEnglish_India = 0x4009, kEnglish_Ireland = 0x1809, kEnglish_Jamaica = 0x2009, kEnglish_Malaysia = 0x4409, kEnglish_NewZealand = 0x1409, kEnglish_RepublicOfThePhilippines = 0x3409, kEnglish_Singapore = 0x4809, kEnglish_SouthAfrica = 0x1C09, kEnglish_TrinidadAndTobago = 0x2C09, kEnglish_UnitedKingdom = 0x0809, kEnglish_UnitedStates = 0x0409, kEnglish_Zimbabwe = 0x3009, kEstonian_Estonia = 0x0425, kFaroese_FaroeIslands = 0x0438, kFilipino_Philippines = 0x0464, kFinnish_Finland = 0x040B, kFrench_Belgium = 0x080C, kFrench_Canada = 0x0C0C, kFrench_France = 0x040C, kFrench_Luxembourg = 0x140c, kFrench_PrincipalityOfMonoco = 0x180C, kFrench_Switzerland = 0x100C, kFrisian_Netherlands = 0x0462, kGalician_Galician = 0x0456, kGeorgian_Georgia = 0x0437, kGerman_Austria = 0x0C07, kGerman_Germany = 0x0407, kGerman_Liechtenstein = 0x1407, kGerman_Luxembourg = 0x1007, kGerman_Switzerland = 0x0807, kGreek_Greece = 0x0408, kGreenlandic_Greenland = 0x046F, kGujarati_India = 0x0447, kHausa_Latin_Nigeria = 0x0468, kHebrew_Israel = 0x040D, kHindi_India = 0x0439, kHungarian_Hungary = 0x040E, kIcelandic_Iceland = 0x040F, kIgbo_Nigeria = 0x0470, kIndonesian_Indonesia = 0x0421, kInuktitut_Canada = 0x045D, kInuktitut_Latin_Canada = 0x085D, kIrish_Ireland = 0x083C, kisiXhosa_SouthAfrica = 0x0434, kisiZulu_SouthAfrica = 0x0435, kItalian_Italy = 0x0410, kItalian_Switzerland = 0x0810, kJapanese_Japan = 0x0411, kKannada_India = 0x044B, kKazakh_Kazakhstan = 0x043F, kKhmer_Cambodia = 0x0453, kKiche_Guatemala = 0x0486, kKinyarwanda_Rwanda = 0x0487, kKiswahili_Kenya = 0x0441, kKonkani_India = 0x0457, kKorean_Korea = 0x0412, kKyrgyz_Kyrgyzstan = 0x0440, kLao_LaoPDR = 0x0454, kLatvian_Latvia = 0x0426, kLithuanian_Lithuania = 0x0427, kLowerSorbian_Germany = 0x082E, kLuxembourgish_Luxembourg = 0x046E, kMacedonian_FYROM_FormerYugoslavRepublicOfMacedonia = 0x042F, kMalay_BruneiDarussalam = 0x083E, kMalay_Malaysia = 0x043E, kMalayalam_India = 0x044C, kMaltese_Malta = 0x043A, kMaori_NewZealand = 0x0481, kMapudungun_Chile = 0x047A, kMarathi_India = 0x044E, kMohawk_Mohawk = 0x047C, kMongolian_Cyrillic_Mongolia = 0x0450, kMongolian_Traditional_PeoplesRepublicOfChina = 0x0850, kNepali_Nepal = 0x0461, kNorwegian_Bokmal_Norway = 0x0414, kNorwegian_Nynorsk_Norway = 0x0814, kOccitan_France = 0x0482, kOriya_India = 0x0448, kPashto_Afghanistan = 0x0463, kPolish_Poland = 0x0415, kPortuguese_Brazil = 0x0416, kPortuguese_Portugal = 0x0816, kPunjabi_India = 0x0446, kQuechua_Bolivia = 0x046B, kQuechua_Ecuador = 0x086B, kQuechua_Peru = 0x0C6B, kRomanian_Romania = 0x0418, kRomansh_Switzerland = 0x0417, kRussian_Russia = 0x0419, kSami_Inari_Finland = 0x243B, kSami_Lule_Norway = 0x103B, kSami_Lule_Sweden = 0x143B, kSami_Northern_Finland = 0x0C3B, kSami_Northern_Norway = 0x043B, kSami_Northern_Sweden = 0x083B, kSami_Skolt_Finland = 0x203B, kSami_Southern_Norway = 0x183B, kSami_Southern_Sweden = 0x1C3B, kSanskrit_India = 0x044F, kSerbian_Cyrillic_BosniaAndHerzegovina = 0x1C1A, kSerbian_Cyrillic_Serbia = 0x0C1A, kSerbian_Latin_BosniaAndHerzegovina = 0x181A, kSerbian_Latin_Serbia = 0x081A, kSesothoSaLeboa_SouthAfrica = 0x046C, kSetswana_SouthAfrica = 0x0432, kSinhala_SriLanka = 0x045B, kSlovak_Slovakia = 0x041B, kSlovenian_Slovenia = 0x0424, kSpanish_Argentina = 0x2C0A, kSpanish_Bolivia = 0x400A, kSpanish_Chile = 0x340A, kSpanish_Colombia = 0x240A, kSpanish_CostaRica = 0x140A, kSpanish_DominicanRepublic = 0x1C0A, kSpanish_Ecuador = 0x300A, kSpanish_ElSalvador = 0x440A, kSpanish_Guatemala = 0x100A, kSpanish_Honduras = 0x480A, kSpanish_Mexico = 0x080A, kSpanish_Nicaragua = 0x4C0A, kSpanish_Panama = 0x180A, kSpanish_Paraguay = 0x3C0A, kSpanish_Peru = 0x280A, kSpanish_PuertoRico = 0x500A, kSpanish_ModernSort_Spain = 0x0C0A, kSpanish_TraditionalSort_Spain = 0x040A, kSpanish_UnitedStates = 0x540A, kSpanish_Uruguay = 0x380A, kSpanish_Venezuela = 0x200A, kSweden_Finland = 0x081D, kSwedish_Sweden = 0x041D, kSyriac_Syria = 0x045A, kTajik_Cyrillic_Tajikistan = 0x0428, kTamazight_Latin_Algeria = 0x085F, kTamil_India = 0x0449, kTatar_Russia = 0x0444, kTelugu_India = 0x044A, kThai_Thailand = 0x041E, kTibetan_PRC = 0x0451, kTurkish_Turkey = 0x041F, kTurkmen_Turkmenistan = 0x0442, kUighur_PRC = 0x0480, kUkrainian_Ukraine = 0x0422, kUpperSorbian_Germany = 0x042E, kUrdu_IslamicRepublicOfPakistan = 0x0420, kUzbek_Cyrillic_Uzbekistan = 0x0843, kUzbek_Latin_Uzbekistan = 0x0443, kVietnamese_Vietnam = 0x042A, kWelsh_UnitedKingdom = 0x0452, kWolof_Senegal = 0x0448, kYakut_Russia = 0x0485, kYi_PRC = 0x0478, kYoruba_Nigeria = 0x046A }; }; class NameTable : public SubTableContainerTable, public RefCounted { public: // Unique identifier for a given name record. class NameEntryId { public: NameEntryId(); // C++ port only, must provide default constructor. NameEntryId(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id); NameEntryId(const NameEntryId&); // Make gcc -Wnon-virtual-dtor happy. virtual ~NameEntryId() {} int32_t platform_id() const { return platform_id_; } int32_t encoding_id() const { return encoding_id_; } int32_t language_id() const { return language_id_; } int32_t name_id() const { return name_id_; } const NameEntryId& operator=(const NameEntryId& rhs) const; bool operator==(const NameEntryId& rhs) const; bool operator<(const NameEntryId& rhs) const; // UNIMPLEMENTED: int hashCode() // String toString() private: mutable int32_t platform_id_; mutable int32_t encoding_id_; mutable int32_t language_id_; mutable int32_t name_id_; }; class NameEntryBuilder; // Class to represent a name entry in the name table. class NameEntry : public RefCounted { public: NameEntry(); NameEntry(const NameEntryId& name_entry_id, const ByteVector& name_bytes); NameEntry(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id, const ByteVector& name_bytes); virtual ~NameEntry(); NameEntryId& name_entry_id() { return name_entry_id_; } int32_t platform_id() const { return name_entry_id_.platform_id(); } int32_t encoding_id() const { return name_entry_id_.encoding_id(); } int32_t language_id() const { return name_entry_id_.language_id(); } int32_t name_id() const { return name_entry_id_.name_id(); } // Get the bytes for name. Returned pointer is the address of private // member of this class, do not attempt to delete. ByteVector* NameAsBytes(); // C++ port only: get the length of NameAsBytes. int32_t NameBytesLength(); // Returns the name in Unicode as UChar array. // Note: ICU UChar* convention requires caller to delete[] it. UChar* Name(); bool operator==(const NameEntry& rhs) const; // UNIMPLEMENTED: String toString() // int hashCode() private: void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id, const ByteVector* name_bytes); NameEntryId name_entry_id_; int32_t length_; ByteVector name_bytes_; friend class NameEntryBuilder; }; // Builder of a name entry. // C++ port: original Java hierarchy inherits from NameEntry. In C++ port, we // opted not doing so to avoid ref count issues and nasty protected members. class NameEntryBuilder : public RefCounted { public: NameEntryBuilder(); NameEntryBuilder(const NameEntryId& name_entry_id, const ByteVector& name_bytes); explicit NameEntryBuilder(const NameEntryId& name_entry_id); explicit NameEntryBuilder(NameEntry* entry); virtual ~NameEntryBuilder(); virtual void SetName(const UChar* name); virtual void SetName(const ByteVector& name_bytes); virtual void SetName(const ByteVector& name_bytes, int32_t offset, int32_t length); // C++ port only. CALLER_ATTACH is not added because the lifetime shall be // controlled by this class, therefore the caller shall not increase the ref // count. NameEntry* name_entry() { return name_entry_; } private: void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id, const ByteVector* name_bytes); Ptr name_entry_; }; typedef std::map > NameEntryBuilderMap; // An interface for a filter to use with the name entry iterator. This allows // name entries to be iterated and only those acceptable to the filter will be // returned. class NameEntryFilter { public: virtual bool Accept(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id) = 0; // Make gcc -Wnon-virtual-dtor happy. virtual ~NameEntryFilter() {} }; // C++ port only: an in-place filter to mimic Java Iterator's filtering. class NameEntryFilterInPlace : public NameEntryFilter { public: NameEntryFilterInPlace(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id); // Make gcc -Wnon-virtual-dtor happy. virtual ~NameEntryFilterInPlace() {} virtual bool Accept(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id); private: int32_t platform_id_; int32_t encoding_id_; int32_t language_id_; int32_t name_id_; }; class NameEntryIterator : public RefIterator { public: // If filter is NULL, filter through all tables. explicit NameEntryIterator(NameTable* table); NameEntryIterator(NameTable* table, NameEntryFilter* filter); virtual ~NameEntryIterator() {} virtual bool HasNext(); virtual CALLER_ATTACH NameEntry* Next(); private: int32_t name_index_; NameEntryFilter* filter_; }; // The builder to construct name table for outputting. class Builder : public SubTableContainerTable::Builder, public RefCounted { public: // Constructor scope altered to public because C++ does not allow base // class to instantiate derived class with protected constructors. Builder(Header* header, WritableFontData* data); Builder(Header* header, ReadableFontData* data); static CALLER_ATTACH Builder* CreateBuilder(Header* header, WritableFontData* data); // Revert the name builders for the name table to the last version that came // from data. void RevertNames(); // Number of name entry builders contained. int32_t BuilderCount(); // Note: For C++ port, clear() is not implemented. The clear() function // implies completely remove name entry builders, which is easy in // Java but will take a lot of efforts in C++ to release the builders // nicely and correctly. // TODO(arthurhsu): IMPLEMENT // Clear the name builders for the name table. // void clear(); // Check the existance of a name entry builder by key. bool Has(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id); // Get name entry builder by key. CALLER_ATTACH NameEntryBuilder* NameBuilder(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id); // Remove name entry builder by key. bool Remove(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id); // FontDataTable::Builder API implementation virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); virtual void SubDataSet(); virtual int32_t SubDataSizeToSerialize(); virtual bool SubReadyToSerialize(); virtual int32_t SubSerialize(WritableFontData* new_data); private: void Initialize(ReadableFontData* data); NameEntryBuilderMap* GetNameBuilders(); // Note: callers should use the getter funtion provided above to ensure that // this is lazily initialized instead of accessing directly. NameEntryBuilderMap name_entry_map_; }; /**************************************************************************** * public methods of NameTable class ****************************************************************************/ virtual ~NameTable(); // Get the format used in the name table. virtual int32_t Format(); // Get the number of names in the name table. virtual int32_t NameCount(); // Get the platform id for the given name record. virtual int32_t PlatformId(int32_t index); // Get the encoding id for the given name record. // see MacintoshEncodingId, WindowsEncodingId, UnicodeEncodingId virtual int32_t EncodingId(int32_t index); // Get the language id for the given name record. virtual int32_t LanguageId(int32_t index); // Get the name id for given name record. virtual int32_t NameId(int32_t index); // Get the name as bytes for the specified name. If there is no entry for the // requested name, then empty vector is returned. virtual void NameAsBytes(int32_t index, ByteVector* b); virtual void NameAsBytes(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id, ByteVector* b); // Get the name as a UChar* for the given name record. If there is no // encoding conversion available for the name record then a best attempt // UChar* will be returned. // Note: ICU UChar* convention requires caller to delete[] it. virtual UChar* Name(int32_t index); // Get the name as a UChar* for the specified name. If there is no entry for // the requested name then NULL is returned. If there is no encoding // conversion available for the name then a best attempt UChar* will be // returned. // Note: ICU UChar* convention requires caller to delete[] it. virtual UChar* Name(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id); // Note: These functions are renamed in C++ port. Their original Java name is // nameEntry(). virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t index); virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id); // Note: Not implemented in C++ port due to complexity and low usage. // virtual void names(std::set*); // Get the iterator to iterate through all name entries. virtual CALLER_ATTACH NameEntryIterator* Iterator(); virtual CALLER_ATTACH NameEntryIterator* Iterator(NameEntryFilter* filter); private: struct Offset { enum { kFormat = 0, kCount = 2, kStringOffset = 4, kNameRecordStart = 6, // Format 1 - offset from the end of the name records kLangTagCount = 0, kLangTagRecord = 2, kNameRecordSize = 12, // Name Records kNameRecordPlatformId = 0, kNameRecordEncodingId = 2, kNameRecordLanguageId = 4, kNameRecordNameId = 6, kNameRecordStringLength = 8, kNameRecordStringOffset = 10 }; }; // The table shall be constructed using Builder, no direct instantiation. NameTable(Header* header, ReadableFontData* data); // Get the offset to the string data in the name table. int32_t StringOffset(); // Get the offset for the given name record. int32_t OffsetForNameRecord(int32_t index); // Get the length of the string data for the given name record. int32_t NameLength(int32_t index); // Get the offset of the string data for the given name record. int32_t NameOffset(int32_t index); // Note: string literals are returned. Caller shall not attempt to manipulate // the returned pointer. static const char* GetEncodingName(int32_t platform_id, int32_t encoding_id); // Note: ICU UConverter* convention requires caller to ucnv_close() it. static UConverter* GetCharset(int32_t platform_id, int32_t encoding_id); // Note: Output will be stored in ByteVector* b. Original data in b will be // erased and replaced with converted name bytes. static void ConvertToNameBytes(const UChar* name, int32_t platform_id, int32_t encoding_id, ByteVector* b); // Note: ICU UChar* convention requires caller to delete[] it. static UChar* ConvertFromNameBytes(ByteVector* name_bytes, int32_t platform_id, int32_t encoding_id); }; // class NameTable typedef Ptr NameTablePtr; typedef Ptr NameEntryPtr; typedef Ptr NameTableBuilderPtr; typedef Ptr NameEntryBuilderPtr; } // namespace sfntly #endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_