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 |