1464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/*
2464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Copyright 2011 Google Inc. All Rights Reserved.
3464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
4464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * you may not use this file except in compliance with the License.
6464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * You may obtain a copy of the License at
7464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
8464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *      http://www.apache.org/licenses/LICENSE-2.0
9464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
10464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Unless required by applicable law or agreed to in writing, software
11464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * distributed under the License is distributed on an "AS IS" BASIS,
12464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * See the License for the specific language governing permissions and
14464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * limitations under the License.
15464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com */
16464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
175af34fd773f8cfee82321393504f558ddf67c628arthurhsu@google.com#include "sfntly/table/core/name_table.h"
182538405b412d47c3772cb2bebfe96fb96217b1f1dfilimon@google.com
19090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include <stdio.h>
20090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include <string.h>
21090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
22090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include <unicode/unistr.h>
23464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
24090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "sfntly/font.h"
25090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "sfntly/port/exception_type.h"
26464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
27464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comnamespace sfntly {
28464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/******************************************************************************
29090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * NameTable::NameEntryId class
30090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com ******************************************************************************/
31090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.comNameTable::NameEntryId::NameEntryId()
32246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    : platform_id_(0),
33246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      encoding_id_(0),
34246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      language_id_(0),
35246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      name_id_(0) {
36090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
37090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
38246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comNameTable::NameEntryId::NameEntryId(int32_t platform_id,
39246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                    int32_t encoding_id,
40246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                    int32_t language_id,
41246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                    int32_t name_id)
42246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    : platform_id_(platform_id),
43246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      encoding_id_(encoding_id),
44246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      language_id_(language_id),
45246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      name_id_(name_id) {
46090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
47090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
48090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.comNameTable::NameEntryId::NameEntryId(const NameTable::NameEntryId& rhs) {
49090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  *this = rhs;
50090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
51090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
52246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comconst NameTable::NameEntryId&
53246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    NameTable::NameEntryId::operator=(const NameTable::NameEntryId& rhs) const {
54090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  platform_id_ = rhs.platform_id_;
55090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  encoding_id_ = rhs.encoding_id_;
56090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  language_id_ = rhs.language_id_;
57090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  name_id_ = rhs.name_id_;
58090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  return *this;
59090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
60090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
61090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.combool NameTable::NameEntryId::operator==(const NameEntryId& rhs) const {
62246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return platform_id_ == rhs.platform_id_ &&
63246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com         encoding_id_ == rhs.encoding_id_ &&
64246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com         language_id_ == rhs.language_id_ &&
65246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com         name_id_ == rhs.name_id_;
66090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
67090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
68090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.combool NameTable::NameEntryId::operator<(const NameEntryId& rhs) const {
69090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  if (platform_id_ != rhs.platform_id_) return platform_id_ < rhs.platform_id_;
70090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  if (encoding_id_ != rhs.encoding_id_) return encoding_id_ < rhs.encoding_id_;
71090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  if (language_id_ != rhs.language_id_) return language_id_ < rhs.language_id_;
72090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  return name_id_ < rhs.name_id_;
73090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
74090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
75464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/******************************************************************************
76464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * NameTable::NameEntry class
77464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/
78464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comNameTable::NameEntry::NameEntry() {
79246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  Init(0, 0, 0, 0, NULL);
80464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
81464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
82090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.comNameTable::NameEntry::NameEntry(const NameEntryId& name_entry_id,
83090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com                                const ByteVector& name_bytes) {
84246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  Init(name_entry_id.platform_id(),
85246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       name_entry_id.encoding_id(),
86246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       name_entry_id.language_id(),
87246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       name_entry_id.name_id(),
88246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       &name_bytes);
89090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
90090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
91246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comNameTable::NameEntry::NameEntry(int32_t platform_id,
92246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                int32_t encoding_id,
93246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                int32_t language_id,
94246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                int32_t name_id,
95464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com                                const ByteVector& name_bytes) {
96246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  Init(platform_id, encoding_id, language_id, name_id, &name_bytes);
97464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
98464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
99464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comNameTable::NameEntry::~NameEntry() {}
100464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
101246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comByteVector* NameTable::NameEntry::NameAsBytes() {
102246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return &name_bytes_;
103090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
104090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
105246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::NameEntry::NameBytesLength() {
106090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  return name_bytes_.size();
107090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
108090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
109246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comUChar* NameTable::NameEntry::Name() {
110246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return NameTable::ConvertFromNameBytes(&name_bytes_,
111246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                         platform_id(),
112246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                         encoding_id());
113090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
114090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
115090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.combool NameTable::NameEntry::operator==(const NameEntry& rhs) const {
116090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  return (name_entry_id_ == rhs.name_entry_id_ &&
117090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com          name_bytes_ == rhs.name_bytes_);
118464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
119464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
120246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::NameEntry::Init(int32_t platform_id,
121246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                int32_t encoding_id,
122246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                int32_t language_id,
123246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                int32_t name_id,
124246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                const ByteVector* name_bytes) {
125246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  name_entry_id_ = NameEntryId(platform_id, encoding_id, language_id, name_id);
126246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (name_bytes) {
127246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    name_bytes_ = *name_bytes;
128246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  } else {
129246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    name_bytes_.clear();
130246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
131246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
132246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
133464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/******************************************************************************
134464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * NameTable::NameEntryBuilder class
135464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/
136464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comNameTable::NameEntryBuilder::NameEntryBuilder() {
137246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  Init(0, 0, 0, 0, NULL);
138464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
139464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
140b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comNameTable::NameEntryBuilder::NameEntryBuilder(const NameEntryId& name_entry_id,
141b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com                                              const ByteVector& name_bytes) {
142246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  Init(name_entry_id.platform_id(),
143246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       name_entry_id.encoding_id(),
144246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       name_entry_id.language_id(),
145246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       name_entry_id.name_id(),
146246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       &name_bytes);
147464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
148464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
149464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comNameTable::NameEntryBuilder::NameEntryBuilder(
150090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com    const NameEntryId& name_entry_id) {
151246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  Init(name_entry_id.platform_id(),
152246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       name_entry_id.encoding_id(),
153246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       name_entry_id.language_id(),
154246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       name_entry_id.name_id(),
155246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       NULL);
156464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
157464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
158464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comNameTable::NameEntryBuilder::NameEntryBuilder(NameEntry* b) {
159246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  Init(b->platform_id(),
160246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       b->encoding_id(),
161246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       b->language_id(),
162246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       b->name_id(),
163246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       b->NameAsBytes());
164464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
165464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
166464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comNameTable::NameEntryBuilder::~NameEntryBuilder() {}
167464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
168246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::NameEntryBuilder::SetName(const UChar* name) {
169090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  if (name == NULL) {
170090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com    name_entry_->name_bytes_.clear();
171090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com    return;
172090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  }
173246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  NameTable::ConvertToNameBytes(name,
174246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                name_entry_->platform_id(),
175246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                name_entry_->encoding_id(),
176090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com                                &name_entry_->name_bytes_);
177090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
178090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
179246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes) {
180090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  name_entry_->name_bytes_.clear();
181246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  std::copy(name_bytes.begin(),
182246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com            name_bytes.end(),
183090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com            name_entry_->name_bytes_.begin());
184090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
185090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
186246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes,
187246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                          int32_t offset,
188246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                          int32_t length) {
189090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  name_entry_->name_bytes_.clear();
190246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  std::copy(name_bytes.begin() + offset,
191246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com            name_bytes.begin() + offset + length,
192090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com            name_entry_->name_bytes_.begin());
193090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
194090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
195246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::NameEntryBuilder::Init(int32_t platform_id,
196246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                       int32_t encoding_id,
197246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                       int32_t language_id,
198246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                       int32_t name_id,
199246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                       const ByteVector* name_bytes) {
200090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  name_entry_ = new NameEntry();
201246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  name_entry_->Init(platform_id, encoding_id, language_id, name_id, name_bytes);
202090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
203090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
204090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com/******************************************************************************
205090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * NameTable::NameEntryFilterInPlace class (C++ port only)
206090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com ******************************************************************************/
207090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.comNameTable::NameEntryFilterInPlace::NameEntryFilterInPlace(int32_t platform_id,
208246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                                          int32_t encoding_id,
209246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                                          int32_t language_id,
210246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                                          int32_t name_id)
211246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    : platform_id_(platform_id),
212246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      encoding_id_(encoding_id),
213246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      language_id_(language_id),
214246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      name_id_(name_id) {
215090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
216090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
217246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.combool NameTable::NameEntryFilterInPlace::Accept(int32_t platform_id,
218246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                               int32_t encoding_id,
219246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                               int32_t language_id,
220246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                               int32_t name_id) {
221246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return (platform_id_ == platform_id &&
222246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          encoding_id_ == encoding_id &&
223246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          language_id_ == language_id &&
224246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          name_id_ == name_id);
225090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
226090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
227464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/******************************************************************************
228464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * NameTable::NameEntryIterator class
229464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/
230333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comNameTable::NameEntryIterator::NameEntryIterator(NameTable* table)
231333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    : RefIterator<NameEntry, NameTable>(table),
232333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      name_index_(0),
233333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      filter_(NULL) {
234090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
235090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
236464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comNameTable::NameEntryIterator::NameEntryIterator(NameTable* table,
237333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                                NameEntryFilter* filter)
238333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    : RefIterator<NameEntry, NameTable>(table),
239333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      name_index_(0),
240333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      filter_(filter) {
241464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
242464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
243246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.combool NameTable::NameEntryIterator::HasNext() {
244464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (!filter_) {
245333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    if (name_index_ < container()->NameCount()) {
246464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com      return true;
247464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    }
248464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    return false;
249464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
250333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  for (; name_index_ < container()->NameCount(); ++name_index_) {
251333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    if (filter_->Accept(container()->PlatformId(name_index_),
252333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                        container()->EncodingId(name_index_),
253333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                        container()->LanguageId(name_index_),
254333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                        container()->NameId(name_index_))) {
255464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com      return true;
256464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    }
257464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
258464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return false;
259464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
260464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
261246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH NameTable::NameEntry* NameTable::NameEntryIterator::Next() {
262246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (!HasNext())
263464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    return NULL;
264333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return container()->GetNameEntry(name_index_++);
265246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
266246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
267464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/******************************************************************************
268464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * NameTable::Builder class
269464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com ******************************************************************************/
270b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comNameTable::Builder::Builder(Header* header, WritableFontData* data)
271b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com    : SubTableContainerTable::Builder(header, data) {
272b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com}
273b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com
274b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comNameTable::Builder::Builder(Header* header, ReadableFontData* data)
275b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com    : SubTableContainerTable::Builder(header, data) {
276464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
277464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
278b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.comCALLER_ATTACH NameTable::Builder*
279b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com    NameTable::Builder::CreateBuilder(Header* header,
280b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com                                      WritableFontData* data) {
281b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  Ptr<NameTable::Builder> builder;
282b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  builder = new NameTable::Builder(header, data);
283b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  return builder.Detach();
284464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
285464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
286246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::Builder::RevertNames() {
287090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  name_entry_map_.clear();
288246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  set_model_changed(false);
289090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
290090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
291246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::Builder::BuilderCount() {
292246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  GetNameBuilders();  // Ensure name_entry_map_ is built.
293090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  return (int32_t)name_entry_map_.size();
294090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
295090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
296246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.combool NameTable::Builder::Has(int32_t platform_id,
297246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                             int32_t encoding_id,
298246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                             int32_t language_id,
299246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                             int32_t name_id) {
300090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  NameEntryId probe(platform_id, encoding_id, language_id, name_id);
301246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  GetNameBuilders();  // Ensure name_entry_map_ is built.
302090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  return (name_entry_map_.find(probe) != name_entry_map_.end());
303090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
304090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
305246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH NameTable::NameEntryBuilder*
306246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    NameTable::Builder::NameBuilder(int32_t platform_id,
307246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                    int32_t encoding_id,
308246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                    int32_t language_id,
309246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                    int32_t name_id) {
310090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  NameEntryId probe(platform_id, encoding_id, language_id, name_id);
311090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  NameEntryBuilderMap builders;
312246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  GetNameBuilders();  // Ensure name_entry_map_ is built.
313090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  if (name_entry_map_.find(probe) != name_entry_map_.end()) {
314090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com    return name_entry_map_[probe];
315090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  }
316090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  NameEntryBuilderPtr builder = new NameEntryBuilder(probe);
317090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  name_entry_map_[probe] = builder;
318246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return builder.Detach();
319090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
320090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
321246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.combool NameTable::Builder::Remove(int32_t platform_id,
322246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                int32_t encoding_id,
323246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                int32_t language_id,
324246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                int32_t name_id) {
325090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  NameEntryId probe(platform_id, encoding_id, language_id, name_id);
326246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  GetNameBuilders();  // Ensure name_entry_map_ is built.
327090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  NameEntryBuilderMap::iterator position = name_entry_map_.find(probe);
328090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  if (position != name_entry_map_.end()) {
329090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com    name_entry_map_.erase(position);
330090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com    return true;
331464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
332090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  return false;
333090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com}
334464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
335246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH FontDataTable*
336246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    NameTable::Builder::SubBuildTable(ReadableFontData* data) {
337090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  FontDataTablePtr table = new NameTable(header(), data);
338246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return table.Detach();
339464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
340464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
341246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::Builder::SubDataSet() {
342090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  name_entry_map_.clear();
343246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  set_model_changed(false);
344464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
345464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
346246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::Builder::SubDataSizeToSerialize() {
347464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (name_entry_map_.empty()) {
348464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    return 0;
349464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
350464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
351246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int32_t size = NameTable::Offset::kNameRecordStart +
352246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                 name_entry_map_.size() * NameTable::Offset::kNameRecordSize;
353090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  for (NameEntryBuilderMap::iterator b = name_entry_map_.begin(),
354090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com                                     end = name_entry_map_.end();
355090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com                                     b != end; ++b) {
356090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com    NameEntryBuilderPtr p = b->second;
357246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    NameEntry* entry = p->name_entry();
358246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    size += entry->NameBytesLength();
359464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
360464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return size;
361464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
362464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
363246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.combool NameTable::Builder::SubReadyToSerialize() {
364090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  return !name_entry_map_.empty();
365464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
366464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
367246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::Builder::SubSerialize(WritableFontData* new_data) {
368090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  int32_t string_table_start_offset =
369246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      NameTable::Offset::kNameRecordStart +
370246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      name_entry_map_.size() * NameTable::Offset::kNameRecordSize;
371090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
372246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  // Header
373246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  new_data->WriteUShort(NameTable::Offset::kFormat, 0);
374246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  new_data->WriteUShort(NameTable::Offset::kCount, name_entry_map_.size());
375246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  new_data->WriteUShort(NameTable::Offset::kStringOffset,
376090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com                        string_table_start_offset);
377090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  int32_t name_record_offset = NameTable::Offset::kNameRecordStart;
378090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  int32_t string_offset = 0;
379090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  // Note: we offered operator< in NameEntryId, which will be used by std::less,
380090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  //       and therefore our map will act like TreeMap in Java to provide
381090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  //       sorted key set.
382090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  for (NameEntryBuilderMap::iterator b = name_entry_map_.begin(),
383090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com                                     end = name_entry_map_.end();
384090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com                                     b != end; ++b) {
385246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    new_data->WriteUShort(
386090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com        name_record_offset + NameTable::Offset::kNameRecordPlatformId,
387246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        b->first.platform_id());
388246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    new_data->WriteUShort(
389090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com        name_record_offset + NameTable::Offset::kNameRecordEncodingId,
390246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        b->first.encoding_id());
391246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    new_data->WriteUShort(
392090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com        name_record_offset + NameTable::Offset::kNameRecordLanguageId,
393246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        b->first.language_id());
394246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    new_data->WriteUShort(
395090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com        name_record_offset + NameTable::Offset::kNameRecordNameId,
396246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        b->first.name_id());
397246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    NameEntry* builder_entry = b->second->name_entry();
398246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    new_data->WriteUShort(
399090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com        name_record_offset + NameTable::Offset::kNameRecordStringLength,
400246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        builder_entry->NameBytesLength());
401246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    new_data->WriteUShort(
402090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com        name_record_offset + NameTable::Offset::kNameRecordStringOffset,
403090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com        string_offset);
404090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com    name_record_offset += NameTable::Offset::kNameRecordSize;
405246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    string_offset += new_data->WriteBytes(
406090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com        string_offset + string_table_start_offset,
407246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        builder_entry->NameAsBytes());
408090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  }
409090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
410090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com  return string_offset + string_table_start_offset;
411464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
412464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
413246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::Builder::Initialize(ReadableFontData* data) {
414246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (data) {
415246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    NameTablePtr table = new NameTable(header(), data);
416333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    Ptr<NameEntryIterator> name_iter;
417333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    name_iter.Attach(table->Iterator());
418333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    while (name_iter->HasNext()) {
4196a22b959c06e66a039c630e6ac514234114b46cbarthurhsu@google.com      NameEntryPtr name_entry;
420333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      name_entry.Attach(name_iter->Next());
421246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      NameEntryBuilderPtr name_entry_builder = new NameEntryBuilder(name_entry);
422246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      NameEntry* builder_entry = name_entry_builder->name_entry();
423246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      NameEntryId probe = builder_entry->name_entry_id();
424246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      name_entry_map_[probe] = name_entry_builder;
425246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    }
426246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
427246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
428246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
429246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comNameTable::NameEntryBuilderMap* NameTable::Builder::GetNameBuilders() {
430246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (name_entry_map_.empty()) {
431246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    Initialize(InternalReadData());
432246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
433246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  set_model_changed();
434246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return &name_entry_map_;
435246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
436246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
437246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com/******************************************************************************
438246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com * NameTable class
439246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com ******************************************************************************/
440246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comNameTable::~NameTable() {}
441246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
442246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::Format() {
443246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return data_->ReadUShort(Offset::kFormat);
444246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
445246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
446246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::NameCount() {
447246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return data_->ReadUShort(Offset::kCount);
448246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
449246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
450246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::PlatformId(int32_t index) {
451246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return data_->ReadUShort(Offset::kNameRecordPlatformId +
452246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                           OffsetForNameRecord(index));
453246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
454246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
455246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::EncodingId(int32_t index) {
456246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return data_->ReadUShort(Offset::kNameRecordEncodingId +
457246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                           OffsetForNameRecord(index));
458246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
459246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
460246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::LanguageId(int32_t index) {
461246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return data_->ReadUShort(Offset::kNameRecordLanguageId +
462246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                           OffsetForNameRecord(index));
463246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
464246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
465246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::NameId(int32_t index) {
466246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return data_->ReadUShort(Offset::kNameRecordNameId +
467246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                           OffsetForNameRecord(index));
468246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
469246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
470246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::NameAsBytes(int32_t index, ByteVector* b) {
471246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  assert(b);
472246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int32_t length = NameLength(index);
473246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  b->clear();
474246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  b->resize(length);
475cfb2f1743f0169ad8d01035458617bce97107539arthurhsu@google.com  if (length > 0) {
476cfb2f1743f0169ad8d01035458617bce97107539arthurhsu@google.com    data_->ReadBytes(NameOffset(index), &((*b)[0]), 0, length);
477cfb2f1743f0169ad8d01035458617bce97107539arthurhsu@google.com  }
478246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
479246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
480246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::NameAsBytes(int32_t platform_id,
481246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                            int32_t encoding_id,
482246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                            int32_t language_id,
483246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                            int32_t name_id,
484246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                            ByteVector* b) {
485246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  assert(b);
486246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  NameEntryPtr entry;
487246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
488246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (entry) {
489246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    ByteVector* name = entry->NameAsBytes();
490246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    std::copy(name->begin(), name->end(), b->begin());
491246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
492246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
493246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
494f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.comUChar* NameTable::Name(int32_t index) {
495246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  ByteVector b;
496246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  NameAsBytes(index, &b);
497246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return ConvertFromNameBytes(&b, PlatformId(index), EncodingId(index));
498246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
499246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
500246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comUChar* NameTable::Name(int32_t platform_id,
501246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                       int32_t encoding_id,
502246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                       int32_t language_id,
503246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                       int32_t name_id) {
504246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  NameEntryPtr entry;
505246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
506246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (entry) {
507246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    return entry->Name();
508246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
509246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return NULL;
510246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
511246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
512246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t index) {
513246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  ByteVector b;
514246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  NameAsBytes(index, &b);
515246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  NameEntryPtr instance = new NameEntry(PlatformId(index),
516246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                        EncodingId(index),
517246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                        LanguageId(index),
518246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                        NameId(index), b);
519246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return instance.Detach();
520246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
521246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
522246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comCALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t platform_id,
523246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                                            int32_t encoding_id,
524246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                                            int32_t language_id,
525246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                                            int32_t name_id) {
526246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  NameTable::NameEntryFilterInPlace
527246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      filter(platform_id, encoding_id, language_id, name_id);
528333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  Ptr<NameTable::NameEntryIterator> name_entry_iter;
529333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  name_entry_iter.Attach(Iterator(&filter));
530246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  NameEntryPtr result;
531246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (name_entry_iter->HasNext()) {
532246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    result = name_entry_iter->Next();
533246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
534246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return result;
535246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
536246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
537333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comCALLER_ATTACH NameTable::NameEntryIterator* NameTable::Iterator() {
538333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  Ptr<NameEntryIterator> output = new NameTable::NameEntryIterator(this);
539333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return output.Detach();
540246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
541246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
542333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comCALLER_ATTACH
543246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comNameTable::NameEntryIterator* NameTable::Iterator(NameEntryFilter* filter) {
544333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  Ptr<NameEntryIterator> output =
545333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      new NameTable::NameEntryIterator(this, filter);
546333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return output.Detach();
547246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
548246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
549246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comNameTable::NameTable(Header* header, ReadableFontData* data)
550b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com    : SubTableContainerTable(header, data) {}
551246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
552246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::StringOffset() {
553246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return data_->ReadUShort(Offset::kStringOffset);
554246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
555246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
556246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::OffsetForNameRecord(int32_t index) {
557246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return Offset::kNameRecordStart + index * Offset::kNameRecordSize;
558246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
559246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
560246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::NameLength(int32_t index) {
561246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return data_->ReadUShort(Offset::kNameRecordStringLength +
562246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                           OffsetForNameRecord(index));
563246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
564246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
565246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t NameTable::NameOffset(int32_t index) {
566246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return data_->ReadUShort(Offset::kNameRecordStringOffset +
567246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                           OffsetForNameRecord(index)) + StringOffset();
568246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
569246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
570246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comconst char* NameTable::GetEncodingName(int32_t platform_id,
571246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                       int32_t encoding_id) {
572246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  switch (platform_id) {
573246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    case PlatformId::kUnicode:
574246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      return "UTF-16BE";
575246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    case PlatformId::kMacintosh:
576246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      switch (encoding_id) {
577246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kRoman:
578246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "MacRoman";
579246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kJapanese:
580246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "Shift-JIS";
581246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kChineseTraditional:
582246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "Big5";
583246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kKorean:
584246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "EUC-KR";
585246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kArabic:
586246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "MacArabic";
587246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kHebrew:
588246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "MacHebrew";
589246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kGreek:
590246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "MacGreek";
591246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kRussian:
592246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "MacCyrillic";
593246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kRSymbol:
594246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "MacSymbol";
595246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kThai:
596246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "MacThai";
597246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case MacintoshEncodingId::kChineseSimplified:
598246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "EUC-CN";
599246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        default:  // Note: unknown/unconfirmed cases are not ported.
600246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          break;
601246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      }
602246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      break;
603246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    case PlatformId::kISO:
604246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      break;
605246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    case PlatformId::kWindows:
606246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      switch (encoding_id) {
607246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case WindowsEncodingId::kSymbol:
608246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case WindowsEncodingId::kUnicodeUCS2:
609246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "UTF-16BE";
610246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case WindowsEncodingId::kShiftJIS:
611246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "windows-933";
612246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case WindowsEncodingId::kPRC:
613246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "windows-936";
614246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case WindowsEncodingId::kBig5:
615246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "windows-950";
616246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case WindowsEncodingId::kWansung:
617246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "windows-949";
618246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case WindowsEncodingId::kJohab:
619246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "ms1361";
620246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        case WindowsEncodingId::kUnicodeUCS4:
621246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com          return "UCS-4";
622246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      }
623246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      break;
624246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    case PlatformId::kCustom:
625246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      break;
626246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    default:
627246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      break;
628246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
629246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return NULL;
630246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
631246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
632246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comUConverter* NameTable::GetCharset(int32_t platform_id, int32_t encoding_id) {
633246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  UErrorCode error_code = U_ZERO_ERROR;
634246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  UConverter* conv = ucnv_open(GetEncodingName(platform_id, encoding_id),
635246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                               &error_code);
636246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (U_SUCCESS(error_code)) {
637246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    return conv;
638246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
639246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
640246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (conv) {
641246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    ucnv_close(conv);
642246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
643246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return NULL;
644246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
645246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
646246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid NameTable::ConvertToNameBytes(const UChar* name,
647246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                   int32_t platform_id,
648246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                   int32_t encoding_id,
649246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                   ByteVector* b) {
650246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  assert(b);
651246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  assert(name);
652246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  b->clear();
653246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  UConverter* cs = GetCharset(platform_id, encoding_id);
654246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (cs == NULL) {
655246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    return;
656246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
657246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
658246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  // Preflight to get buffer size.
659246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  UErrorCode error_code = U_ZERO_ERROR;
660246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int32_t length = ucnv_fromUChars(cs, NULL, 0, name, -1, &error_code);
661246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  b->resize(length + 4);  // The longest termination "\0" is 4 bytes.
662246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  memset(&((*b)[0]), 0, length + 4);
663246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  error_code = U_ZERO_ERROR;
664246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  ucnv_fromUChars(cs,
665246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                  reinterpret_cast<char*>(&((*b)[0])),
666246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                  length + 4,
667246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                  name,
668246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                  -1,
669246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                  &error_code);
670246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (!U_SUCCESS(error_code)) {
671246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    b->clear();
672246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
673246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  ucnv_close(cs);
674246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
675246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
676246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comUChar* NameTable::ConvertFromNameBytes(ByteVector* name_bytes,
677246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                       int32_t platform_id,
678246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                       int32_t encoding_id) {
679cfb2f1743f0169ad8d01035458617bce97107539arthurhsu@google.com  if (name_bytes == NULL || name_bytes->size() == 0) {
680246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    return NULL;
681246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
682246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  UConverter* cs = GetCharset(platform_id, encoding_id);
683246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  UErrorCode error_code = U_ZERO_ERROR;
684246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (cs == NULL) {
685246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    char buffer[11] = {0};
686246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com#if defined (WIN32)
687246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    _itoa_s(platform_id, buffer, 16);
688246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com#else
689246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    snprintf(buffer, sizeof(buffer), "%x", platform_id);
690246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com#endif
691246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    UChar* result = new UChar[12];
692246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    memset(result, 0, sizeof(UChar) * 12);
693246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    cs = ucnv_open("utf-8", &error_code);
694246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    if (U_SUCCESS(error_code)) {
695246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      ucnv_toUChars(cs, result, 12, buffer, 11, &error_code);
696246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      ucnv_close(cs);
697246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      if (U_SUCCESS(error_code)) {
698246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com        return result;
699246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      }
700246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    }
701246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    delete[] result;
702246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    return NULL;
703246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
704246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
705246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  // No preflight needed here, we will be bigger.
706246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  UChar* output_buffer = new UChar[name_bytes->size() + 1];
707246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  memset(output_buffer, 0, sizeof(UChar) * (name_bytes->size() + 1));
708246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int32_t length = ucnv_toUChars(cs,
709246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                 output_buffer,
710246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                 name_bytes->size(),
711246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                 reinterpret_cast<char*>(&((*name_bytes)[0])),
712246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                 name_bytes->size(),
713246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                                 &error_code);
714246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  ucnv_close(cs);
715246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  if (length > 0) {
716246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    return output_buffer;
717246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  }
718246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
719246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  delete[] output_buffer;
720246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return NULL;
721246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
722246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
723464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}  // namespace sfntly
724