153 inline bool intersects (const hb_set_t *glyphs) const { |
153 inline bool intersects (const hb_set_t *glyphs) const { |
154 return glyphs->intersects (start, end); |
154 return glyphs->intersects (start, end); |
155 } |
155 } |
156 |
156 |
157 template <typename set_t> |
157 template <typename set_t> |
158 inline void add_coverage (set_t *glyphs) const { |
158 inline bool add_coverage (set_t *glyphs) const { |
159 glyphs->add_range (start, end); |
159 return glyphs->add_range (start, end); |
160 } |
160 } |
161 |
161 |
162 GlyphID start; /* First GlyphID in the range */ |
162 GlyphID start; /* First GlyphID in the range */ |
163 GlyphID end; /* Last GlyphID in the range */ |
163 GlyphID end; /* Last GlyphID in the range */ |
164 USHORT value; /* Value */ |
164 HBUINT16 value; /* Value */ |
165 public: |
165 public: |
166 DEFINE_SIZE_STATIC (6); |
166 DEFINE_SIZE_STATIC (6); |
167 }; |
167 }; |
168 DEFINE_NULL_DATA (RangeRecord, "\000\001"); |
168 DEFINE_NULL_DATA (RangeRecord, "\000\001"); |
169 |
169 |
173 inline unsigned int get_indexes (unsigned int start_offset, |
173 inline unsigned int get_indexes (unsigned int start_offset, |
174 unsigned int *_count /* IN/OUT */, |
174 unsigned int *_count /* IN/OUT */, |
175 unsigned int *_indexes /* OUT */) const |
175 unsigned int *_indexes /* OUT */) const |
176 { |
176 { |
177 if (_count) { |
177 if (_count) { |
178 const USHORT *arr = this->sub_array (start_offset, _count); |
178 const HBUINT16 *arr = this->sub_array (start_offset, _count); |
179 unsigned int count = *_count; |
179 unsigned int count = *_count; |
180 for (unsigned int i = 0; i < count; i++) |
180 for (unsigned int i = 0; i < count; i++) |
181 _indexes[i] = arr[i]; |
181 _indexes[i] = arr[i]; |
182 } |
182 } |
183 return this->len; |
183 return this->len; |
214 { |
214 { |
215 TRACE_SANITIZE (this); |
215 TRACE_SANITIZE (this); |
216 return_trace (c->check_struct (this) && featureIndex.sanitize (c)); |
216 return_trace (c->check_struct (this) && featureIndex.sanitize (c)); |
217 } |
217 } |
218 |
218 |
219 Offset<> lookupOrderZ; /* = Null (reserved for an offset to a |
219 Offset16 lookupOrderZ; /* = Null (reserved for an offset to a |
220 * reordering table) */ |
220 * reordering table) */ |
221 USHORT reqFeatureIndex;/* Index of a feature required for this |
221 HBUINT16 reqFeatureIndex;/* Index of a feature required for this |
222 * language system--if no required features |
222 * language system--if no required features |
223 * = 0xFFFFu */ |
223 * = 0xFFFFu */ |
224 IndexArray featureIndex; /* Array of indices into the FeatureList */ |
224 IndexArray featureIndex; /* Array of indices into the FeatureList */ |
225 public: |
225 public: |
226 DEFINE_SIZE_ARRAY (6, featureIndex); |
226 DEFINE_SIZE_ARRAY (6, featureIndex); |
297 * Here is one set of rules to determine if the 'size' feature is built |
297 * Here is one set of rules to determine if the 'size' feature is built |
298 * correctly, or as by the older versions of MakeOTF. You may be able to do |
298 * correctly, or as by the older versions of MakeOTF. You may be able to do |
299 * better. |
299 * better. |
300 * |
300 * |
301 * Assume that the offset to the size feature is according to specification, |
301 * Assume that the offset to the size feature is according to specification, |
302 * and make the following value checks. If it fails, assume the the size |
302 * and make the following value checks. If it fails, assume the size |
303 * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it. |
303 * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it. |
304 * If this fails, reject the 'size' feature. The older makeOTF's calculated the |
304 * If this fails, reject the 'size' feature. The older makeOTF's calculated the |
305 * offset from the beginning of the FeatureList table, rather than from the |
305 * offset from the beginning of the FeatureList table, rather than from the |
306 * beginning of the 'size' Feature table. |
306 * beginning of the 'size' Feature table. |
307 * |
307 * |
341 return_trace (false); |
341 return_trace (false); |
342 else |
342 else |
343 return_trace (true); |
343 return_trace (true); |
344 } |
344 } |
345 |
345 |
346 USHORT designSize; /* Represents the design size in 720/inch |
346 HBUINT16 designSize; /* Represents the design size in 720/inch |
347 * units (decipoints). The design size entry |
347 * units (decipoints). The design size entry |
348 * must be non-zero. When there is a design |
348 * must be non-zero. When there is a design |
349 * size but no recommended size range, the |
349 * size but no recommended size range, the |
350 * rest of the array will consist of zeros. */ |
350 * rest of the array will consist of zeros. */ |
351 USHORT subfamilyID; /* Has no independent meaning, but serves |
351 HBUINT16 subfamilyID; /* Has no independent meaning, but serves |
352 * as an identifier that associates fonts |
352 * as an identifier that associates fonts |
353 * in a subfamily. All fonts which share a |
353 * in a subfamily. All fonts which share a |
354 * Preferred or Font Family name and which |
354 * Preferred or Font Family name and which |
355 * differ only by size range shall have the |
355 * differ only by size range shall have the |
356 * same subfamily value, and no fonts which |
356 * same subfamily value, and no fonts which |
357 * differ in weight or style shall have the |
357 * differ in weight or style shall have the |
358 * same subfamily value. If this value is |
358 * same subfamily value. If this value is |
359 * zero, the remaining fields in the array |
359 * zero, the remaining fields in the array |
360 * will be ignored. */ |
360 * will be ignored. */ |
361 USHORT subfamilyNameID;/* If the preceding value is non-zero, this |
361 HBUINT16 subfamilyNameID;/* If the preceding value is non-zero, this |
362 * value must be set in the range 256 - 32767 |
362 * value must be set in the range 256 - 32767 |
363 * (inclusive). It records the value of a |
363 * (inclusive). It records the value of a |
364 * field in the name table, which must |
364 * field in the name table, which must |
365 * contain English-language strings encoded |
365 * contain English-language strings encoded |
366 * in Windows Unicode and Macintosh Roman, |
366 * in Windows Unicode and Macintosh Roman, |
370 * application should use, in combination |
370 * application should use, in combination |
371 * with the family name, to represent the |
371 * with the family name, to represent the |
372 * subfamily in a menu. Applications will |
372 * subfamily in a menu. Applications will |
373 * choose the appropriate version based on |
373 * choose the appropriate version based on |
374 * their selection criteria. */ |
374 * their selection criteria. */ |
375 USHORT rangeStart; /* Large end of the recommended usage range |
375 HBUINT16 rangeStart; /* Large end of the recommended usage range |
376 * (inclusive), stored in 720/inch units |
376 * (inclusive), stored in 720/inch units |
377 * (decipoints). */ |
377 * (decipoints). */ |
378 USHORT rangeEnd; /* Small end of the recommended usage range |
378 HBUINT16 rangeEnd; /* Small end of the recommended usage range |
379 (exclusive), stored in 720/inch units |
379 (exclusive), stored in 720/inch units |
380 * (decipoints). */ |
380 * (decipoints). */ |
381 public: |
381 public: |
382 DEFINE_SIZE_STATIC (10); |
382 DEFINE_SIZE_STATIC (10); |
383 }; |
383 }; |
391 /* Right now minorVersion is at zero. Which means, any table supports |
391 /* Right now minorVersion is at zero. Which means, any table supports |
392 * the uiNameID field. */ |
392 * the uiNameID field. */ |
393 return_trace (c->check_struct (this)); |
393 return_trace (c->check_struct (this)); |
394 } |
394 } |
395 |
395 |
396 USHORT version; /* (set to 0): This corresponds to a “minor” |
396 HBUINT16 version; /* (set to 0): This corresponds to a “minor” |
397 * version number. Additional data may be |
397 * version number. Additional data may be |
398 * added to the end of this Feature Parameters |
398 * added to the end of this Feature Parameters |
399 * table in the future. */ |
399 * table in the future. */ |
400 |
400 |
401 USHORT uiNameID; /* The 'name' table name ID that specifies a |
401 HBUINT16 uiNameID; /* The 'name' table name ID that specifies a |
402 * string (or strings, for multiple languages) |
402 * string (or strings, for multiple languages) |
403 * for a user-interface label for this |
403 * for a user-interface label for this |
404 * feature. The values of uiLabelNameId and |
404 * feature. The values of uiLabelNameId and |
405 * sampleTextNameId are expected to be in the |
405 * sampleTextNameId are expected to be in the |
406 * font-specific name ID range (256-32767), |
406 * font-specific name ID range (256-32767), |
424 TRACE_SANITIZE (this); |
424 TRACE_SANITIZE (this); |
425 return_trace (c->check_struct (this) && |
425 return_trace (c->check_struct (this) && |
426 characters.sanitize (c)); |
426 characters.sanitize (c)); |
427 } |
427 } |
428 |
428 |
429 USHORT format; /* Format number is set to 0. */ |
429 HBUINT16 format; /* Format number is set to 0. */ |
430 USHORT featUILableNameID; /* The ‘name’ table name ID that |
430 HBUINT16 featUILableNameID; /* The ‘name’ table name ID that |
431 * specifies a string (or strings, |
431 * specifies a string (or strings, |
432 * for multiple languages) for a |
432 * for multiple languages) for a |
433 * user-interface label for this |
433 * user-interface label for this |
434 * feature. (May be nullptr.) */ |
434 * feature. (May be nullptr.) */ |
435 USHORT featUITooltipTextNameID;/* The ‘name’ table name ID that |
435 HBUINT16 featUITooltipTextNameID;/* The ‘name’ table name ID that |
436 * specifies a string (or strings, |
436 * specifies a string (or strings, |
437 * for multiple languages) that an |
437 * for multiple languages) that an |
438 * application can use for tooltip |
438 * application can use for tooltip |
439 * text for this feature. (May be |
439 * text for this feature. (May be |
440 * nullptr.) */ |
440 * nullptr.) */ |
441 USHORT sampleTextNameID; /* The ‘name’ table name ID that |
441 HBUINT16 sampleTextNameID; /* The ‘name’ table name ID that |
442 * specifies sample text that |
442 * specifies sample text that |
443 * illustrates the effect of this |
443 * illustrates the effect of this |
444 * feature. (May be nullptr.) */ |
444 * feature. (May be nullptr.) */ |
445 USHORT numNamedParameters; /* Number of named parameters. (May |
445 HBUINT16 numNamedParameters; /* Number of named parameters. (May |
446 * be zero.) */ |
446 * be zero.) */ |
447 USHORT firstParamUILabelNameID;/* The first ‘name’ table name ID |
447 HBUINT16 firstParamUILabelNameID;/* The first ‘name’ table name ID |
448 * used to specify strings for |
448 * used to specify strings for |
449 * user-interface labels for the |
449 * user-interface labels for the |
450 * feature parameters. (Must be zero |
450 * feature parameters. (Must be zero |
451 * if numParameters is zero.) */ |
451 * if numParameters is zero.) */ |
452 ArrayOf<UINT24> |
452 ArrayOf<UINT24> |
560 }; |
560 }; |
561 |
561 |
562 typedef RecordListOf<Feature> FeatureList; |
562 typedef RecordListOf<Feature> FeatureList; |
563 |
563 |
564 |
564 |
565 struct LookupFlag : USHORT |
565 struct LookupFlag : HBUINT16 |
566 { |
566 { |
567 enum Flags { |
567 enum Flags { |
568 RightToLeft = 0x0001u, |
568 RightToLeft = 0x0001u, |
569 IgnoreBaseGlyphs = 0x0002u, |
569 IgnoreBaseGlyphs = 0x0002u, |
570 IgnoreLigatures = 0x0004u, |
570 IgnoreLigatures = 0x0004u, |
638 lookupType.set (lookup_type); |
638 lookupType.set (lookup_type); |
639 lookupFlag.set (lookup_props & 0xFFFFu); |
639 lookupFlag.set (lookup_props & 0xFFFFu); |
640 if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); |
640 if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); |
641 if (lookupFlag & LookupFlag::UseMarkFilteringSet) |
641 if (lookupFlag & LookupFlag::UseMarkFilteringSet) |
642 { |
642 { |
643 USHORT &markFilteringSet = StructAfter<USHORT> (subTable); |
643 HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable); |
644 markFilteringSet.set (lookup_props >> 16); |
644 markFilteringSet.set (lookup_props >> 16); |
645 } |
645 } |
646 return_trace (true); |
646 return_trace (true); |
647 } |
647 } |
648 |
648 |
651 TRACE_SANITIZE (this); |
651 TRACE_SANITIZE (this); |
652 /* Real sanitize of the subtables is done by GSUB/GPOS/... */ |
652 /* Real sanitize of the subtables is done by GSUB/GPOS/... */ |
653 if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); |
653 if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); |
654 if (lookupFlag & LookupFlag::UseMarkFilteringSet) |
654 if (lookupFlag & LookupFlag::UseMarkFilteringSet) |
655 { |
655 { |
656 const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); |
656 const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable); |
657 if (!markFilteringSet.sanitize (c)) return_trace (false); |
657 if (!markFilteringSet.sanitize (c)) return_trace (false); |
658 } |
658 } |
659 return_trace (true); |
659 return_trace (true); |
660 } |
660 } |
661 |
661 |
662 private: |
662 private: |
663 USHORT lookupType; /* Different enumerations for GSUB and GPOS */ |
663 HBUINT16 lookupType; /* Different enumerations for GSUB and GPOS */ |
664 USHORT lookupFlag; /* Lookup qualifiers */ |
664 HBUINT16 lookupFlag; /* Lookup qualifiers */ |
665 ArrayOf<Offset<> > |
665 ArrayOf<Offset16> |
666 subTable; /* Array of SubTables */ |
666 subTable; /* Array of SubTables */ |
667 USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets |
667 HBUINT16 markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets |
668 * structure. This field is only present if bit |
668 * structure. This field is only present if bit |
669 * UseMarkFilteringSet of lookup flags is set. */ |
669 * UseMarkFilteringSet of lookup flags is set. */ |
670 public: |
670 public: |
671 DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); |
671 DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); |
672 }; |
672 }; |
698 if (unlikely (!c->extend_min (*this))) return_trace (false); |
698 if (unlikely (!c->extend_min (*this))) return_trace (false); |
699 glyphArray.len.set (num_glyphs); |
699 glyphArray.len.set (num_glyphs); |
700 if (unlikely (!c->extend (glyphArray))) return_trace (false); |
700 if (unlikely (!c->extend (glyphArray))) return_trace (false); |
701 for (unsigned int i = 0; i < num_glyphs; i++) |
701 for (unsigned int i = 0; i < num_glyphs; i++) |
702 glyphArray[i] = glyphs[i]; |
702 glyphArray[i] = glyphs[i]; |
703 glyphs.advance (num_glyphs); |
703 glyphs += num_glyphs; |
704 return_trace (true); |
704 return_trace (true); |
705 } |
705 } |
706 |
706 |
707 inline bool sanitize (hb_sanitize_context_t *c) const |
707 inline bool sanitize (hb_sanitize_context_t *c) const |
708 { |
708 { |
713 inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { |
713 inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { |
714 return glyphs->has (glyphArray[index]); |
714 return glyphs->has (glyphArray[index]); |
715 } |
715 } |
716 |
716 |
717 template <typename set_t> |
717 template <typename set_t> |
718 inline void add_coverage (set_t *glyphs) const { |
718 inline bool add_coverage (set_t *glyphs) const { |
719 unsigned int count = glyphArray.len; |
719 return glyphs->add_sorted_array (glyphArray.array, glyphArray.len); |
720 for (unsigned int i = 0; i < count; i++) |
|
721 glyphs->add (glyphArray[i]); |
|
722 } |
720 } |
723 |
721 |
724 public: |
722 public: |
725 /* Older compilers need this to be public. */ |
723 /* Older compilers need this to be public. */ |
726 struct Iter { |
724 struct Iter { |
815 } |
813 } |
816 return false; |
814 return false; |
817 } |
815 } |
818 |
816 |
819 template <typename set_t> |
817 template <typename set_t> |
820 inline void add_coverage (set_t *glyphs) const { |
818 inline bool add_coverage (set_t *glyphs) const { |
821 unsigned int count = rangeRecord.len; |
819 unsigned int count = rangeRecord.len; |
822 for (unsigned int i = 0; i < count; i++) |
820 for (unsigned int i = 0; i < count; i++) |
823 rangeRecord[i].add_coverage (glyphs); |
821 if (unlikely (!rangeRecord[i].add_coverage (glyphs))) |
|
822 return false; |
|
823 return true; |
824 } |
824 } |
825 |
825 |
826 public: |
826 public: |
827 /* Older compilers need this to be public. */ |
827 /* Older compilers need this to be public. */ |
828 struct Iter |
828 struct Iter |
858 unsigned int i, j, coverage; |
858 unsigned int i, j, coverage; |
859 }; |
859 }; |
860 private: |
860 private: |
861 |
861 |
862 protected: |
862 protected: |
863 USHORT coverageFormat; /* Format identifier--format = 2 */ |
863 HBUINT16 coverageFormat; /* Format identifier--format = 2 */ |
864 SortedArrayOf<RangeRecord> |
864 SortedArrayOf<RangeRecord> |
865 rangeRecord; /* Array of glyph ranges--ordered by |
865 rangeRecord; /* Array of glyph ranges--ordered by |
866 * Start GlyphID. rangeCount entries |
866 * Start GlyphID. rangeCount entries |
867 * long */ |
867 * long */ |
868 public: |
868 public: |
872 struct Coverage |
872 struct Coverage |
873 { |
873 { |
874 inline unsigned int get_coverage (hb_codepoint_t glyph_id) const |
874 inline unsigned int get_coverage (hb_codepoint_t glyph_id) const |
875 { |
875 { |
876 switch (u.format) { |
876 switch (u.format) { |
877 case 1: return u.format1.get_coverage(glyph_id); |
877 case 1: return u.format1.get_coverage (glyph_id); |
878 case 2: return u.format2.get_coverage(glyph_id); |
878 case 2: return u.format2.get_coverage (glyph_id); |
879 default:return NOT_COVERED; |
879 default:return NOT_COVERED; |
880 } |
880 } |
881 } |
881 } |
882 |
882 |
883 inline bool serialize (hb_serialize_context_t *c, |
883 inline bool serialize (hb_serialize_context_t *c, |
925 case 2: return u.format2.intersects_coverage (glyphs, index); |
925 case 2: return u.format2.intersects_coverage (glyphs, index); |
926 default:return false; |
926 default:return false; |
927 } |
927 } |
928 } |
928 } |
929 |
929 |
|
930 /* Might return false if array looks unsorted. |
|
931 * Used for faster rejection of corrupt data. */ |
930 template <typename set_t> |
932 template <typename set_t> |
931 inline void add_coverage (set_t *glyphs) const { |
933 inline bool add_coverage (set_t *glyphs) const { |
932 switch (u.format) { |
934 switch (u.format) { |
933 case 1: u.format1.add_coverage (glyphs); break; |
935 case 1: return u.format1.add_coverage (glyphs); |
934 case 2: u.format2.add_coverage (glyphs); break; |
936 case 2: return u.format2.add_coverage (glyphs); |
935 default: break; |
937 default:return false; |
936 } |
938 } |
937 } |
939 } |
938 |
940 |
939 struct Iter { |
941 struct Iter { |
940 Iter (void) : format (0), u () {}; |
942 Iter (void) : format (0), u () {}; |
1016 TRACE_SANITIZE (this); |
1018 TRACE_SANITIZE (this); |
1017 return_trace (c->check_struct (this) && classValue.sanitize (c)); |
1019 return_trace (c->check_struct (this) && classValue.sanitize (c)); |
1018 } |
1020 } |
1019 |
1021 |
1020 template <typename set_t> |
1022 template <typename set_t> |
1021 inline void add_class (set_t *glyphs, unsigned int klass) const { |
1023 inline bool add_coverage (set_t *glyphs) const { |
|
1024 unsigned int start = 0; |
1022 unsigned int count = classValue.len; |
1025 unsigned int count = classValue.len; |
1023 for (unsigned int i = 0; i < count; i++) |
1026 for (unsigned int i = 0; i < count; i++) |
|
1027 { |
|
1028 if (classValue[i]) |
|
1029 continue; |
|
1030 |
|
1031 if (start != i) |
|
1032 if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i))) |
|
1033 return false; |
|
1034 |
|
1035 start = i + 1; |
|
1036 } |
|
1037 if (start != count) |
|
1038 if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + count))) |
|
1039 return false; |
|
1040 |
|
1041 return true; |
|
1042 } |
|
1043 |
|
1044 template <typename set_t> |
|
1045 inline bool add_class (set_t *glyphs, unsigned int klass) const { |
|
1046 unsigned int count = classValue.len; |
|
1047 for (unsigned int i = 0; i < count; i++) |
|
1048 { |
1024 if (classValue[i] == klass) |
1049 if (classValue[i] == klass) |
1025 glyphs->add (startGlyph + i); |
1050 glyphs->add (startGlyph + i); |
|
1051 } |
|
1052 return true; |
1026 } |
1053 } |
1027 |
1054 |
1028 inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { |
1055 inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { |
1029 unsigned int count = classValue.len; |
1056 unsigned int count = classValue.len; |
1030 if (klass == 0) |
1057 if (klass == 0) |
1031 { |
1058 { |
1032 /* Match if there's any glyph that is not listed! */ |
1059 /* Match if there's any glyph that is not listed! */ |
1033 hb_codepoint_t g = -1; |
1060 hb_codepoint_t g = HB_SET_VALUE_INVALID; |
1034 if (!hb_set_next (glyphs, &g)) |
1061 if (!hb_set_next (glyphs, &g)) |
1035 return false; |
1062 return false; |
1036 if (g < startGlyph) |
1063 if (g < startGlyph) |
1037 return true; |
1064 return true; |
1038 g = startGlyph + count - 1; |
1065 g = startGlyph + count - 1; |
1073 TRACE_SANITIZE (this); |
1100 TRACE_SANITIZE (this); |
1074 return_trace (rangeRecord.sanitize (c)); |
1101 return_trace (rangeRecord.sanitize (c)); |
1075 } |
1102 } |
1076 |
1103 |
1077 template <typename set_t> |
1104 template <typename set_t> |
1078 inline void add_class (set_t *glyphs, unsigned int klass) const { |
1105 inline bool add_coverage (set_t *glyphs) const { |
1079 unsigned int count = rangeRecord.len; |
1106 unsigned int count = rangeRecord.len; |
1080 for (unsigned int i = 0; i < count; i++) |
1107 for (unsigned int i = 0; i < count; i++) |
|
1108 if (rangeRecord[i].value) |
|
1109 if (unlikely (!rangeRecord[i].add_coverage (glyphs))) |
|
1110 return false; |
|
1111 return true; |
|
1112 } |
|
1113 |
|
1114 template <typename set_t> |
|
1115 inline bool add_class (set_t *glyphs, unsigned int klass) const { |
|
1116 unsigned int count = rangeRecord.len; |
|
1117 for (unsigned int i = 0; i < count; i++) |
|
1118 { |
1081 if (rangeRecord[i].value == klass) |
1119 if (rangeRecord[i].value == klass) |
1082 rangeRecord[i].add_coverage (glyphs); |
1120 if (unlikely (!rangeRecord[i].add_coverage (glyphs))) |
|
1121 return false; |
|
1122 } |
|
1123 return true; |
1083 } |
1124 } |
1084 |
1125 |
1085 inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { |
1126 inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { |
1086 unsigned int count = rangeRecord.len; |
1127 unsigned int count = rangeRecord.len; |
1087 if (klass == 0) |
1128 if (klass == 0) |
1088 { |
1129 { |
1089 /* Match if there's any glyph that is not listed! */ |
1130 /* Match if there's any glyph that is not listed! */ |
1090 hb_codepoint_t g = (hb_codepoint_t) -1; |
1131 hb_codepoint_t g = HB_SET_VALUE_INVALID; |
1091 for (unsigned int i = 0; i < count; i++) |
1132 for (unsigned int i = 0; i < count; i++) |
1092 { |
1133 { |
1093 if (!hb_set_next (glyphs, &g)) |
1134 if (!hb_set_next (glyphs, &g)) |
1094 break; |
1135 break; |
1095 if (g < rangeRecord[i].start) |
1136 if (g < rangeRecord[i].start) |
1096 return true; |
1137 return true; |
1097 g = rangeRecord[i].end; |
1138 g = rangeRecord[i].end; |
1098 } |
1139 } |
1099 if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g)) |
1140 if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) |
1100 return true; |
1141 return true; |
1101 /* Fall through. */ |
1142 /* Fall through. */ |
1102 } |
1143 } |
1103 for (unsigned int i = 0; i < count; i++) |
1144 for (unsigned int i = 0; i < count; i++) |
1104 if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) |
1145 if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) |
1105 return true; |
1146 return true; |
1106 return false; |
1147 return false; |
1107 } |
1148 } |
1108 |
1149 |
1109 protected: |
1150 protected: |
1110 USHORT classFormat; /* Format identifier--format = 2 */ |
1151 HBUINT16 classFormat; /* Format identifier--format = 2 */ |
1111 SortedArrayOf<RangeRecord> |
1152 SortedArrayOf<RangeRecord> |
1112 rangeRecord; /* Array of glyph ranges--ordered by |
1153 rangeRecord; /* Array of glyph ranges--ordered by |
1113 * Start GlyphID */ |
1154 * Start GlyphID */ |
1114 public: |
1155 public: |
1115 DEFINE_SIZE_ARRAY (4, rangeRecord); |
1156 DEFINE_SIZE_ARRAY (4, rangeRecord); |
1135 case 2: return_trace (u.format2.sanitize (c)); |
1176 case 2: return_trace (u.format2.sanitize (c)); |
1136 default:return_trace (true); |
1177 default:return_trace (true); |
1137 } |
1178 } |
1138 } |
1179 } |
1139 |
1180 |
1140 inline void add_class (hb_set_t *glyphs, unsigned int klass) const { |
1181 /* Might return false if array looks unsorted. |
|
1182 * Used for faster rejection of corrupt data. */ |
|
1183 template <typename set_t> |
|
1184 inline bool add_coverage (set_t *glyphs) const { |
1141 switch (u.format) { |
1185 switch (u.format) { |
1142 case 1: u.format1.add_class (glyphs, klass); return; |
1186 case 1: return u.format1.add_coverage (glyphs); |
1143 case 2: u.format2.add_class (glyphs, klass); return; |
1187 case 2: return u.format2.add_coverage (glyphs); |
1144 default:return; |
1188 default:return false; |
|
1189 } |
|
1190 } |
|
1191 |
|
1192 /* Might return false if array looks unsorted. |
|
1193 * Used for faster rejection of corrupt data. */ |
|
1194 template <typename set_t> |
|
1195 inline bool add_class (set_t *glyphs, unsigned int klass) const { |
|
1196 switch (u.format) { |
|
1197 case 1: return u.format1.add_class (glyphs, klass); |
|
1198 case 2: return u.format2.add_class (glyphs, klass); |
|
1199 default:return false; |
1145 } |
1200 } |
1146 } |
1201 } |
1147 |
1202 |
1148 inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { |
1203 inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { |
1149 switch (u.format) { |
1204 switch (u.format) { |
1263 return 0.; |
1319 return 0.; |
1264 |
1320 |
1265 unsigned int count = regionIndices.len; |
1321 unsigned int count = regionIndices.len; |
1266 unsigned int scount = shortCount; |
1322 unsigned int scount = shortCount; |
1267 |
1323 |
1268 const BYTE *bytes = &StructAfter<BYTE> (regionIndices); |
1324 const HBUINT8 *bytes = &StructAfter<HBUINT8> (regionIndices); |
1269 const BYTE *row = bytes + inner * (scount + count); |
1325 const HBUINT8 *row = bytes + inner * (scount + count); |
1270 |
1326 |
1271 float delta = 0.; |
1327 float delta = 0.; |
1272 unsigned int i = 0; |
1328 unsigned int i = 0; |
1273 |
1329 |
1274 const SHORT *scursor = reinterpret_cast<const SHORT *> (row); |
1330 const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row); |
1275 for (; i < scount; i++) |
1331 for (; i < scount; i++) |
1276 { |
1332 { |
1277 float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); |
1333 float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); |
1278 delta += scalar * *scursor++; |
1334 delta += scalar * *scursor++; |
1279 } |
1335 } |
1280 const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor); |
1336 const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor); |
1281 for (; i < count; i++) |
1337 for (; i < count; i++) |
1282 { |
1338 { |
1283 float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); |
1339 float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); |
1284 delta += scalar * *bcursor++; |
1340 delta += scalar * *bcursor++; |
1285 } |
1341 } |
1291 { |
1347 { |
1292 TRACE_SANITIZE (this); |
1348 TRACE_SANITIZE (this); |
1293 return_trace (c->check_struct (this) && |
1349 return_trace (c->check_struct (this) && |
1294 regionIndices.sanitize(c) && |
1350 regionIndices.sanitize(c) && |
1295 shortCount <= regionIndices.len && |
1351 shortCount <= regionIndices.len && |
1296 c->check_array (&StructAfter<BYTE> (regionIndices), |
1352 c->check_array (&StructAfter<HBUINT8> (regionIndices), |
1297 get_row_size (), itemCount)); |
1353 get_row_size (), itemCount)); |
1298 } |
1354 } |
1299 |
1355 |
1300 protected: |
1356 protected: |
1301 USHORT itemCount; |
1357 HBUINT16 itemCount; |
1302 USHORT shortCount; |
1358 HBUINT16 shortCount; |
1303 ArrayOf<USHORT> regionIndices; |
1359 ArrayOf<HBUINT16> regionIndices; |
1304 BYTE bytesX[VAR]; |
1360 HBUINT8 bytesX[VAR]; |
1305 public: |
1361 public: |
1306 DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); |
1362 DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); |
1307 }; |
1363 }; |
1308 |
1364 |
1309 struct VariationStore |
1365 struct VariationStore |
1335 regions.sanitize (c, this) && |
1391 regions.sanitize (c, this) && |
1336 dataSets.sanitize (c, this)); |
1392 dataSets.sanitize (c, this)); |
1337 } |
1393 } |
1338 |
1394 |
1339 protected: |
1395 protected: |
1340 USHORT format; |
1396 HBUINT16 format; |
1341 LOffsetTo<VarRegionList> regions; |
1397 LOffsetTo<VarRegionList> regions; |
1342 OffsetArrayOf<VarData, ULONG> dataSets; |
1398 OffsetArrayOf<VarData, HBUINT32> dataSets; |
1343 public: |
1399 public: |
1344 DEFINE_SIZE_ARRAY (8, dataSets); |
1400 DEFINE_SIZE_ARRAY (8, dataSets); |
1345 }; |
1401 }; |
1346 |
1402 |
1347 /* |
1403 /* |
1419 TRACE_SANITIZE (this); |
1475 TRACE_SANITIZE (this); |
1420 return_trace (conditions.sanitize (c, this)); |
1476 return_trace (conditions.sanitize (c, this)); |
1421 } |
1477 } |
1422 |
1478 |
1423 protected: |
1479 protected: |
1424 OffsetArrayOf<Condition, ULONG> conditions; |
1480 OffsetArrayOf<Condition, HBUINT32> conditions; |
1425 public: |
1481 public: |
1426 DEFINE_SIZE_ARRAY (2, conditions); |
1482 DEFINE_SIZE_ARRAY (2, conditions); |
1427 }; |
1483 }; |
1428 |
1484 |
1429 struct FeatureTableSubstitutionRecord |
1485 struct FeatureTableSubstitutionRecord |
1555 { return get_delta (font->y_ppem, font->y_scale); } |
1611 { return get_delta (font->y_ppem, font->y_scale); } |
1556 |
1612 |
1557 inline unsigned int get_size (void) const |
1613 inline unsigned int get_size (void) const |
1558 { |
1614 { |
1559 unsigned int f = deltaFormat; |
1615 unsigned int f = deltaFormat; |
1560 if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size; |
1616 if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * HBUINT16::static_size; |
1561 return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); |
1617 return HBUINT16::static_size * (4 + ((endSize - startSize) >> (4 - f))); |
1562 } |
1618 } |
1563 |
1619 |
1564 inline bool sanitize (hb_sanitize_context_t *c) const |
1620 inline bool sanitize (hb_sanitize_context_t *c) const |
1565 { |
1621 { |
1566 TRACE_SANITIZE (this); |
1622 TRACE_SANITIZE (this); |
1601 |
1657 |
1602 return delta; |
1658 return delta; |
1603 } |
1659 } |
1604 |
1660 |
1605 protected: |
1661 protected: |
1606 USHORT startSize; /* Smallest size to correct--in ppem */ |
1662 HBUINT16 startSize; /* Smallest size to correct--in ppem */ |
1607 USHORT endSize; /* Largest size to correct--in ppem */ |
1663 HBUINT16 endSize; /* Largest size to correct--in ppem */ |
1608 USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 |
1664 HBUINT16 deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 |
1609 * 1 Signed 2-bit value, 8 values per uint16 |
1665 * 1 Signed 2-bit value, 8 values per uint16 |
1610 * 2 Signed 4-bit value, 4 values per uint16 |
1666 * 2 Signed 4-bit value, 4 values per uint16 |
1611 * 3 Signed 8-bit value, 2 values per uint16 |
1667 * 3 Signed 8-bit value, 2 values per uint16 |
1612 */ |
1668 */ |
1613 USHORT deltaValue[VAR]; /* Array of compressed data */ |
1669 HBUINT16 deltaValue[VAR]; /* Array of compressed data */ |
1614 public: |
1670 public: |
1615 DEFINE_SIZE_ARRAY (6, deltaValue); |
1671 DEFINE_SIZE_ARRAY (6, deltaValue); |
1616 }; |
1672 }; |
1617 |
1673 |
1618 struct VariationDevice |
1674 struct VariationDevice |
1639 { |
1695 { |
1640 return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coords); |
1696 return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coords); |
1641 } |
1697 } |
1642 |
1698 |
1643 protected: |
1699 protected: |
1644 USHORT outerIndex; |
1700 HBUINT16 outerIndex; |
1645 USHORT innerIndex; |
1701 HBUINT16 innerIndex; |
1646 USHORT deltaFormat; /* Format identifier for this table: 0x0x8000 */ |
1702 HBUINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */ |
1647 public: |
1703 public: |
1648 DEFINE_SIZE_STATIC (6); |
1704 DEFINE_SIZE_STATIC (6); |
1649 }; |
1705 }; |
1650 |
1706 |
1651 struct DeviceHeader |
1707 struct DeviceHeader |
1652 { |
1708 { |
1653 protected: |
1709 protected: |
1654 USHORT reserved1; |
1710 HBUINT16 reserved1; |
1655 USHORT reserved2; |
1711 HBUINT16 reserved2; |
1656 public: |
1712 public: |
1657 USHORT format; /* Format identifier */ |
1713 HBUINT16 format; /* Format identifier */ |
1658 public: |
1714 public: |
1659 DEFINE_SIZE_STATIC (6); |
1715 DEFINE_SIZE_STATIC (6); |
1660 }; |
1716 }; |
1661 |
1717 |
1662 struct Device |
1718 struct Device |