| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "ots.h" | 5 #include "ots.h" |
| 6 | 6 |
| 7 #include <sys/types.h> | 7 #include <sys/types.h> |
| 8 #include <zlib.h> | 8 #include <zlib.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <cstdlib> | 11 #include <cstdlib> |
| 12 #include <cstring> | 12 #include <cstring> |
| 13 #include <limits> | 13 #include <limits> |
| 14 #include <map> | 14 #include <map> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "woff2.h" | 17 #include "third_party/woff2/src/woff2_dec.h" |
| 18 | 18 |
| 19 // The OpenType Font File | 19 // The OpenType Font File |
| 20 // http://www.microsoft.com/typography/otspec/cmap.htm | 20 // http://www.microsoft.com/typography/otspec/cmap.htm |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 // Generate a message with or without a table tag, when 'header' is the OpenType
File pointer | 24 // Generate a message with or without a table tag, when 'header' is the OpenType
File pointer |
| 25 #define OTS_FAILURE_MSG_TAG(msg_,tag_) OTS_FAILURE_MSG_TAG_(header, msg_, tag_) | 25 #define OTS_FAILURE_MSG_TAG(msg_,tag_) OTS_FAILURE_MSG_TAG_(header, msg_, tag_) |
| 26 #define OTS_FAILURE_MSG_HDR(msg_) OTS_FAILURE_MSG_(header, msg_) | 26 #define OTS_FAILURE_MSG_HDR(msg_) OTS_FAILURE_MSG_(header, msg_) |
| 27 #define OTS_WARNING_MSG_HDR(msg_) OTS_WARNING_MSG_(header, msg_) | 27 #define OTS_WARNING_MSG_HDR(msg_) OTS_WARNING_MSG_(header, msg_) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 private: | 64 private: |
| 65 std::vector<uint8_t*> hunks_; | 65 std::vector<uint8_t*> hunks_; |
| 66 }; | 66 }; |
| 67 | 67 |
| 68 const struct { | 68 const struct { |
| 69 uint32_t tag; | 69 uint32_t tag; |
| 70 bool (*parse)(ots::Font *font, const uint8_t *data, size_t length); | 70 bool (*parse)(ots::Font *font, const uint8_t *data, size_t length); |
| 71 bool (*serialise)(ots::OTSStream *out, ots::Font *font); | 71 bool (*serialise)(ots::OTSStream *out, ots::Font *font); |
| 72 bool (*should_serialise)(ots::Font *font); | 72 bool (*should_serialise)(ots::Font *font); |
| 73 void (*reuse)(ots::Font *font, ots::Font *other); | 73 void (*reuse)(ots::Font *font, ots::Font *other); |
| 74 void (*free)(ots::Font *font); | |
| 75 bool required; | 74 bool required; |
| 76 } table_parsers[] = { | 75 } table_parsers[] = { |
| 77 { OTS_TAG('m','a','x','p'), ots::ots_maxp_parse, ots::ots_maxp_serialise, | 76 { OTS_TAG('m','a','x','p'), ots::ots_maxp_parse, ots::ots_maxp_serialise, |
| 78 ots::ots_maxp_should_serialise, ots::ots_maxp_reuse, ots::ots_maxp_free, | 77 ots::ots_maxp_should_serialise, ots::ots_maxp_reuse, true }, |
| 79 true }, | |
| 80 { OTS_TAG('h','e','a','d'), ots::ots_head_parse, ots::ots_head_serialise, | 78 { OTS_TAG('h','e','a','d'), ots::ots_head_parse, ots::ots_head_serialise, |
| 81 ots::ots_head_should_serialise, ots::ots_head_reuse, ots::ots_head_free, | 79 ots::ots_head_should_serialise, ots::ots_head_reuse, true }, |
| 82 true }, | |
| 83 { OTS_TAG('O','S','/','2'), ots::ots_os2_parse, ots::ots_os2_serialise, | 80 { OTS_TAG('O','S','/','2'), ots::ots_os2_parse, ots::ots_os2_serialise, |
| 84 ots::ots_os2_should_serialise, ots::ots_os2_reuse, ots::ots_os2_free, | 81 ots::ots_os2_should_serialise, ots::ots_os2_reuse, true }, |
| 85 true }, | |
| 86 { OTS_TAG('c','m','a','p'), ots::ots_cmap_parse, ots::ots_cmap_serialise, | 82 { OTS_TAG('c','m','a','p'), ots::ots_cmap_parse, ots::ots_cmap_serialise, |
| 87 ots::ots_cmap_should_serialise, ots::ots_cmap_reuse, ots::ots_cmap_free, | 83 ots::ots_cmap_should_serialise, ots::ots_cmap_reuse, true }, |
| 88 true }, | |
| 89 { OTS_TAG('h','h','e','a'), ots::ots_hhea_parse, ots::ots_hhea_serialise, | 84 { OTS_TAG('h','h','e','a'), ots::ots_hhea_parse, ots::ots_hhea_serialise, |
| 90 ots::ots_hhea_should_serialise, ots::ots_hhea_reuse, ots::ots_hhea_free, | 85 ots::ots_hhea_should_serialise, ots::ots_hhea_reuse, true }, |
| 91 true }, | |
| 92 { OTS_TAG('h','m','t','x'), ots::ots_hmtx_parse, ots::ots_hmtx_serialise, | 86 { OTS_TAG('h','m','t','x'), ots::ots_hmtx_parse, ots::ots_hmtx_serialise, |
| 93 ots::ots_hmtx_should_serialise, ots::ots_hmtx_reuse, ots::ots_hmtx_free, | 87 ots::ots_hmtx_should_serialise, ots::ots_hmtx_reuse, true }, |
| 94 true }, | |
| 95 { OTS_TAG('n','a','m','e'), ots::ots_name_parse, ots::ots_name_serialise, | 88 { OTS_TAG('n','a','m','e'), ots::ots_name_parse, ots::ots_name_serialise, |
| 96 ots::ots_name_should_serialise, ots::ots_name_reuse, ots::ots_name_free, | 89 ots::ots_name_should_serialise, ots::ots_name_reuse, true }, |
| 97 true }, | |
| 98 { OTS_TAG('p','o','s','t'), ots::ots_post_parse, ots::ots_post_serialise, | 90 { OTS_TAG('p','o','s','t'), ots::ots_post_parse, ots::ots_post_serialise, |
| 99 ots::ots_post_should_serialise, ots::ots_post_reuse, ots::ots_post_free, | 91 ots::ots_post_should_serialise, ots::ots_post_reuse, true }, |
| 100 true }, | |
| 101 { OTS_TAG('l','o','c','a'), ots::ots_loca_parse, ots::ots_loca_serialise, | 92 { OTS_TAG('l','o','c','a'), ots::ots_loca_parse, ots::ots_loca_serialise, |
| 102 ots::ots_loca_should_serialise, ots::ots_loca_reuse, ots::ots_loca_free, | 93 ots::ots_loca_should_serialise, ots::ots_loca_reuse, false }, |
| 103 false }, | |
| 104 { OTS_TAG('g','l','y','f'), ots::ots_glyf_parse, ots::ots_glyf_serialise, | 94 { OTS_TAG('g','l','y','f'), ots::ots_glyf_parse, ots::ots_glyf_serialise, |
| 105 ots::ots_glyf_should_serialise, ots::ots_glyf_reuse, ots::ots_glyf_free, | 95 ots::ots_glyf_should_serialise, ots::ots_glyf_reuse, false }, |
| 106 false }, | |
| 107 { OTS_TAG('C','F','F',' '), ots::ots_cff_parse, ots::ots_cff_serialise, | 96 { OTS_TAG('C','F','F',' '), ots::ots_cff_parse, ots::ots_cff_serialise, |
| 108 ots::ots_cff_should_serialise, ots::ots_cff_reuse, ots::ots_cff_free, | 97 ots::ots_cff_should_serialise, ots::ots_cff_reuse, false }, |
| 109 false }, | |
| 110 { OTS_TAG('V','D','M','X'), ots::ots_vdmx_parse, ots::ots_vdmx_serialise, | 98 { OTS_TAG('V','D','M','X'), ots::ots_vdmx_parse, ots::ots_vdmx_serialise, |
| 111 ots::ots_vdmx_should_serialise, ots::ots_vdmx_reuse, ots::ots_vdmx_free, | 99 ots::ots_vdmx_should_serialise, ots::ots_vdmx_reuse, false }, |
| 112 false }, | |
| 113 { OTS_TAG('h','d','m','x'), ots::ots_hdmx_parse, ots::ots_hdmx_serialise, | 100 { OTS_TAG('h','d','m','x'), ots::ots_hdmx_parse, ots::ots_hdmx_serialise, |
| 114 ots::ots_hdmx_should_serialise, ots::ots_hdmx_reuse, ots::ots_hdmx_free, | 101 ots::ots_hdmx_should_serialise, ots::ots_hdmx_reuse, false }, |
| 115 false }, | |
| 116 { OTS_TAG('g','a','s','p'), ots::ots_gasp_parse, ots::ots_gasp_serialise, | 102 { OTS_TAG('g','a','s','p'), ots::ots_gasp_parse, ots::ots_gasp_serialise, |
| 117 ots::ots_gasp_should_serialise, ots::ots_gasp_reuse, ots::ots_gasp_free, | 103 ots::ots_gasp_should_serialise, ots::ots_gasp_reuse, false }, |
| 118 false }, | |
| 119 { OTS_TAG('c','v','t',' '), ots::ots_cvt_parse, ots::ots_cvt_serialise, | 104 { OTS_TAG('c','v','t',' '), ots::ots_cvt_parse, ots::ots_cvt_serialise, |
| 120 ots::ots_cvt_should_serialise, ots::ots_cvt_reuse, ots::ots_cvt_free, | 105 ots::ots_cvt_should_serialise, ots::ots_cvt_reuse, false }, |
| 121 false }, | |
| 122 { OTS_TAG('f','p','g','m'), ots::ots_fpgm_parse, ots::ots_fpgm_serialise, | 106 { OTS_TAG('f','p','g','m'), ots::ots_fpgm_parse, ots::ots_fpgm_serialise, |
| 123 ots::ots_fpgm_should_serialise, ots::ots_fpgm_reuse, ots::ots_fpgm_free, | 107 ots::ots_fpgm_should_serialise, ots::ots_fpgm_reuse, false }, |
| 124 false }, | |
| 125 { OTS_TAG('p','r','e','p'), ots::ots_prep_parse, ots::ots_prep_serialise, | 108 { OTS_TAG('p','r','e','p'), ots::ots_prep_parse, ots::ots_prep_serialise, |
| 126 ots::ots_prep_should_serialise, ots::ots_prep_reuse, ots::ots_prep_free, | 109 ots::ots_prep_should_serialise, ots::ots_prep_reuse, false }, |
| 127 false }, | |
| 128 { OTS_TAG('L','T','S','H'), ots::ots_ltsh_parse, ots::ots_ltsh_serialise, | 110 { OTS_TAG('L','T','S','H'), ots::ots_ltsh_parse, ots::ots_ltsh_serialise, |
| 129 ots::ots_ltsh_should_serialise, ots::ots_ltsh_reuse, ots::ots_ltsh_free, | 111 ots::ots_ltsh_should_serialise, ots::ots_ltsh_reuse, false }, |
| 130 false }, | |
| 131 { OTS_TAG('V','O','R','G'), ots::ots_vorg_parse, ots::ots_vorg_serialise, | 112 { OTS_TAG('V','O','R','G'), ots::ots_vorg_parse, ots::ots_vorg_serialise, |
| 132 ots::ots_vorg_should_serialise, ots::ots_vorg_reuse, ots::ots_vorg_free, | 113 ots::ots_vorg_should_serialise, ots::ots_vorg_reuse, false }, |
| 133 false }, | |
| 134 { OTS_TAG('k','e','r','n'), ots::ots_kern_parse, ots::ots_kern_serialise, | 114 { OTS_TAG('k','e','r','n'), ots::ots_kern_parse, ots::ots_kern_serialise, |
| 135 ots::ots_kern_should_serialise, ots::ots_kern_reuse, ots::ots_kern_free, | 115 ots::ots_kern_should_serialise, ots::ots_kern_reuse, false }, |
| 136 false }, | |
| 137 // We need to parse GDEF table in advance of parsing GSUB/GPOS tables | 116 // We need to parse GDEF table in advance of parsing GSUB/GPOS tables |
| 138 // because they could refer GDEF table. | 117 // because they could refer GDEF table. |
| 139 { OTS_TAG('G','D','E','F'), ots::ots_gdef_parse, ots::ots_gdef_serialise, | 118 { OTS_TAG('G','D','E','F'), ots::ots_gdef_parse, ots::ots_gdef_serialise, |
| 140 ots::ots_gdef_should_serialise, ots::ots_gdef_reuse, ots::ots_gdef_free, | 119 ots::ots_gdef_should_serialise, ots::ots_gdef_reuse, false }, |
| 141 false }, | |
| 142 { OTS_TAG('G','P','O','S'), ots::ots_gpos_parse, ots::ots_gpos_serialise, | 120 { OTS_TAG('G','P','O','S'), ots::ots_gpos_parse, ots::ots_gpos_serialise, |
| 143 ots::ots_gpos_should_serialise, ots::ots_gpos_reuse, ots::ots_gpos_free, | 121 ots::ots_gpos_should_serialise, ots::ots_gpos_reuse, false }, |
| 144 false }, | |
| 145 { OTS_TAG('G','S','U','B'), ots::ots_gsub_parse, ots::ots_gsub_serialise, | 122 { OTS_TAG('G','S','U','B'), ots::ots_gsub_parse, ots::ots_gsub_serialise, |
| 146 ots::ots_gsub_should_serialise, ots::ots_gsub_reuse, ots::ots_gsub_free, | 123 ots::ots_gsub_should_serialise, ots::ots_gsub_reuse, false }, |
| 147 false }, | |
| 148 { OTS_TAG('v','h','e','a'), ots::ots_vhea_parse, ots::ots_vhea_serialise, | 124 { OTS_TAG('v','h','e','a'), ots::ots_vhea_parse, ots::ots_vhea_serialise, |
| 149 ots::ots_vhea_should_serialise, ots::ots_vhea_reuse, ots::ots_vhea_free, | 125 ots::ots_vhea_should_serialise, ots::ots_vhea_reuse, false }, |
| 150 false }, | |
| 151 { OTS_TAG('v','m','t','x'), ots::ots_vmtx_parse, ots::ots_vmtx_serialise, | 126 { OTS_TAG('v','m','t','x'), ots::ots_vmtx_parse, ots::ots_vmtx_serialise, |
| 152 ots::ots_vmtx_should_serialise, ots::ots_vmtx_reuse, ots::ots_vmtx_free, | 127 ots::ots_vmtx_should_serialise, ots::ots_vmtx_reuse, false }, |
| 153 false }, | |
| 154 { OTS_TAG('M','A','T','H'), ots::ots_math_parse, ots::ots_math_serialise, | 128 { OTS_TAG('M','A','T','H'), ots::ots_math_parse, ots::ots_math_serialise, |
| 155 ots::ots_math_should_serialise, ots::ots_math_reuse, ots::ots_math_free, | 129 ots::ots_math_should_serialise, ots::ots_math_reuse, false }, |
| 156 false }, | 130 { 0, NULL, NULL, NULL, NULL, false }, |
| 157 { 0, NULL, NULL, NULL, NULL, NULL, false }, | |
| 158 }; | 131 }; |
| 159 | 132 |
| 160 bool ProcessGeneric(ots::OpenTypeFile *header, | 133 bool ProcessGeneric(ots::OpenTypeFile *header, |
| 161 ots::Font *font, | 134 ots::Font *font, |
| 162 uint32_t signature, | 135 uint32_t signature, |
| 163 ots::OTSStream *output, | 136 ots::OTSStream *output, |
| 164 const uint8_t *data, size_t length, | 137 const uint8_t *data, size_t length, |
| 165 const std::vector<OpenTypeTable>& tables, | 138 const std::vector<OpenTypeTable>& tables, |
| 166 ots::Buffer& file); | 139 ots::Buffer& file); |
| 167 | 140 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 return OTS_FAILURE_MSG_HDR("invalid WOFF marker"); | 327 return OTS_FAILURE_MSG_HDR("invalid WOFF marker"); |
| 355 } | 328 } |
| 356 | 329 |
| 357 if (!file.ReadU32(&font->version)) { | 330 if (!file.ReadU32(&font->version)) { |
| 358 return OTS_FAILURE_MSG_HDR("error reading version tag"); | 331 return OTS_FAILURE_MSG_HDR("error reading version tag"); |
| 359 } | 332 } |
| 360 if (!ots::IsValidVersionTag(font->version)) { | 333 if (!ots::IsValidVersionTag(font->version)) { |
| 361 return OTS_FAILURE_MSG_HDR("invalid version tag"); | 334 return OTS_FAILURE_MSG_HDR("invalid version tag"); |
| 362 } | 335 } |
| 363 | 336 |
| 364 font->search_range = 0; | |
| 365 font->entry_selector = 0; | |
| 366 font->range_shift = 0; | |
| 367 | |
| 368 uint32_t reported_length; | 337 uint32_t reported_length; |
| 369 if (!file.ReadU32(&reported_length) || length != reported_length) { | 338 if (!file.ReadU32(&reported_length) || length != reported_length) { |
| 370 return OTS_FAILURE_MSG_HDR("incorrect file size in WOFF header"); | 339 return OTS_FAILURE_MSG_HDR("incorrect file size in WOFF header"); |
| 371 } | 340 } |
| 372 | 341 |
| 373 if (!file.ReadU16(&font->num_tables) || !font->num_tables) { | 342 if (!file.ReadU16(&font->num_tables) || !font->num_tables) { |
| 374 return OTS_FAILURE_MSG_HDR("error reading number of tables"); | 343 return OTS_FAILURE_MSG_HDR("error reading number of tables"); |
| 375 } | 344 } |
| 376 | 345 |
| 377 uint16_t reserved_value; | 346 uint16_t reserved_value; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 } | 457 } |
| 489 } | 458 } |
| 490 if (block_end != ots::Round4(length)) { | 459 if (block_end != ots::Round4(length)) { |
| 491 return OTS_FAILURE_MSG_HDR("File length mismatch (trailing junk?)"); | 460 return OTS_FAILURE_MSG_HDR("File length mismatch (trailing junk?)"); |
| 492 } | 461 } |
| 493 | 462 |
| 494 return ProcessGeneric(header, font, woff_tag, output, data, length, tables, fi
le); | 463 return ProcessGeneric(header, font, woff_tag, output, data, length, tables, fi
le); |
| 495 } | 464 } |
| 496 | 465 |
| 497 bool ProcessWOFF2(ots::OpenTypeFile *header, | 466 bool ProcessWOFF2(ots::OpenTypeFile *header, |
| 498 ots::Font *font, | 467 ots::OTSStream *output, |
| 499 ots::OTSStream *output, const uint8_t *data, size_t length) { | 468 const uint8_t *data, |
| 500 size_t decompressed_size = ots::ComputeWOFF2FinalSize(data, length); | 469 size_t length, |
| 470 uint32_t index) { |
| 471 size_t decompressed_size = woff2::ComputeWOFF2FinalSize(data, length); |
| 501 | 472 |
| 502 if (decompressed_size == 0) { | 473 if (decompressed_size == 0) { |
| 503 return OTS_FAILURE_MSG_HDR("Size of decompressed WOFF 2.0 is set to 0"); | 474 return OTS_FAILURE_MSG_HDR("Size of decompressed WOFF 2.0 is set to 0"); |
| 504 } | 475 } |
| 505 // decompressed font must be <= 30MB | 476 // decompressed font must be <= 30MB |
| 506 if (decompressed_size > 30 * 1024 * 1024) { | 477 if (decompressed_size > 30 * 1024 * 1024) { |
| 507 return OTS_FAILURE_MSG_HDR("Size of decompressed WOFF 2.0 font exceeds 30MB"
); | 478 return OTS_FAILURE_MSG_HDR("Size of decompressed WOFF 2.0 font exceeds 30MB"
); |
| 508 } | 479 } |
| 509 | 480 |
| 510 std::vector<uint8_t> decompressed_buffer(decompressed_size); | 481 std::vector<uint8_t> decompressed_buffer(decompressed_size); |
| 511 if (!ots::ConvertWOFF2ToSFNT(font, &decompressed_buffer[0], decompressed_size, | 482 if (!woff2::ConvertWOFF2ToTTF(&decompressed_buffer[0], decompressed_size, |
| 512 data, length)) { | 483 data, length)) { |
| 513 return OTS_FAILURE_MSG_HDR("Failed to convert WOFF 2.0 font to SFNT"); | 484 return OTS_FAILURE_MSG_HDR("Failed to convert WOFF 2.0 font to SFNT"); |
| 514 } | 485 } |
| 515 return ProcessTTF(header, font, output, &decompressed_buffer[0], decompressed_
size); | 486 |
| 487 if (data[4] == 't' && data[5] == 't' && data[6] == 'c' && data[7] == 'f') { |
| 488 return ProcessTTC(header, output, &decompressed_buffer[0], decompressed_size
, index); |
| 489 } else { |
| 490 ots::Font font(header); |
| 491 return ProcessTTF(header, &font, output, &decompressed_buffer[0], decompress
ed_size); |
| 492 } |
| 516 } | 493 } |
| 517 | 494 |
| 518 ots::TableAction GetTableAction(ots::OpenTypeFile *header, uint32_t tag) { | 495 ots::TableAction GetTableAction(ots::OpenTypeFile *header, uint32_t tag) { |
| 519 ots::TableAction action = ots::TABLE_ACTION_DEFAULT; | 496 ots::TableAction action = header->context->GetTableAction(tag); |
| 520 | |
| 521 action = header->context->GetTableAction(htonl(tag)); | |
| 522 | 497 |
| 523 if (action == ots::TABLE_ACTION_DEFAULT) { | 498 if (action == ots::TABLE_ACTION_DEFAULT) { |
| 524 action = ots::TABLE_ACTION_DROP; | 499 action = ots::TABLE_ACTION_DROP; |
| 525 | 500 |
| 526 for (unsigned i = 0; ; ++i) { | 501 for (unsigned i = 0; ; ++i) { |
| 527 if (table_parsers[i].parse == NULL) break; | 502 if (table_parsers[i].parse == NULL) break; |
| 528 | 503 |
| 529 if (table_parsers[i].tag == tag) { | 504 if (table_parsers[i].tag == tag) { |
| 530 action = ots::TABLE_ACTION_SANITIZE; | 505 action = ots::TABLE_ACTION_SANITIZE; |
| 531 break; | 506 break; |
| 532 } | 507 } |
| 533 } | 508 } |
| 534 } | 509 } |
| 535 | 510 |
| 536 assert(action != ots::TABLE_ACTION_DEFAULT); // Should never return this. | 511 assert(action != ots::TABLE_ACTION_DEFAULT); // Should never return this. |
| 537 return action; | 512 return action; |
| 538 } | 513 } |
| 539 | 514 |
| 540 bool GetTableData(const uint8_t *data, | 515 bool GetTableData(const uint8_t *data, |
| 541 const OpenTypeTable table, | 516 const OpenTypeTable& table, |
| 542 Arena *arena, | 517 Arena *arena, |
| 543 size_t *table_length, | 518 size_t *table_length, |
| 544 const uint8_t **table_data) { | 519 const uint8_t **table_data) { |
| 545 if (table.uncompressed_length != table.length) { | 520 if (table.uncompressed_length != table.length) { |
| 546 // Compressed table. Need to uncompress into memory first. | 521 // Compressed table. Need to uncompress into memory first. |
| 547 *table_length = table.uncompressed_length; | 522 *table_length = table.uncompressed_length; |
| 548 *table_data = (*arena).Allocate(*table_length); | 523 *table_data = (*arena).Allocate(*table_length); |
| 549 uLongf dest_len = *table_length; | 524 uLongf dest_len = *table_length; |
| 550 int r = uncompress((Bytef*) *table_data, &dest_len, | 525 int r = uncompress((Bytef*) *table_data, &dest_len, |
| 551 data + table.offset, table.length); | 526 data + table.offset, table.length); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 if (ot == header->tables.end()) { | 659 if (ot == header->tables.end()) { |
| 685 const uint8_t* table_data; | 660 const uint8_t* table_data; |
| 686 size_t table_length; | 661 size_t table_length; |
| 687 | 662 |
| 688 if (!GetTableData(data, it->second, &arena, &table_length, &table_data)) { | 663 if (!GetTableData(data, it->second, &arena, &table_length, &table_data)) { |
| 689 return OTS_FAILURE_MSG_TAG("uncompress failed", table_parsers[i].tag); | 664 return OTS_FAILURE_MSG_TAG("uncompress failed", table_parsers[i].tag); |
| 690 } | 665 } |
| 691 | 666 |
| 692 if (action == ots::TABLE_ACTION_SANITIZE && | 667 if (action == ots::TABLE_ACTION_SANITIZE && |
| 693 !table_parsers[i].parse(font, table_data, table_length)) { | 668 !table_parsers[i].parse(font, table_data, table_length)) { |
| 694 // TODO: parsers should generate specific messages detailing the failure
; | 669 return OTS_FAILURE(); |
| 695 // once those are all added, we won't need a generic failure message her
e | |
| 696 return OTS_FAILURE_MSG_TAG("failed to parse table", table_parsers[i].tag
); | |
| 697 } | 670 } |
| 698 } else if (action == ots::TABLE_ACTION_SANITIZE) { | 671 } else if (action == ots::TABLE_ACTION_SANITIZE) { |
| 699 table_parsers[i].reuse(font, ot->second.first); | 672 table_parsers[i].reuse(font, ot->second.first); |
| 700 } | 673 } |
| 701 } | 674 } |
| 702 | 675 |
| 703 if (font->cff) { | 676 if (font->cff) { |
| 704 // font with PostScript glyph | 677 // font with PostScript glyph |
| 705 if (font->version != OTS_TAG('O','T','T','O')) { | 678 if (font->version != OTS_TAG('O','T','T','O')) { |
| 706 return OTS_FAILURE_MSG_HDR("wrong font version for PostScript glyph data")
; | 679 return OTS_FAILURE_MSG_HDR("wrong font version for PostScript glyph data")
; |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 header.context = this; | 886 header.context = this; |
| 914 | 887 |
| 915 if (length < 4) { | 888 if (length < 4) { |
| 916 return OTS_FAILURE_MSG_(&header, "file less than 4 bytes"); | 889 return OTS_FAILURE_MSG_(&header, "file less than 4 bytes"); |
| 917 } | 890 } |
| 918 | 891 |
| 919 bool result; | 892 bool result; |
| 920 if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') { | 893 if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') { |
| 921 result = ProcessWOFF(&header, &font, output, data, length); | 894 result = ProcessWOFF(&header, &font, output, data, length); |
| 922 } else if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2
') { | 895 } else if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2
') { |
| 923 result = ProcessWOFF2(&header, &font, output, data, length); | 896 result = ProcessWOFF2(&header, output, data, length, index); |
| 924 } else if (data[0] == 't' && data[1] == 't' && data[2] == 'c' && data[3] == 'f
') { | 897 } else if (data[0] == 't' && data[1] == 't' && data[2] == 'c' && data[3] == 'f
') { |
| 925 result = ProcessTTC(&header, output, data, length, index); | 898 result = ProcessTTC(&header, output, data, length, index); |
| 926 } else { | 899 } else { |
| 927 result = ProcessTTF(&header, &font, output, data, length); | 900 result = ProcessTTF(&header, &font, output, data, length); |
| 928 } | 901 } |
| 929 | 902 |
| 930 return result; | 903 return result; |
| 931 } | 904 } |
| 932 | 905 |
| 933 } // namespace ots | 906 } // namespace ots |
| OLD | NEW |