| OLD | NEW |
| 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 // name - Naming Table | 10 // name - Naming Table |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 return OTS_FAILURE_MSG("Failed to read name count"); | 72 return OTS_FAILURE_MSG("Failed to read name count"); |
| 73 } | 73 } |
| 74 | 74 |
| 75 uint16_t string_offset = 0; | 75 uint16_t string_offset = 0; |
| 76 if (!table.ReadU16(&string_offset) || string_offset > length) { | 76 if (!table.ReadU16(&string_offset) || string_offset > length) { |
| 77 return OTS_FAILURE_MSG("Failed to read strings offset"); | 77 return OTS_FAILURE_MSG("Failed to read strings offset"); |
| 78 } | 78 } |
| 79 const char* string_base = reinterpret_cast<const char*>(data) + | 79 const char* string_base = reinterpret_cast<const char*>(data) + |
| 80 string_offset; | 80 string_offset; |
| 81 | 81 |
| 82 NameRecord prev_record; | |
| 83 bool sort_required = false; | 82 bool sort_required = false; |
| 84 | 83 |
| 85 // Read all the names, discarding any with invalid IDs, | 84 // Read all the names, discarding any with invalid IDs, |
| 86 // and any where the offset/length would be outside the table. | 85 // and any where the offset/length would be outside the table. |
| 87 // A stricter alternative would be to reject the font if there | 86 // A stricter alternative would be to reject the font if there |
| 88 // are invalid name records, but it's not clear that is necessary. | 87 // are invalid name records, but it's not clear that is necessary. |
| 89 for (unsigned i = 0; i < count; ++i) { | 88 for (unsigned i = 0; i < count; ++i) { |
| 90 NameRecord rec; | 89 NameRecord rec; |
| 91 uint16_t name_length, name_offset = 0; | 90 uint16_t name_length, name_offset = 0; |
| 92 if (!table.ReadU16(&rec.platform_id) || | 91 if (!table.ReadU16(&rec.platform_id) || |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 if (!CheckPsNameAscii(rec.text)) { | 141 if (!CheckPsNameAscii(rec.text)) { |
| 143 continue; | 142 continue; |
| 144 } | 143 } |
| 145 } else if (rec.platform_id == 0 || rec.platform_id == 3) { | 144 } else if (rec.platform_id == 0 || rec.platform_id == 3) { |
| 146 if (!CheckPsNameUtf16Be(rec.text)) { | 145 if (!CheckPsNameUtf16Be(rec.text)) { |
| 147 continue; | 146 continue; |
| 148 } | 147 } |
| 149 } | 148 } |
| 150 } | 149 } |
| 151 | 150 |
| 152 if ((i > 0) && !(prev_record < rec)) { | 151 if (!name->names.empty() && !(name->names.back() < rec)) { |
| 153 OTS_WARNING("name records are not sorted."); | 152 OTS_WARNING("name records are not sorted."); |
| 154 sort_required = true; | 153 sort_required = true; |
| 155 } | 154 } |
| 156 | 155 |
| 157 name->names.push_back(rec); | 156 name->names.push_back(rec); |
| 158 prev_record = rec; | |
| 159 } | 157 } |
| 160 | 158 |
| 161 if (format == 1) { | 159 if (format == 1) { |
| 162 // extended name table format with language tags | 160 // extended name table format with language tags |
| 163 uint16_t lang_tag_count; | 161 uint16_t lang_tag_count; |
| 164 if (!table.ReadU16(&lang_tag_count)) { | 162 if (!table.ReadU16(&lang_tag_count)) { |
| 165 return OTS_FAILURE_MSG("Failed to read language tag count"); | 163 return OTS_FAILURE_MSG("Failed to read language tag count"); |
| 166 } | 164 } |
| 167 for (unsigned i = 0; i < lang_tag_count; ++i) { | 165 for (unsigned i = 0; i < lang_tag_count; ++i) { |
| 168 uint16_t tag_length = 0; | 166 uint16_t tag_length = 0; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 "OTS derived font", | 201 "OTS derived font", |
| 204 "1.000", | 202 "1.000", |
| 205 "OTS-derived-font" | 203 "OTS-derived-font" |
| 206 }; | 204 }; |
| 207 | 205 |
| 208 // scan the names to check whether the required "standard" ones are present; | 206 // scan the names to check whether the required "standard" ones are present; |
| 209 // if not, we'll add our fixed versions here | 207 // if not, we'll add our fixed versions here |
| 210 bool mac_name[kStdNameCount] = { 0 }; | 208 bool mac_name[kStdNameCount] = { 0 }; |
| 211 bool win_name[kStdNameCount] = { 0 }; | 209 bool win_name[kStdNameCount] = { 0 }; |
| 212 for (std::vector<NameRecord>::iterator name_iter = name->names.begin(); | 210 for (std::vector<NameRecord>::iterator name_iter = name->names.begin(); |
| 213 name_iter != name->names.end(); name_iter++) { | 211 name_iter != name->names.end(); ++name_iter) { |
| 214 const uint16_t id = name_iter->name_id; | 212 const uint16_t id = name_iter->name_id; |
| 215 if (id >= kStdNameCount || kStdNames[id] == NULL) { | 213 if (id >= kStdNameCount || kStdNames[id] == NULL) { |
| 216 continue; | 214 continue; |
| 217 } | 215 } |
| 218 if (name_iter->platform_id == 1) { | 216 if (name_iter->platform_id == 1) { |
| 219 mac_name[id] = true; | 217 mac_name[id] = true; |
| 220 continue; | 218 continue; |
| 221 } | 219 } |
| 222 if (name_iter->platform_id == 3) { | 220 if (name_iter->platform_id == 3) { |
| 223 win_name[id] = true; | 221 win_name[id] = true; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 return OTS_FAILURE_MSG("Bad string offset %ld", string_offset); | 270 return OTS_FAILURE_MSG("Bad string offset %ld", string_offset); |
| 273 } | 271 } |
| 274 if (!out->WriteU16(format) || | 272 if (!out->WriteU16(format) || |
| 275 !out->WriteU16(name_count) || | 273 !out->WriteU16(name_count) || |
| 276 !out->WriteU16(static_cast<uint16_t>(string_offset))) { | 274 !out->WriteU16(static_cast<uint16_t>(string_offset))) { |
| 277 return OTS_FAILURE_MSG("Failed to write name header"); | 275 return OTS_FAILURE_MSG("Failed to write name header"); |
| 278 } | 276 } |
| 279 | 277 |
| 280 std::string string_data; | 278 std::string string_data; |
| 281 for (std::vector<NameRecord>::const_iterator name_iter = name->names.begin(); | 279 for (std::vector<NameRecord>::const_iterator name_iter = name->names.begin(); |
| 282 name_iter != name->names.end(); name_iter++) { | 280 name_iter != name->names.end(); ++name_iter) { |
| 283 const NameRecord& rec = *name_iter; | 281 const NameRecord& rec = *name_iter; |
| 284 if (string_data.size() + rec.text.size() > | 282 if (string_data.size() + rec.text.size() > |
| 285 std::numeric_limits<uint16_t>::max() || | 283 std::numeric_limits<uint16_t>::max() || |
| 286 !out->WriteU16(rec.platform_id) || | 284 !out->WriteU16(rec.platform_id) || |
| 287 !out->WriteU16(rec.encoding_id) || | 285 !out->WriteU16(rec.encoding_id) || |
| 288 !out->WriteU16(rec.language_id) || | 286 !out->WriteU16(rec.language_id) || |
| 289 !out->WriteU16(rec.name_id) || | 287 !out->WriteU16(rec.name_id) || |
| 290 !out->WriteU16(static_cast<uint16_t>(rec.text.size())) || | 288 !out->WriteU16(static_cast<uint16_t>(rec.text.size())) || |
| 291 !out->WriteU16(static_cast<uint16_t>(string_data.size())) ) { | 289 !out->WriteU16(static_cast<uint16_t>(string_data.size())) ) { |
| 292 return OTS_FAILURE_MSG("Faile to write name entry"); | 290 return OTS_FAILURE_MSG("Faile to write name entry"); |
| 293 } | 291 } |
| 294 string_data.append(rec.text); | 292 string_data.append(rec.text); |
| 295 } | 293 } |
| 296 | 294 |
| 297 if (format == 1) { | 295 if (format == 1) { |
| 298 if (!out->WriteU16(lang_tag_count)) { | 296 if (!out->WriteU16(lang_tag_count)) { |
| 299 return OTS_FAILURE_MSG("Faile to write language tag count"); | 297 return OTS_FAILURE_MSG("Faile to write language tag count"); |
| 300 } | 298 } |
| 301 for (std::vector<std::string>::const_iterator tag_iter = | 299 for (std::vector<std::string>::const_iterator tag_iter = |
| 302 name->lang_tags.begin(); | 300 name->lang_tags.begin(); |
| 303 tag_iter != name->lang_tags.end(); tag_iter++) { | 301 tag_iter != name->lang_tags.end(); ++tag_iter) { |
| 304 if (string_data.size() + tag_iter->size() > | 302 if (string_data.size() + tag_iter->size() > |
| 305 std::numeric_limits<uint16_t>::max() || | 303 std::numeric_limits<uint16_t>::max() || |
| 306 !out->WriteU16(static_cast<uint16_t>(tag_iter->size())) || | 304 !out->WriteU16(static_cast<uint16_t>(tag_iter->size())) || |
| 307 !out->WriteU16(static_cast<uint16_t>(string_data.size()))) { | 305 !out->WriteU16(static_cast<uint16_t>(string_data.size()))) { |
| 308 return OTS_FAILURE_MSG("Failed to write string"); | 306 return OTS_FAILURE_MSG("Failed to write string"); |
| 309 } | 307 } |
| 310 string_data.append(*tag_iter); | 308 string_data.append(*tag_iter); |
| 311 } | 309 } |
| 312 } | 310 } |
| 313 | 311 |
| 314 if (!out->Write(string_data.data(), string_data.size())) { | 312 if (!out->Write(string_data.data(), string_data.size())) { |
| 315 return OTS_FAILURE_MSG("Faile to write string data"); | 313 return OTS_FAILURE_MSG("Faile to write string data"); |
| 316 } | 314 } |
| 317 | 315 |
| 318 return true; | 316 return true; |
| 319 } | 317 } |
| 320 | 318 |
| 321 void ots_name_reuse(Font *font, Font *other) { | 319 void ots_name_reuse(Font *font, Font *other) { |
| 322 font->name = other->name; | 320 font->name = other->name; |
| 323 font->name_reused = true; | 321 font->name_reused = true; |
| 324 } | 322 } |
| 325 | 323 |
| 326 void ots_name_free(Font *font) { | 324 void ots_name_free(Font *font) { |
| 327 delete font->name; | 325 delete font->name; |
| 328 } | 326 } |
| 329 | 327 |
| 330 } // namespace | 328 } // namespace |
| 331 | 329 |
| 332 #undef TABLE_NAME | 330 #undef TABLE_NAME |
| OLD | NEW |