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
32namespace 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.
38struct 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.
68struct UnicodeLanguageId {
69  enum {
70    kUnknown = -1,
71    kAll = 0
72  };
73};
74
75// Macintosh Language IDs (platform ID = 1)
76struct 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)
201struct 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
412class 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
736typedef Ptr<NameTable> NameTablePtr;
737typedef Ptr<NameTable::NameEntry> NameEntryPtr;
738typedef Ptr<NameTable::Builder> NameTableBuilderPtr;
739typedef Ptr<NameTable::NameEntryBuilder> NameEntryBuilderPtr;
740
741}  // namespace sfntly
742
743#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
744