Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: src/name.cc

Issue 658573004: Updating to new OTS repo from https://github.com/khaledhosny/ots.git (Closed) Base URL: https://chromium.googlesource.com/external/ots@master
Patch Set: Adding Colored Emoji changes from external/git repo Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« .gitmodules ('K') | « src/name.h ('k') | src/os2.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "name.h" 5 #include "name.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 9
10 #include "cff.h" 10 #include "cff.h"
11 11
12 // name - Naming Table 12 // name - Naming Table
13 // http://www.microsoft.com/opentype/otspec/name.htm 13 // http://www.microsoft.com/typography/otspec/name.htm
14
15 #define TABLE_NAME "name"
14 16
15 namespace { 17 namespace {
16 18
17 bool ValidInPsName(char c) { 19 bool ValidInPsName(char c) {
18 return (c > 0x20 && c < 0x7f && !std::strchr("[](){}<>/%", c)); 20 return (c > 0x20 && c < 0x7f && !std::strchr("[](){}<>/%", c));
19 } 21 }
20 22
21 bool CheckPsNameAscii(const std::string& name) { 23 bool CheckPsNameAscii(const std::string& name) {
22 for (unsigned i = 0; i < name.size(); ++i) { 24 for (unsigned i = 0; i < name.size(); ++i) {
23 if (!ValidInPsName(name[i])) { 25 if (!ValidInPsName(name[i])) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 namespace ots { 59 namespace ots {
58 60
59 bool ots_name_parse(OpenTypeFile* file, const uint8_t* data, size_t length) { 61 bool ots_name_parse(OpenTypeFile* file, const uint8_t* data, size_t length) {
60 Buffer table(data, length); 62 Buffer table(data, length);
61 63
62 OpenTypeNAME* name = new OpenTypeNAME; 64 OpenTypeNAME* name = new OpenTypeNAME;
63 file->name = name; 65 file->name = name;
64 66
65 uint16_t format = 0; 67 uint16_t format = 0;
66 if (!table.ReadU16(&format) || format > 1) { 68 if (!table.ReadU16(&format) || format > 1) {
67 return OTS_FAILURE(); 69 return OTS_FAILURE_MSG("Failed to read name table format or bad format %d", format);
68 } 70 }
69 71
70 uint16_t count = 0; 72 uint16_t count = 0;
71 if (!table.ReadU16(&count)) { 73 if (!table.ReadU16(&count)) {
72 return OTS_FAILURE(); 74 return OTS_FAILURE_MSG("Failed to read name count");
73 } 75 }
74 76
75 uint16_t string_offset = 0; 77 uint16_t string_offset = 0;
76 if (!table.ReadU16(&string_offset) || string_offset > length) { 78 if (!table.ReadU16(&string_offset) || string_offset > length) {
77 return OTS_FAILURE(); 79 return OTS_FAILURE_MSG("Failed to read strings offset");
78 } 80 }
79 const char* string_base = reinterpret_cast<const char*>(data) + 81 const char* string_base = reinterpret_cast<const char*>(data) +
80 string_offset; 82 string_offset;
81 83
82 NameRecord prev_record; 84 NameRecord prev_record;
83 bool sort_required = false; 85 bool sort_required = false;
84 86
85 // Read all the names, discarding any with invalid IDs, 87 // Read all the names, discarding any with invalid IDs,
86 // and any where the offset/length would be outside the table. 88 // and any where the offset/length would be outside the table.
87 // A stricter alternative would be to reject the font if there 89 // A stricter alternative would be to reject the font if there
88 // are invalid name records, but it's not clear that is necessary. 90 // are invalid name records, but it's not clear that is necessary.
89 for (unsigned i = 0; i < count; ++i) { 91 for (unsigned i = 0; i < count; ++i) {
90 NameRecord rec; 92 NameRecord rec;
91 uint16_t name_length, name_offset; 93 uint16_t name_length, name_offset = 0;
92 if (!table.ReadU16(&rec.platform_id) || 94 if (!table.ReadU16(&rec.platform_id) ||
93 !table.ReadU16(&rec.encoding_id) || 95 !table.ReadU16(&rec.encoding_id) ||
94 !table.ReadU16(&rec.language_id) || 96 !table.ReadU16(&rec.language_id) ||
95 !table.ReadU16(&rec.name_id) || 97 !table.ReadU16(&rec.name_id) ||
96 !table.ReadU16(&name_length) || 98 !table.ReadU16(&name_length) ||
97 !table.ReadU16(&name_offset)) { 99 !table.ReadU16(&name_offset)) {
98 return OTS_FAILURE(); 100 return OTS_FAILURE_MSG("Failed to read name entry %d", i);
99 } 101 }
100 // check platform & encoding, discard names with unknown values 102 // check platform & encoding, discard names with unknown values
101 switch (rec.platform_id) { 103 switch (rec.platform_id) {
102 case 0: // Unicode 104 case 0: // Unicode
103 if (rec.encoding_id > 6) { 105 if (rec.encoding_id > 6) {
104 continue; 106 continue;
105 } 107 }
106 break; 108 break;
107 case 1: // Macintosh 109 case 1: // Macintosh
108 if (rec.encoding_id > 32) { 110 if (rec.encoding_id > 32) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 } 161 }
160 162
161 name->names.push_back(rec); 163 name->names.push_back(rec);
162 prev_record = rec; 164 prev_record = rec;
163 } 165 }
164 166
165 if (format == 1) { 167 if (format == 1) {
166 // extended name table format with language tags 168 // extended name table format with language tags
167 uint16_t lang_tag_count; 169 uint16_t lang_tag_count;
168 if (!table.ReadU16(&lang_tag_count)) { 170 if (!table.ReadU16(&lang_tag_count)) {
169 return OTS_FAILURE(); 171 return OTS_FAILURE_MSG("Failed to read language tag count");
170 } 172 }
171 for (unsigned i = 0; i < lang_tag_count; ++i) { 173 for (unsigned i = 0; i < lang_tag_count; ++i) {
172 uint16_t tag_length = 0; 174 uint16_t tag_length = 0;
173 uint16_t tag_offset = 0; 175 uint16_t tag_offset = 0;
174 if (!table.ReadU16(&tag_length) || !table.ReadU16(&tag_offset)) { 176 if (!table.ReadU16(&tag_length) || !table.ReadU16(&tag_offset)) {
175 return OTS_FAILURE(); 177 return OTS_FAILURE_MSG("Faile to read tag length or offset");
176 } 178 }
177 const unsigned tag_end = static_cast<unsigned>(string_offset) + 179 const unsigned tag_end = static_cast<unsigned>(string_offset) +
178 tag_offset + tag_length; 180 tag_offset + tag_length;
179 if (tag_end > length) { 181 if (tag_end > length) {
180 return OTS_FAILURE(); 182 return OTS_FAILURE_MSG("bad end of tag %d > %ld for name entry %d", tag_ end, length, i);
181 } 183 }
182 std::string tag(string_base + tag_offset, tag_length); 184 std::string tag(string_base + tag_offset, tag_length);
183 name->lang_tags.push_back(tag); 185 name->lang_tags.push_back(tag);
184 } 186 }
185 } 187 }
186 188
187 if (table.offset() > string_offset) { 189 if (table.offset() > string_offset) {
188 // the string storage apparently overlapped the name/tag records; 190 // the string storage apparently overlapped the name/tag records;
189 // consider this font to be badly broken 191 // consider this font to be badly broken
190 return OTS_FAILURE(); 192 return OTS_FAILURE_MSG("Bad table offset %ld > %d", table.offset(), string_o ffset);
191 } 193 }
192 194
193 // check existence of required name strings (synthesize if necessary) 195 // check existence of required name strings (synthesize if necessary)
194 // [0 - copyright - skip] 196 // [0 - copyright - skip]
195 // 1 - family 197 // 1 - family
196 // 2 - subfamily 198 // 2 - subfamily
197 // [3 - unique ID - skip] 199 // [3 - unique ID - skip]
198 // 4 - full name 200 // 4 - full name
199 // 5 - version 201 // 5 - version
200 // 6 - postscript name 202 // 6 - postscript name
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 uint16_t lang_tag_count = static_cast<uint16_t>(name->lang_tags.size()); 275 uint16_t lang_tag_count = static_cast<uint16_t>(name->lang_tags.size());
274 uint16_t format = 0; 276 uint16_t format = 0;
275 size_t string_offset = 6 + name_count * 12; 277 size_t string_offset = 6 + name_count * 12;
276 278
277 if (name->lang_tags.size() > 0) { 279 if (name->lang_tags.size() > 0) {
278 // lang tags require a format-1 name table 280 // lang tags require a format-1 name table
279 format = 1; 281 format = 1;
280 string_offset += 2 + lang_tag_count * 4; 282 string_offset += 2 + lang_tag_count * 4;
281 } 283 }
282 if (string_offset > 0xffff) { 284 if (string_offset > 0xffff) {
283 return OTS_FAILURE(); 285 return OTS_FAILURE_MSG("Bad string offset %ld", string_offset);
284 } 286 }
285 if (!out->WriteU16(format) || 287 if (!out->WriteU16(format) ||
286 !out->WriteU16(name_count) || 288 !out->WriteU16(name_count) ||
287 !out->WriteU16(static_cast<uint16_t>(string_offset))) { 289 !out->WriteU16(static_cast<uint16_t>(string_offset))) {
288 return OTS_FAILURE(); 290 return OTS_FAILURE_MSG("Failed to write name header");
289 } 291 }
290 292
291 std::string string_data; 293 std::string string_data;
292 for (std::vector<NameRecord>::const_iterator name_iter = name->names.begin(); 294 for (std::vector<NameRecord>::const_iterator name_iter = name->names.begin();
293 name_iter != name->names.end(); name_iter++) { 295 name_iter != name->names.end(); name_iter++) {
294 const NameRecord& rec = *name_iter; 296 const NameRecord& rec = *name_iter;
295 if (string_data.size() + rec.text.size() > 297 if (string_data.size() + rec.text.size() >
296 std::numeric_limits<uint16_t>::max() || 298 std::numeric_limits<uint16_t>::max() ||
297 !out->WriteU16(rec.platform_id) || 299 !out->WriteU16(rec.platform_id) ||
298 !out->WriteU16(rec.encoding_id) || 300 !out->WriteU16(rec.encoding_id) ||
299 !out->WriteU16(rec.language_id) || 301 !out->WriteU16(rec.language_id) ||
300 !out->WriteU16(rec.name_id) || 302 !out->WriteU16(rec.name_id) ||
301 !out->WriteU16(static_cast<uint16_t>(rec.text.size())) || 303 !out->WriteU16(static_cast<uint16_t>(rec.text.size())) ||
302 !out->WriteU16(static_cast<uint16_t>(string_data.size())) ) { 304 !out->WriteU16(static_cast<uint16_t>(string_data.size())) ) {
303 return OTS_FAILURE(); 305 return OTS_FAILURE_MSG("Faile to write name entry");
304 } 306 }
305 string_data.append(rec.text); 307 string_data.append(rec.text);
306 } 308 }
307 309
308 if (format == 1) { 310 if (format == 1) {
309 if (!out->WriteU16(lang_tag_count)) { 311 if (!out->WriteU16(lang_tag_count)) {
310 return OTS_FAILURE(); 312 return OTS_FAILURE_MSG("Faile to write language tag count");
311 } 313 }
312 for (std::vector<std::string>::const_iterator tag_iter = 314 for (std::vector<std::string>::const_iterator tag_iter =
313 name->lang_tags.begin(); 315 name->lang_tags.begin();
314 tag_iter != name->lang_tags.end(); tag_iter++) { 316 tag_iter != name->lang_tags.end(); tag_iter++) {
315 if (string_data.size() + tag_iter->size() > 317 if (string_data.size() + tag_iter->size() >
316 std::numeric_limits<uint16_t>::max() || 318 std::numeric_limits<uint16_t>::max() ||
317 !out->WriteU16(static_cast<uint16_t>(tag_iter->size())) || 319 !out->WriteU16(static_cast<uint16_t>(tag_iter->size())) ||
318 !out->WriteU16(static_cast<uint16_t>(string_data.size()))) { 320 !out->WriteU16(static_cast<uint16_t>(string_data.size()))) {
319 return OTS_FAILURE(); 321 return OTS_FAILURE_MSG("Failed to write string");
320 } 322 }
321 string_data.append(*tag_iter); 323 string_data.append(*tag_iter);
322 } 324 }
323 } 325 }
324 326
325 if (!out->Write(string_data.data(), string_data.size())) { 327 if (!out->Write(string_data.data(), string_data.size())) {
326 return OTS_FAILURE(); 328 return OTS_FAILURE_MSG("Faile to write string data");
327 } 329 }
328 330
329 return true; 331 return true;
330 } 332 }
331 333
332 void ots_name_free(OpenTypeFile* file) { 334 void ots_name_free(OpenTypeFile* file) {
333 delete file->name; 335 delete file->name;
334 } 336 }
335 337
336 } // namespace 338 } // namespace
339
340 #undef TABLE_NAME
OLDNEW
« .gitmodules ('K') | « src/name.h ('k') | src/os2.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698