OLD | NEW |
1 // Copyright (c) 2012 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> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
| 11 #include "maxp.h" |
11 #include "cff_type2_charstring.h" | 12 #include "cff_type2_charstring.h" |
12 | 13 |
13 // CFF - PostScript font program (Compact Font Format) table | 14 // CFF - PostScript font program (Compact Font Format) table |
14 // http://www.microsoft.com/typography/otspec/cff.htm | 15 // http://www.microsoft.com/typography/otspec/cff.htm |
15 // http://www.microsoft.com/typography/otspec/cffspec.htm | 16 // http://www.microsoft.com/typography/otspec/cffspec.htm |
16 | 17 |
| 18 #define TABLE_NAME "CFF" |
| 19 |
17 namespace { | 20 namespace { |
18 | 21 |
19 enum DICT_OPERAND_TYPE { | 22 enum DICT_OPERAND_TYPE { |
20 DICT_OPERAND_INTEGER, | 23 DICT_OPERAND_INTEGER, |
21 DICT_OPERAND_REAL, | 24 DICT_OPERAND_REAL, |
22 DICT_OPERATOR, | 25 DICT_OPERATOR, |
23 }; | 26 }; |
24 | 27 |
25 enum DICT_DATA_TYPE { | 28 enum DICT_DATA_TYPE { |
26 DICT_DATA_TOPLEVEL, | 29 DICT_DATA_TOPLEVEL, |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 if (operands.back().second != DICT_OPERAND_INTEGER) { | 411 if (operands.back().second != DICT_OPERAND_INTEGER) { |
409 return OTS_FAILURE(); | 412 return OTS_FAILURE(); |
410 } | 413 } |
411 if (operands.back().first >= 1024 * 1024 * 1024) { | 414 if (operands.back().first >= 1024 * 1024 * 1024) { |
412 return OTS_FAILURE(); | 415 return OTS_FAILURE(); |
413 } | 416 } |
414 if (operands.back().first + offset >= table_length) { | 417 if (operands.back().first + offset >= table_length) { |
415 return OTS_FAILURE(); | 418 return OTS_FAILURE(); |
416 } | 419 } |
417 // parse "16. Local Subrs INDEX" | 420 // parse "16. Local Subrs INDEX" |
418 ots::Buffer table(data, table_length); | 421 ots::Buffer cff_table(data, table_length); |
419 table.set_offset(operands.back().first + offset); | 422 cff_table.set_offset(operands.back().first + offset); |
420 ots::CFFIndex *local_subrs_index = NULL; | 423 ots::CFFIndex *local_subrs_index = NULL; |
421 if (type == DICT_DATA_FDARRAY) { | 424 if (type == DICT_DATA_FDARRAY) { |
422 if (out_cff->local_subrs_per_font.empty()) { | 425 if (out_cff->local_subrs_per_font.empty()) { |
423 return OTS_FAILURE(); // not reached. | 426 return OTS_FAILURE(); // not reached. |
424 } | 427 } |
425 local_subrs_index = out_cff->local_subrs_per_font.back(); | 428 local_subrs_index = out_cff->local_subrs_per_font.back(); |
426 } else { // type == DICT_DATA_TOPLEVEL | 429 } else { // type == DICT_DATA_TOPLEVEL |
427 if (out_cff->local_subrs) { | 430 if (out_cff->local_subrs) { |
428 return OTS_FAILURE(); // two or more local_subrs? | 431 return OTS_FAILURE(); // two or more local_subrs? |
429 } | 432 } |
430 local_subrs_index = new ots::CFFIndex; | 433 local_subrs_index = new ots::CFFIndex; |
431 out_cff->local_subrs = local_subrs_index; | 434 out_cff->local_subrs = local_subrs_index; |
432 } | 435 } |
433 if (!ParseIndex(&table, local_subrs_index)) { | 436 if (!ParseIndex(&cff_table, local_subrs_index)) { |
434 return OTS_FAILURE(); | 437 return OTS_FAILURE(); |
435 } | 438 } |
436 break; | 439 break; |
437 } | 440 } |
438 | 441 |
439 // boolean | 442 // boolean |
440 case (12U << 8) + 14: // ForceBold | 443 case (12U << 8) + 14: // ForceBold |
441 if (operands.size() != 1) { | 444 if (operands.size() != 1) { |
442 return OTS_FAILURE(); | 445 return OTS_FAILURE(); |
443 } | 446 } |
444 if (operands.back().second != DICT_OPERAND_INTEGER) { | 447 if (operands.back().second != DICT_OPERAND_INTEGER) { |
445 return OTS_FAILURE(); | 448 return OTS_FAILURE(); |
446 } | 449 } |
447 if (operands.back().first >= 2) { | 450 if (operands.back().first >= 2) { |
448 return OTS_FAILURE(); | 451 return OTS_FAILURE(); |
449 } | 452 } |
450 break; | 453 break; |
451 | 454 |
452 default: | 455 default: |
453 return OTS_FAILURE(); | 456 return OTS_FAILURE(); |
454 } | 457 } |
455 operands.clear(); | 458 operands.clear(); |
456 } | 459 } |
457 | 460 |
458 return true; | 461 return true; |
459 } | 462 } |
460 | 463 |
461 bool ParseDictData(const uint8_t *data, size_t table_length, | 464 bool ParseDictData(const uint8_t *data, size_t table_length, |
462 const ots::CFFIndex &index, size_t sid_max, | 465 const ots::CFFIndex &index, uint16_t glyphs, |
463 DICT_DATA_TYPE type, ots::OpenTypeCFF *out_cff) { | 466 size_t sid_max, DICT_DATA_TYPE type, |
| 467 ots::OpenTypeCFF *out_cff) { |
464 for (unsigned i = 1; i < index.offsets.size(); ++i) { | 468 for (unsigned i = 1; i < index.offsets.size(); ++i) { |
465 if (type == DICT_DATA_TOPLEVEL) { | 469 if (type == DICT_DATA_TOPLEVEL) { |
466 out_cff->char_strings_array.push_back(new ots::CFFIndex); | 470 out_cff->char_strings_array.push_back(new ots::CFFIndex); |
467 } | 471 } |
468 size_t dict_length = index.offsets[i] - index.offsets[i - 1]; | 472 size_t dict_length = index.offsets[i] - index.offsets[i - 1]; |
469 ots::Buffer table(data + index.offsets[i - 1], dict_length); | 473 ots::Buffer table(data + index.offsets[i - 1], dict_length); |
470 | 474 |
471 std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > operands; | 475 std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > operands; |
472 | 476 |
473 FONT_FORMAT font_format = FORMAT_UNKNOWN; | 477 FONT_FORMAT font_format = FORMAT_UNKNOWN; |
474 bool have_ros = false; | 478 bool have_ros = false; |
475 uint16_t glyphs = 0; | 479 uint16_t charstring_glyphs = 0; |
476 size_t charset_offset = 0; | 480 size_t charset_offset = 0; |
477 | 481 |
478 while (table.offset() < dict_length) { | 482 while (table.offset() < dict_length) { |
479 if (!ParseDictDataReadNext(&table, &operands)) { | 483 if (!ParseDictDataReadNext(&table, &operands)) { |
480 return OTS_FAILURE(); | 484 return OTS_FAILURE(); |
481 } | 485 } |
482 if (operands.empty()) { | 486 if (operands.empty()) { |
483 return OTS_FAILURE(); | 487 return OTS_FAILURE(); |
484 } | 488 } |
485 if (operands.size() > 48) { | 489 if (operands.size() > 48) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 return OTS_FAILURE(); | 599 return OTS_FAILURE(); |
596 } | 600 } |
597 if (operands.back().first <= 1) { | 601 if (operands.back().first <= 1) { |
598 break; // predefined encoding, "Standard" or "Expert", is used. | 602 break; // predefined encoding, "Standard" or "Expert", is used. |
599 } | 603 } |
600 if (!CheckOffset(operands.back(), table_length)) { | 604 if (!CheckOffset(operands.back(), table_length)) { |
601 return OTS_FAILURE(); | 605 return OTS_FAILURE(); |
602 } | 606 } |
603 | 607 |
604 // parse sub dictionary INDEX. | 608 // parse sub dictionary INDEX. |
605 ots::Buffer table(data, table_length); | 609 ots::Buffer cff_table(data, table_length); |
606 table.set_offset(operands.back().first); | 610 cff_table.set_offset(operands.back().first); |
607 uint8_t format = 0; | 611 uint8_t format = 0; |
608 if (!table.ReadU8(&format)) { | 612 if (!cff_table.ReadU8(&format)) { |
609 return OTS_FAILURE(); | 613 return OTS_FAILURE(); |
610 } | 614 } |
611 if (format & 0x80) { | 615 if (format & 0x80) { |
612 // supplemental encoding is not supported at the moment. | 616 // supplemental encoding is not supported at the moment. |
613 return OTS_FAILURE(); | 617 return OTS_FAILURE(); |
614 } | 618 } |
615 // TODO(yusukes): support & parse supplemental encoding tables. | 619 // TODO(yusukes): support & parse supplemental encoding tables. |
616 break; | 620 break; |
617 } | 621 } |
618 | 622 |
619 case 17: { // CharStrings | 623 case 17: { // CharStrings |
620 if (type != DICT_DATA_TOPLEVEL) { | 624 if (type != DICT_DATA_TOPLEVEL) { |
621 return OTS_FAILURE(); | 625 return OTS_FAILURE(); |
622 } | 626 } |
623 if (operands.size() != 1) { | 627 if (operands.size() != 1) { |
624 return OTS_FAILURE(); | 628 return OTS_FAILURE(); |
625 } | 629 } |
626 if (!CheckOffset(operands.back(), table_length)) { | 630 if (!CheckOffset(operands.back(), table_length)) { |
627 return OTS_FAILURE(); | 631 return OTS_FAILURE(); |
628 } | 632 } |
629 // parse "14. CharStrings INDEX" | 633 // parse "14. CharStrings INDEX" |
630 ots::Buffer table(data, table_length); | 634 ots::Buffer cff_table(data, table_length); |
631 table.set_offset(operands.back().first); | 635 cff_table.set_offset(operands.back().first); |
632 ots::CFFIndex *charstring_index = out_cff->char_strings_array.back(); | 636 ots::CFFIndex *charstring_index = out_cff->char_strings_array.back(); |
633 if (!ParseIndex(&table, charstring_index)) { | 637 if (!ParseIndex(&cff_table, charstring_index)) { |
634 return OTS_FAILURE(); | 638 return OTS_FAILURE(); |
635 } | 639 } |
636 if (charstring_index->count < 2) { | 640 if (charstring_index->count < 2) { |
637 return OTS_FAILURE(); | 641 return OTS_FAILURE(); |
638 } | 642 } |
639 if (glyphs) { | 643 if (charstring_glyphs) { |
640 return OTS_FAILURE(); // multiple charstring tables? | 644 return OTS_FAILURE(); // multiple charstring tables? |
641 } | 645 } |
642 glyphs = charstring_index->count; | 646 charstring_glyphs = charstring_index->count; |
| 647 if (charstring_glyphs != glyphs) { |
| 648 return OTS_FAILURE(); // CFF and maxp have different number of glyp
hs? |
| 649 } |
643 break; | 650 break; |
644 } | 651 } |
645 | 652 |
646 case (12U << 8) + 36: { // FDArray | 653 case (12U << 8) + 36: { // FDArray |
647 if (type != DICT_DATA_TOPLEVEL) { | 654 if (type != DICT_DATA_TOPLEVEL) { |
648 return OTS_FAILURE(); | 655 return OTS_FAILURE(); |
649 } | 656 } |
650 if (operands.size() != 1) { | 657 if (operands.size() != 1) { |
651 return OTS_FAILURE(); | 658 return OTS_FAILURE(); |
652 } | 659 } |
653 if (!CheckOffset(operands.back(), table_length)) { | 660 if (!CheckOffset(operands.back(), table_length)) { |
654 return OTS_FAILURE(); | 661 return OTS_FAILURE(); |
655 } | 662 } |
656 | 663 |
657 // parse sub dictionary INDEX. | 664 // parse sub dictionary INDEX. |
658 ots::Buffer table(data, table_length); | 665 ots::Buffer cff_table(data, table_length); |
659 table.set_offset(operands.back().first); | 666 cff_table.set_offset(operands.back().first); |
660 ots::CFFIndex sub_dict_index; | 667 ots::CFFIndex sub_dict_index; |
661 if (!ParseIndex(&table, &sub_dict_index)) { | 668 if (!ParseIndex(&cff_table, &sub_dict_index)) { |
662 return OTS_FAILURE(); | 669 return OTS_FAILURE(); |
663 } | 670 } |
664 if (!ParseDictData(data, table_length, | 671 if (!ParseDictData(data, table_length, |
665 sub_dict_index, sid_max, DICT_DATA_FDARRAY, | 672 sub_dict_index, |
| 673 glyphs, sid_max, DICT_DATA_FDARRAY, |
666 out_cff)) { | 674 out_cff)) { |
667 return OTS_FAILURE(); | 675 return OTS_FAILURE(); |
668 } | 676 } |
669 if (out_cff->font_dict_length != 0) { | 677 if (out_cff->font_dict_length != 0) { |
670 return OTS_FAILURE(); // two or more FDArray found. | 678 return OTS_FAILURE(); // two or more FDArray found. |
671 } | 679 } |
672 out_cff->font_dict_length = sub_dict_index.count; | 680 out_cff->font_dict_length = sub_dict_index.count; |
673 break; | 681 break; |
674 } | 682 } |
675 | 683 |
676 case (12U << 8) + 37: { // FDSelect | 684 case (12U << 8) + 37: { // FDSelect |
677 if (type != DICT_DATA_TOPLEVEL) { | 685 if (type != DICT_DATA_TOPLEVEL) { |
678 return OTS_FAILURE(); | 686 return OTS_FAILURE(); |
679 } | 687 } |
680 if (operands.size() != 1) { | 688 if (operands.size() != 1) { |
681 return OTS_FAILURE(); | 689 return OTS_FAILURE(); |
682 } | 690 } |
683 if (!CheckOffset(operands.back(), table_length)) { | 691 if (!CheckOffset(operands.back(), table_length)) { |
684 return OTS_FAILURE(); | 692 return OTS_FAILURE(); |
685 } | 693 } |
686 | 694 |
687 // parse FDSelect data structure | 695 // parse FDSelect data structure |
688 ots::Buffer table(data, table_length); | 696 ots::Buffer cff_table(data, table_length); |
689 table.set_offset(operands.back().first); | 697 cff_table.set_offset(operands.back().first); |
690 uint8_t format = 0; | 698 uint8_t format = 0; |
691 if (!table.ReadU8(&format)) { | 699 if (!cff_table.ReadU8(&format)) { |
692 return OTS_FAILURE(); | 700 return OTS_FAILURE(); |
693 } | 701 } |
694 if (format == 0) { | 702 if (format == 0) { |
695 for (uint16_t j = 0; j < glyphs; ++j) { | 703 for (uint16_t j = 0; j < glyphs; ++j) { |
696 uint8_t fd_index = 0; | 704 uint8_t fd_index = 0; |
697 if (!table.ReadU8(&fd_index)) { | 705 if (!cff_table.ReadU8(&fd_index)) { |
698 return OTS_FAILURE(); | 706 return OTS_FAILURE(); |
699 } | 707 } |
700 (out_cff->fd_select)[j] = fd_index; | 708 (out_cff->fd_select)[j] = fd_index; |
701 } | 709 } |
702 } else if (format == 3) { | 710 } else if (format == 3) { |
703 uint16_t n_ranges = 0; | 711 uint16_t n_ranges = 0; |
704 if (!table.ReadU16(&n_ranges)) { | 712 if (!cff_table.ReadU16(&n_ranges)) { |
705 return OTS_FAILURE(); | 713 return OTS_FAILURE(); |
706 } | 714 } |
707 if (n_ranges == 0) { | 715 if (n_ranges == 0) { |
708 return OTS_FAILURE(); | 716 return OTS_FAILURE(); |
709 } | 717 } |
710 | 718 |
711 uint16_t last_gid = 0; | 719 uint16_t last_gid = 0; |
712 uint8_t fd_index = 0; | 720 uint8_t fd_index = 0; |
713 for (unsigned j = 0; j < n_ranges; ++j) { | 721 for (unsigned j = 0; j < n_ranges; ++j) { |
714 uint16_t first = 0; // GID | 722 uint16_t first = 0; // GID |
715 if (!table.ReadU16(&first)) { | 723 if (!cff_table.ReadU16(&first)) { |
716 return OTS_FAILURE(); | 724 return OTS_FAILURE(); |
717 } | 725 } |
718 | 726 |
719 // Sanity checks. | 727 // Sanity checks. |
720 if ((j == 0) && (first != 0)) { | 728 if ((j == 0) && (first != 0)) { |
721 return OTS_FAILURE(); | 729 return OTS_FAILURE(); |
722 } | 730 } |
723 if ((j != 0) && (last_gid >= first)) { | 731 if ((j != 0) && (last_gid >= first)) { |
724 return OTS_FAILURE(); // not increasing order. | 732 return OTS_FAILURE(); // not increasing order. |
725 } | 733 } |
726 | 734 |
727 // Copy the mapping to |out_cff->fd_select|. | 735 // Copy the mapping to |out_cff->fd_select|. |
728 if (j != 0) { | 736 if (j != 0) { |
729 for (uint16_t k = last_gid; k < first; ++k) { | 737 for (uint16_t k = last_gid; k < first; ++k) { |
730 if (!out_cff->fd_select.insert( | 738 if (!out_cff->fd_select.insert( |
731 std::make_pair(k, fd_index)).second) { | 739 std::make_pair(k, fd_index)).second) { |
732 return OTS_FAILURE(); | 740 return OTS_FAILURE(); |
733 } | 741 } |
734 } | 742 } |
735 } | 743 } |
736 | 744 |
737 if (!table.ReadU8(&fd_index)) { | 745 if (!cff_table.ReadU8(&fd_index)) { |
738 return OTS_FAILURE(); | 746 return OTS_FAILURE(); |
739 } | 747 } |
740 last_gid = first; | 748 last_gid = first; |
741 // TODO(yusukes): check GID? | 749 // TODO(yusukes): check GID? |
742 } | 750 } |
743 uint16_t sentinel = 0; | 751 uint16_t sentinel = 0; |
744 if (!table.ReadU16(&sentinel)) { | 752 if (!cff_table.ReadU16(&sentinel)) { |
745 return OTS_FAILURE(); | 753 return OTS_FAILURE(); |
746 } | 754 } |
747 if (last_gid >= sentinel) { | 755 if (last_gid >= sentinel) { |
748 return OTS_FAILURE(); | 756 return OTS_FAILURE(); |
749 } | 757 } |
750 for (uint16_t k = last_gid; k < sentinel; ++k) { | 758 for (uint16_t k = last_gid; k < sentinel; ++k) { |
751 if (!out_cff->fd_select.insert( | 759 if (!out_cff->fd_select.insert( |
752 std::make_pair(k, fd_index)).second) { | 760 std::make_pair(k, fd_index)).second) { |
753 return OTS_FAILURE(); | 761 return OTS_FAILURE(); |
754 } | 762 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 } | 829 } |
822 operands.clear(); | 830 operands.clear(); |
823 | 831 |
824 if (font_format == FORMAT_UNKNOWN) { | 832 if (font_format == FORMAT_UNKNOWN) { |
825 font_format = FORMAT_OTHER; | 833 font_format = FORMAT_OTHER; |
826 } | 834 } |
827 } | 835 } |
828 | 836 |
829 // parse "13. Charsets" | 837 // parse "13. Charsets" |
830 if (charset_offset) { | 838 if (charset_offset) { |
831 ots::Buffer table(data, table_length); | 839 ots::Buffer cff_table(data, table_length); |
832 table.set_offset(charset_offset); | 840 cff_table.set_offset(charset_offset); |
833 uint8_t format = 0; | 841 uint8_t format = 0; |
834 if (!table.ReadU8(&format)) { | 842 if (!cff_table.ReadU8(&format)) { |
835 return OTS_FAILURE(); | 843 return OTS_FAILURE(); |
836 } | 844 } |
837 switch (format) { | 845 switch (format) { |
838 case 0: | 846 case 0: |
839 for (uint16_t j = 1 /* .notdef is omitted */; j < glyphs; ++j) { | 847 for (uint16_t j = 1 /* .notdef is omitted */; j < glyphs; ++j) { |
840 uint16_t sid = 0; | 848 uint16_t sid = 0; |
841 if (!table.ReadU16(&sid)) { | 849 if (!cff_table.ReadU16(&sid)) { |
842 return OTS_FAILURE(); | 850 return OTS_FAILURE(); |
843 } | 851 } |
844 if (!have_ros && (sid > sid_max)) { | 852 if (!have_ros && (sid > sid_max)) { |
845 return OTS_FAILURE(); | 853 return OTS_FAILURE(); |
846 } | 854 } |
847 // TODO(yusukes): check CIDs when have_ros is true. | 855 // TODO(yusukes): check CIDs when have_ros is true. |
848 } | 856 } |
849 break; | 857 break; |
850 | 858 |
851 case 1: | 859 case 1: |
852 case 2: { | 860 case 2: { |
853 uint32_t total = 1; // .notdef is omitted. | 861 uint32_t total = 1; // .notdef is omitted. |
854 while (total < glyphs) { | 862 while (total < glyphs) { |
855 uint16_t sid = 0; | 863 uint16_t sid = 0; |
856 if (!table.ReadU16(&sid)) { | 864 if (!cff_table.ReadU16(&sid)) { |
857 return OTS_FAILURE(); | 865 return OTS_FAILURE(); |
858 } | 866 } |
859 if (!have_ros && (sid > sid_max)) { | 867 if (!have_ros && (sid > sid_max)) { |
860 return OTS_FAILURE(); | 868 return OTS_FAILURE(); |
861 } | 869 } |
862 // TODO(yusukes): check CIDs when have_ros is true. | 870 // TODO(yusukes): check CIDs when have_ros is true. |
863 | 871 |
864 if (format == 1) { | 872 if (format == 1) { |
865 uint8_t left = 0; | 873 uint8_t left = 0; |
866 if (!table.ReadU8(&left)) { | 874 if (!cff_table.ReadU8(&left)) { |
867 return OTS_FAILURE(); | 875 return OTS_FAILURE(); |
868 } | 876 } |
869 total += (left + 1); | 877 total += (left + 1); |
870 } else { | 878 } else { |
871 uint16_t left = 0; | 879 uint16_t left = 0; |
872 if (!table.ReadU16(&left)) { | 880 if (!cff_table.ReadU16(&left)) { |
873 return OTS_FAILURE(); | 881 return OTS_FAILURE(); |
874 } | 882 } |
875 total += (left + 1); | 883 total += (left + 1); |
876 } | 884 } |
877 } | 885 } |
878 break; | 886 break; |
879 } | 887 } |
880 | 888 |
881 default: | 889 default: |
882 return OTS_FAILURE(); | 890 return OTS_FAILURE(); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 // parse "10. String INDEX" | 960 // parse "10. String INDEX" |
953 table.set_offset(top_dict_index.offset_to_next); | 961 table.set_offset(top_dict_index.offset_to_next); |
954 CFFIndex string_index; | 962 CFFIndex string_index; |
955 if (!ParseIndex(&table, &string_index)) { | 963 if (!ParseIndex(&table, &string_index)) { |
956 return OTS_FAILURE(); | 964 return OTS_FAILURE(); |
957 } | 965 } |
958 if (string_index.count >= 65000 - kNStdString) { | 966 if (string_index.count >= 65000 - kNStdString) { |
959 return OTS_FAILURE(); | 967 return OTS_FAILURE(); |
960 } | 968 } |
961 | 969 |
| 970 const uint16_t num_glyphs = file->maxp->num_glyphs; |
962 const size_t sid_max = string_index.count + kNStdString; | 971 const size_t sid_max = string_index.count + kNStdString; |
963 // string_index.count == 0 is allowed. | 972 // string_index.count == 0 is allowed. |
964 | 973 |
965 // parse "9. Top DICT Data" | 974 // parse "9. Top DICT Data" |
966 if (!ParseDictData(data, length, top_dict_index, | 975 if (!ParseDictData(data, length, top_dict_index, |
967 sid_max, DICT_DATA_TOPLEVEL, file->cff)) { | 976 num_glyphs, sid_max, |
| 977 DICT_DATA_TOPLEVEL, file->cff)) { |
968 return OTS_FAILURE(); | 978 return OTS_FAILURE(); |
969 } | 979 } |
970 | 980 |
971 // parse "16. Global Subrs INDEX" | 981 // parse "16. Global Subrs INDEX" |
972 table.set_offset(string_index.offset_to_next); | 982 table.set_offset(string_index.offset_to_next); |
973 CFFIndex global_subrs_index; | 983 CFFIndex global_subrs_index; |
974 if (!ParseIndex(&table, &global_subrs_index)) { | 984 if (!ParseIndex(&table, &global_subrs_index)) { |
975 return OTS_FAILURE(); | 985 return OTS_FAILURE(); |
976 } | 986 } |
977 | 987 |
978 // Check if all fd_index in FDSelect are valid. | 988 // Check if all fd_index in FDSelect are valid. |
979 std::map<uint16_t, uint8_t>::const_iterator iter; | 989 std::map<uint16_t, uint8_t>::const_iterator iter; |
980 std::map<uint16_t, uint8_t>::const_iterator end = file->cff->fd_select.end(); | 990 std::map<uint16_t, uint8_t>::const_iterator end = file->cff->fd_select.end(); |
981 for (iter = file->cff->fd_select.begin(); iter != end; ++iter) { | 991 for (iter = file->cff->fd_select.begin(); iter != end; ++iter) { |
982 if (iter->second >= file->cff->font_dict_length) { | 992 if (iter->second >= file->cff->font_dict_length) { |
983 return OTS_FAILURE(); | 993 return OTS_FAILURE(); |
984 } | 994 } |
985 } | 995 } |
986 | 996 |
987 // Check if all charstrings (font hinting code for each glyph) are valid. | 997 // Check if all charstrings (font hinting code for each glyph) are valid. |
988 for (size_t i = 0; i < file->cff->char_strings_array.size(); ++i) { | 998 for (size_t i = 0; i < file->cff->char_strings_array.size(); ++i) { |
989 if (!ValidateType2CharStringIndex(*(file->cff->char_strings_array.at(i)), | 999 if (!ValidateType2CharStringIndex(file, |
| 1000 *(file->cff->char_strings_array.at(i)), |
990 global_subrs_index, | 1001 global_subrs_index, |
991 file->cff->fd_select, | 1002 file->cff->fd_select, |
992 file->cff->local_subrs_per_font, | 1003 file->cff->local_subrs_per_font, |
993 file->cff->local_subrs, | 1004 file->cff->local_subrs, |
994 &table)) { | 1005 &table)) { |
995 return OTS_FAILURE(); | 1006 return OTS_FAILURE_MSG("Failed validating charstring set %d", (int) i); |
996 } | 1007 } |
997 } | 1008 } |
998 | 1009 |
999 return true; | 1010 return true; |
1000 } | 1011 } |
1001 | 1012 |
1002 bool ots_cff_should_serialise(OpenTypeFile *file) { | 1013 bool ots_cff_should_serialise(OpenTypeFile *file) { |
1003 return file->cff != NULL; | 1014 return file->cff != NULL; |
1004 } | 1015 } |
1005 | 1016 |
(...skipping 13 matching lines...) Expand all Loading... |
1019 } | 1030 } |
1020 for (size_t i = 0; i < file->cff->local_subrs_per_font.size(); ++i) { | 1031 for (size_t i = 0; i < file->cff->local_subrs_per_font.size(); ++i) { |
1021 delete (file->cff->local_subrs_per_font)[i]; | 1032 delete (file->cff->local_subrs_per_font)[i]; |
1022 } | 1033 } |
1023 delete file->cff->local_subrs; | 1034 delete file->cff->local_subrs; |
1024 delete file->cff; | 1035 delete file->cff; |
1025 } | 1036 } |
1026 } | 1037 } |
1027 | 1038 |
1028 } // namespace ots | 1039 } // namespace ots |
| 1040 |
| 1041 #undef TABLE_NAME |
OLD | NEW |