| 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> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 } | 891 } |
| 892 } | 892 } |
| 893 } | 893 } |
| 894 return true; | 894 return true; |
| 895 } | 895 } |
| 896 | 896 |
| 897 } // namespace | 897 } // namespace |
| 898 | 898 |
| 899 namespace ots { | 899 namespace ots { |
| 900 | 900 |
| 901 bool ots_cff_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { | 901 bool ots_cff_parse(Font *font, const uint8_t *data, size_t length) { |
| 902 Buffer table(data, length); | 902 Buffer table(data, length); |
| 903 | 903 |
| 904 file->cff = new OpenTypeCFF; | 904 font->cff = new OpenTypeCFF; |
| 905 file->cff->data = data; | 905 font->cff->data = data; |
| 906 file->cff->length = length; | 906 font->cff->length = length; |
| 907 file->cff->font_dict_length = 0; | 907 font->cff->font_dict_length = 0; |
| 908 file->cff->local_subrs = NULL; | 908 font->cff->local_subrs = NULL; |
| 909 | 909 |
| 910 // parse "6. Header" in the Adobe Compact Font Format Specification | 910 // parse "6. Header" in the Adobe Compact Font Format Specification |
| 911 uint8_t major = 0; | 911 uint8_t major = 0; |
| 912 uint8_t minor = 0; | 912 uint8_t minor = 0; |
| 913 uint8_t hdr_size = 0; | 913 uint8_t hdr_size = 0; |
| 914 uint8_t off_size = 0; | 914 uint8_t off_size = 0; |
| 915 if (!table.ReadU8(&major)) { | 915 if (!table.ReadU8(&major)) { |
| 916 return OTS_FAILURE(); | 916 return OTS_FAILURE(); |
| 917 } | 917 } |
| 918 if (!table.ReadU8(&minor)) { | 918 if (!table.ReadU8(&minor)) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 936 if (hdr_size >= length) { | 936 if (hdr_size >= length) { |
| 937 return OTS_FAILURE(); | 937 return OTS_FAILURE(); |
| 938 } | 938 } |
| 939 | 939 |
| 940 // parse "7. Name INDEX" | 940 // parse "7. Name INDEX" |
| 941 table.set_offset(hdr_size); | 941 table.set_offset(hdr_size); |
| 942 CFFIndex name_index; | 942 CFFIndex name_index; |
| 943 if (!ParseIndex(&table, &name_index)) { | 943 if (!ParseIndex(&table, &name_index)) { |
| 944 return OTS_FAILURE(); | 944 return OTS_FAILURE(); |
| 945 } | 945 } |
| 946 if (!ParseNameData(&table, name_index, &(file->cff->name))) { | 946 if (!ParseNameData(&table, name_index, &(font->cff->name))) { |
| 947 return OTS_FAILURE(); | 947 return OTS_FAILURE(); |
| 948 } | 948 } |
| 949 | 949 |
| 950 // parse "8. Top DICT INDEX" | 950 // parse "8. Top DICT INDEX" |
| 951 table.set_offset(name_index.offset_to_next); | 951 table.set_offset(name_index.offset_to_next); |
| 952 CFFIndex top_dict_index; | 952 CFFIndex top_dict_index; |
| 953 if (!ParseIndex(&table, &top_dict_index)) { | 953 if (!ParseIndex(&table, &top_dict_index)) { |
| 954 return OTS_FAILURE(); | 954 return OTS_FAILURE(); |
| 955 } | 955 } |
| 956 if (name_index.count != top_dict_index.count) { | 956 if (name_index.count != top_dict_index.count) { |
| 957 return OTS_FAILURE(); | 957 return OTS_FAILURE(); |
| 958 } | 958 } |
| 959 | 959 |
| 960 // parse "10. String INDEX" | 960 // parse "10. String INDEX" |
| 961 table.set_offset(top_dict_index.offset_to_next); | 961 table.set_offset(top_dict_index.offset_to_next); |
| 962 CFFIndex string_index; | 962 CFFIndex string_index; |
| 963 if (!ParseIndex(&table, &string_index)) { | 963 if (!ParseIndex(&table, &string_index)) { |
| 964 return OTS_FAILURE(); | 964 return OTS_FAILURE(); |
| 965 } | 965 } |
| 966 if (string_index.count >= 65000 - kNStdString) { | 966 if (string_index.count >= 65000 - kNStdString) { |
| 967 return OTS_FAILURE(); | 967 return OTS_FAILURE(); |
| 968 } | 968 } |
| 969 | 969 |
| 970 const uint16_t num_glyphs = file->maxp->num_glyphs; | 970 const uint16_t num_glyphs = font->maxp->num_glyphs; |
| 971 const size_t sid_max = string_index.count + kNStdString; | 971 const size_t sid_max = string_index.count + kNStdString; |
| 972 // string_index.count == 0 is allowed. | 972 // string_index.count == 0 is allowed. |
| 973 | 973 |
| 974 // parse "9. Top DICT Data" | 974 // parse "9. Top DICT Data" |
| 975 if (!ParseDictData(data, length, top_dict_index, | 975 if (!ParseDictData(data, length, top_dict_index, |
| 976 num_glyphs, sid_max, | 976 num_glyphs, sid_max, |
| 977 DICT_DATA_TOPLEVEL, file->cff)) { | 977 DICT_DATA_TOPLEVEL, font->cff)) { |
| 978 return OTS_FAILURE(); | 978 return OTS_FAILURE(); |
| 979 } | 979 } |
| 980 | 980 |
| 981 // parse "16. Global Subrs INDEX" | 981 // parse "16. Global Subrs INDEX" |
| 982 table.set_offset(string_index.offset_to_next); | 982 table.set_offset(string_index.offset_to_next); |
| 983 CFFIndex global_subrs_index; | 983 CFFIndex global_subrs_index; |
| 984 if (!ParseIndex(&table, &global_subrs_index)) { | 984 if (!ParseIndex(&table, &global_subrs_index)) { |
| 985 return OTS_FAILURE(); | 985 return OTS_FAILURE(); |
| 986 } | 986 } |
| 987 | 987 |
| 988 // Check if all fd_index in FDSelect are valid. | 988 // Check if all fd_index in FDSelect are valid. |
| 989 std::map<uint16_t, uint8_t>::const_iterator iter; | 989 std::map<uint16_t, uint8_t>::const_iterator iter; |
| 990 std::map<uint16_t, uint8_t>::const_iterator end = file->cff->fd_select.end(); | 990 std::map<uint16_t, uint8_t>::const_iterator end = font->cff->fd_select.end(); |
| 991 for (iter = file->cff->fd_select.begin(); iter != end; ++iter) { | 991 for (iter = font->cff->fd_select.begin(); iter != end; ++iter) { |
| 992 if (iter->second >= file->cff->font_dict_length) { | 992 if (iter->second >= font->cff->font_dict_length) { |
| 993 return OTS_FAILURE(); | 993 return OTS_FAILURE(); |
| 994 } | 994 } |
| 995 } | 995 } |
| 996 | 996 |
| 997 // 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. |
| 998 for (size_t i = 0; i < file->cff->char_strings_array.size(); ++i) { | 998 for (size_t i = 0; i < font->cff->char_strings_array.size(); ++i) { |
| 999 if (!ValidateType2CharStringIndex(file, | 999 if (!ValidateType2CharStringIndex(font, |
| 1000 *(file->cff->char_strings_array.at(i)), | 1000 *(font->cff->char_strings_array.at(i)), |
| 1001 global_subrs_index, | 1001 global_subrs_index, |
| 1002 file->cff->fd_select, | 1002 font->cff->fd_select, |
| 1003 file->cff->local_subrs_per_font, | 1003 font->cff->local_subrs_per_font, |
| 1004 file->cff->local_subrs, | 1004 font->cff->local_subrs, |
| 1005 &table)) { | 1005 &table)) { |
| 1006 return OTS_FAILURE_MSG("Failed validating charstring set %d", (int) i); | 1006 return OTS_FAILURE_MSG("Failed validating charstring set %d", (int) i); |
| 1007 } | 1007 } |
| 1008 } | 1008 } |
| 1009 | 1009 |
| 1010 return true; | 1010 return true; |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 bool ots_cff_should_serialise(OpenTypeFile *file) { | 1013 bool ots_cff_should_serialise(Font *font) { |
| 1014 return file->cff != NULL; | 1014 return font->cff != NULL; |
| 1015 } | 1015 } |
| 1016 | 1016 |
| 1017 bool ots_cff_serialise(OTSStream *out, OpenTypeFile *file) { | 1017 bool ots_cff_serialise(OTSStream *out, Font *font) { |
| 1018 // TODO(yusukes): would be better to transcode the data, | 1018 // TODO(yusukes): would be better to transcode the data, |
| 1019 // rather than simple memcpy. | 1019 // rather than simple memcpy. |
| 1020 if (!out->Write(file->cff->data, file->cff->length)) { | 1020 if (!out->Write(font->cff->data, font->cff->length)) { |
| 1021 return OTS_FAILURE(); | 1021 return OTS_FAILURE(); |
| 1022 } | 1022 } |
| 1023 return true; | 1023 return true; |
| 1024 } | 1024 } |
| 1025 | 1025 |
| 1026 void ots_cff_free(OpenTypeFile *file) { | 1026 void ots_cff_reuse(Font *font, Font *other) { |
| 1027 if (file->cff) { | 1027 font->cff = other->cff; |
| 1028 for (size_t i = 0; i < file->cff->char_strings_array.size(); ++i) { | 1028 font->cff_reused = true; |
| 1029 delete (file->cff->char_strings_array)[i]; | 1029 } |
| 1030 |
| 1031 void ots_cff_free(Font *font) { |
| 1032 if (font->cff) { |
| 1033 for (size_t i = 0; i < font->cff->char_strings_array.size(); ++i) { |
| 1034 delete (font->cff->char_strings_array)[i]; |
| 1030 } | 1035 } |
| 1031 for (size_t i = 0; i < file->cff->local_subrs_per_font.size(); ++i) { | 1036 for (size_t i = 0; i < font->cff->local_subrs_per_font.size(); ++i) { |
| 1032 delete (file->cff->local_subrs_per_font)[i]; | 1037 delete (font->cff->local_subrs_per_font)[i]; |
| 1033 } | 1038 } |
| 1034 delete file->cff->local_subrs; | 1039 delete font->cff->local_subrs; |
| 1035 delete file->cff; | 1040 delete font->cff; |
| 1036 } | 1041 } |
| 1037 } | 1042 } |
| 1038 | 1043 |
| 1039 } // namespace ots | 1044 } // namespace ots |
| 1040 | 1045 |
| 1041 #undef TABLE_NAME | 1046 #undef TABLE_NAME |
| OLD | NEW |