| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "cff.h" | 5 #include "cff.h" |
| 6 | 6 |
| 7 #include <cstring> | 7 #include <cstring> |
| 8 #include <utility> // std::pair | 8 #include <utility> // std::pair |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "cff_type2_charstring.h" | 11 #include "cff_type2_charstring.h" |
| 12 | 12 |
| 13 // CFF - PostScript font program (Compact Font Format) table | 13 // CFF - PostScript font program (Compact Font Format) table |
| 14 // http://www.microsoft.com/opentype/otspec/cff.htm | 14 // http://www.microsoft.com/typography/otspec/cff.htm |
| 15 // http://www.microsoft.com/opentype/otspec/5176.CFF.pdf | 15 // http://www.microsoft.com/typography/otspec/cffspec.htm |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 enum DICT_OPERAND_TYPE { | 19 enum DICT_OPERAND_TYPE { |
| 20 DICT_OPERAND_INTEGER, | 20 DICT_OPERAND_INTEGER, |
| 21 DICT_OPERAND_REAL, | 21 DICT_OPERAND_REAL, |
| 22 DICT_OPERATOR, | 22 DICT_OPERATOR, |
| 23 }; | 23 }; |
| 24 | 24 |
| 25 enum DICT_DATA_TYPE { | 25 enum DICT_DATA_TYPE { |
| 26 DICT_DATA_TOPLEVEL, | 26 DICT_DATA_TOPLEVEL, |
| 27 DICT_DATA_FDARRAY, | 27 DICT_DATA_FDARRAY, |
| 28 }; | 28 }; |
| 29 | 29 |
| 30 enum FONT_FORMAT { |
| 31 FORMAT_UNKNOWN, |
| 32 FORMAT_CID_KEYED, |
| 33 FORMAT_OTHER, // Including synthetic fonts |
| 34 }; |
| 35 |
| 30 // see Appendix. A | 36 // see Appendix. A |
| 31 const size_t kNStdString = 390; | 37 const size_t kNStdString = 390; |
| 32 | 38 |
| 33 bool ReadOffset(ots::Buffer *table, uint8_t off_size, uint32_t *offset) { | 39 bool ReadOffset(ots::Buffer *table, uint8_t off_size, uint32_t *offset) { |
| 34 if (off_size > 4) { | 40 if (off_size > 4) { |
| 35 return OTS_FAILURE(); | 41 return OTS_FAILURE(); |
| 36 } | 42 } |
| 37 | 43 |
| 38 uint32_t tmp32 = 0; | 44 uint32_t tmp32 = 0; |
| 39 for (unsigned i = 0; i < off_size; ++i) { | 45 for (unsigned i = 0; i < off_size; ++i) { |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 DICT_DATA_TYPE type, ots::OpenTypeCFF *out_cff) { | 463 DICT_DATA_TYPE type, ots::OpenTypeCFF *out_cff) { |
| 458 for (unsigned i = 1; i < index.offsets.size(); ++i) { | 464 for (unsigned i = 1; i < index.offsets.size(); ++i) { |
| 459 if (type == DICT_DATA_TOPLEVEL) { | 465 if (type == DICT_DATA_TOPLEVEL) { |
| 460 out_cff->char_strings_array.push_back(new ots::CFFIndex); | 466 out_cff->char_strings_array.push_back(new ots::CFFIndex); |
| 461 } | 467 } |
| 462 size_t dict_length = index.offsets[i] - index.offsets[i - 1]; | 468 size_t dict_length = index.offsets[i] - index.offsets[i - 1]; |
| 463 ots::Buffer table(data + index.offsets[i - 1], dict_length); | 469 ots::Buffer table(data + index.offsets[i - 1], dict_length); |
| 464 | 470 |
| 465 std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > operands; | 471 std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > operands; |
| 466 | 472 |
| 473 FONT_FORMAT font_format = FORMAT_UNKNOWN; |
| 467 bool have_ros = false; | 474 bool have_ros = false; |
| 468 size_t glyphs = 0; | 475 size_t glyphs = 0; |
| 469 size_t charset_offset = 0; | 476 size_t charset_offset = 0; |
| 470 | 477 |
| 471 while (table.offset() < dict_length) { | 478 while (table.offset() < dict_length) { |
| 472 if (!ParseDictDataReadNext(&table, &operands)) { | 479 if (!ParseDictDataReadNext(&table, &operands)) { |
| 473 return OTS_FAILURE(); | 480 return OTS_FAILURE(); |
| 474 } | 481 } |
| 475 if (operands.empty()) { | 482 if (operands.empty()) { |
| 476 return OTS_FAILURE(); | 483 return OTS_FAILURE(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 break; | 522 break; |
| 516 | 523 |
| 517 // number | 524 // number |
| 518 case 13: // UniqueID | 525 case 13: // UniqueID |
| 519 case (12U << 8) + 2: // ItalicAngle | 526 case (12U << 8) + 2: // ItalicAngle |
| 520 case (12U << 8) + 3: // UnderlinePosition | 527 case (12U << 8) + 3: // UnderlinePosition |
| 521 case (12U << 8) + 4: // UnderlineThickness | 528 case (12U << 8) + 4: // UnderlineThickness |
| 522 case (12U << 8) + 5: // PaintType | 529 case (12U << 8) + 5: // PaintType |
| 523 case (12U << 8) + 8: // StrokeWidth | 530 case (12U << 8) + 8: // StrokeWidth |
| 524 case (12U << 8) + 20: // SyntheticBase | 531 case (12U << 8) + 20: // SyntheticBase |
| 532 if (operands.size() != 1) { |
| 533 return OTS_FAILURE(); |
| 534 } |
| 535 break; |
| 525 case (12U << 8) + 31: // CIDFontVersion | 536 case (12U << 8) + 31: // CIDFontVersion |
| 526 case (12U << 8) + 32: // CIDFontRevision | 537 case (12U << 8) + 32: // CIDFontRevision |
| 527 case (12U << 8) + 33: // CIDFontType | 538 case (12U << 8) + 33: // CIDFontType |
| 528 case (12U << 8) + 34: // CIDCount | 539 case (12U << 8) + 34: // CIDCount |
| 529 case (12U << 8) + 35: // UIDBase | 540 case (12U << 8) + 35: // UIDBase |
| 530 if (operands.size() != 1) { | 541 if (operands.size() != 1) { |
| 531 return OTS_FAILURE(); | 542 return OTS_FAILURE(); |
| 532 } | 543 } |
| 544 if (font_format != FORMAT_CID_KEYED) { |
| 545 return OTS_FAILURE(); |
| 546 } |
| 533 break; | 547 break; |
| 534 case (12U << 8) + 6: // CharstringType | 548 case (12U << 8) + 6: // CharstringType |
| 535 if (operands.size() != 1) { | 549 if (operands.size() != 1) { |
| 536 return OTS_FAILURE(); | 550 return OTS_FAILURE(); |
| 537 } | 551 } |
| 538 if(operands.back().second != DICT_OPERAND_INTEGER) { | 552 if(operands.back().second != DICT_OPERAND_INTEGER) { |
| 539 return OTS_FAILURE(); | 553 return OTS_FAILURE(); |
| 540 } | 554 } |
| 541 if (operands.back().first != 2) { | 555 if (operands.back().first != 2) { |
| 542 // We only support the "Type 2 Charstring Format." | 556 // We only support the "Type 2 Charstring Format." |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 if (!ParsePrivateDictData(data, table_length, | 787 if (!ParsePrivateDictData(data, table_length, |
| 774 private_offset, private_length, | 788 private_offset, private_length, |
| 775 type, out_cff)) { | 789 type, out_cff)) { |
| 776 return OTS_FAILURE(); | 790 return OTS_FAILURE(); |
| 777 } | 791 } |
| 778 break; | 792 break; |
| 779 } | 793 } |
| 780 | 794 |
| 781 // ROS | 795 // ROS |
| 782 case (12U << 8) + 30: | 796 case (12U << 8) + 30: |
| 783 if (type != DICT_DATA_TOPLEVEL) { | 797 if (font_format != FORMAT_UNKNOWN) { |
| 784 return OTS_FAILURE(); | 798 return OTS_FAILURE(); |
| 785 } | 799 } |
| 800 font_format = FORMAT_CID_KEYED; |
| 786 if (operands.size() != 3) { | 801 if (operands.size() != 3) { |
| 787 return OTS_FAILURE(); | 802 return OTS_FAILURE(); |
| 788 } | 803 } |
| 789 // check SIDs | 804 // check SIDs |
| 790 operands.pop_back(); // ignore the first number. | 805 operands.pop_back(); // ignore the first number. |
| 791 if (!CheckSid(operands.back(), sid_max)) { | 806 if (!CheckSid(operands.back(), sid_max)) { |
| 792 return OTS_FAILURE(); | 807 return OTS_FAILURE(); |
| 793 } | 808 } |
| 794 operands.pop_back(); | 809 operands.pop_back(); |
| 795 if (!CheckSid(operands.back(), sid_max)) { | 810 if (!CheckSid(operands.back(), sid_max)) { |
| 796 return OTS_FAILURE(); | 811 return OTS_FAILURE(); |
| 797 } | 812 } |
| 798 if (have_ros) { | 813 if (have_ros) { |
| 799 return OTS_FAILURE(); // multiple ROS tables? | 814 return OTS_FAILURE(); // multiple ROS tables? |
| 800 } | 815 } |
| 801 have_ros = true; | 816 have_ros = true; |
| 802 break; | 817 break; |
| 803 | 818 |
| 804 default: | 819 default: |
| 805 return OTS_FAILURE(); | 820 return OTS_FAILURE(); |
| 806 } | 821 } |
| 807 operands.clear(); | 822 operands.clear(); |
| 823 |
| 824 if (font_format == FORMAT_UNKNOWN) { |
| 825 font_format = FORMAT_OTHER; |
| 826 } |
| 808 } | 827 } |
| 809 | 828 |
| 810 // parse "13. Charsets" | 829 // parse "13. Charsets" |
| 811 if (charset_offset) { | 830 if (charset_offset) { |
| 812 ots::Buffer table(data, table_length); | 831 ots::Buffer table(data, table_length); |
| 813 table.set_offset(charset_offset); | 832 table.set_offset(charset_offset); |
| 814 uint8_t format = 0; | 833 uint8_t format = 0; |
| 815 if (!table.ReadU8(&format)) { | 834 if (!table.ReadU8(&format)) { |
| 816 return OTS_FAILURE(); | 835 return OTS_FAILURE(); |
| 817 } | 836 } |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 } | 1019 } |
| 1001 for (size_t i = 0; i < file->cff->local_subrs_per_font.size(); ++i) { | 1020 for (size_t i = 0; i < file->cff->local_subrs_per_font.size(); ++i) { |
| 1002 delete (file->cff->local_subrs_per_font)[i]; | 1021 delete (file->cff->local_subrs_per_font)[i]; |
| 1003 } | 1022 } |
| 1004 delete file->cff->local_subrs; | 1023 delete file->cff->local_subrs; |
| 1005 delete file->cff; | 1024 delete file->cff; |
| 1006 } | 1025 } |
| 1007 } | 1026 } |
| 1008 | 1027 |
| 1009 } // namespace ots | 1028 } // namespace ots |
| OLD | NEW |