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.
~NameEntryId()422     virtual ~NameEntryId() {}
423 
platform_id()424     int32_t platform_id() const { return platform_id_; }
encoding_id()425     int32_t encoding_id() const { return encoding_id_; }
language_id()426     int32_t language_id() const { return language_id_; }
name_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 
name_entry_id()457     NameEntryId& name_entry_id() { return name_entry_id_; }
platform_id()458     int32_t platform_id() const { return name_entry_id_.platform_id(); }
encoding_id()459     int32_t encoding_id() const { return name_entry_id_.encoding_id(); }
language_id()460     int32_t language_id() const { return name_entry_id_.language_id(); }
name_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.
name_entry()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.
~NameEntryFilter()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.
~NameEntryFilterInPlace()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);
~NameEntryIterator()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