25 */ |
25 */ |
26 |
26 |
27 #ifndef HB_OT_VAR_MVAR_TABLE_HH |
27 #ifndef HB_OT_VAR_MVAR_TABLE_HH |
28 #define HB_OT_VAR_MVAR_TABLE_HH |
28 #define HB_OT_VAR_MVAR_TABLE_HH |
29 |
29 |
30 #include "hb-ot-layout-common-private.hh" |
30 #include "hb-ot-layout-common.hh" |
31 |
31 |
32 |
32 |
33 namespace OT { |
33 namespace OT { |
34 |
34 |
35 |
35 |
36 struct VariationValueRecord |
36 struct VariationValueRecord |
37 { |
37 { |
38 inline bool sanitize (hb_sanitize_context_t *c) const |
38 bool sanitize (hb_sanitize_context_t *c) const |
39 { |
39 { |
40 TRACE_SANITIZE (this); |
40 TRACE_SANITIZE (this); |
41 return_trace (c->check_struct (this)); |
41 return_trace (c->check_struct (this)); |
42 } |
42 } |
43 |
43 |
56 */ |
56 */ |
57 #define HB_OT_TAG_MVAR HB_TAG('M','V','A','R') |
57 #define HB_OT_TAG_MVAR HB_TAG('M','V','A','R') |
58 |
58 |
59 struct MVAR |
59 struct MVAR |
60 { |
60 { |
61 static const hb_tag_t tableTag = HB_OT_TAG_MVAR; |
61 static constexpr hb_tag_t tableTag = HB_OT_TAG_MVAR; |
62 |
62 |
63 inline bool sanitize (hb_sanitize_context_t *c) const |
63 bool sanitize (hb_sanitize_context_t *c) const |
64 { |
64 { |
65 TRACE_SANITIZE (this); |
65 TRACE_SANITIZE (this); |
66 return_trace (version.sanitize (c) && |
66 return_trace (version.sanitize (c) && |
67 likely (version.major == 1) && |
67 likely (version.major == 1) && |
68 c->check_struct (this) && |
68 c->check_struct (this) && |
69 valueRecordSize >= VariationValueRecord::static_size && |
69 valueRecordSize >= VariationValueRecord::static_size && |
70 varStore.sanitize (c, this) && |
70 varStore.sanitize (c, this) && |
71 c->check_array (values, valueRecordSize, valueRecordCount)); |
71 c->check_range (valuesZ.arrayZ, |
|
72 valueRecordCount, |
|
73 valueRecordSize)); |
72 } |
74 } |
73 |
75 |
74 inline float get_var (hb_tag_t tag, |
76 float get_var (hb_tag_t tag, |
75 int *coords, unsigned int coord_count) const |
77 const int *coords, unsigned int coord_count) const |
76 { |
78 { |
77 const VariationValueRecord *record; |
79 const VariationValueRecord *record; |
78 record = (VariationValueRecord *) bsearch (&tag, values, |
80 record = (VariationValueRecord *) bsearch (&tag, valuesZ.arrayZ, |
79 valueRecordCount, valueRecordSize, |
81 valueRecordCount, valueRecordSize, |
80 tag_compare); |
82 tag_compare); |
81 if (!record) |
83 if (!record) |
82 return 0.; |
84 return 0.; |
83 |
85 |
84 return (this+varStore).get_delta (record->varIdx, coords, coord_count); |
86 return (this+varStore).get_delta (record->varIdx, coords, coord_count); |
85 } |
87 } |
86 |
88 |
87 protected: |
89 protected: |
88 static inline int tag_compare (const void *pa, const void *pb) |
90 static int tag_compare (const void *pa, const void *pb) |
89 { |
91 { |
90 const hb_tag_t *a = (const hb_tag_t *) pa; |
92 const hb_tag_t *a = (const hb_tag_t *) pa; |
91 const Tag *b = (const Tag *) pb; |
93 const Tag *b = (const Tag *) pb; |
92 return b->cmp (*a); |
94 return b->cmp (*a); |
93 } |
95 } |
99 HBUINT16 valueRecordSize;/* The size in bytes of each value record — |
101 HBUINT16 valueRecordSize;/* The size in bytes of each value record — |
100 * must be greater than zero. */ |
102 * must be greater than zero. */ |
101 HBUINT16 valueRecordCount;/* The number of value records — may be zero. */ |
103 HBUINT16 valueRecordCount;/* The number of value records — may be zero. */ |
102 OffsetTo<VariationStore> |
104 OffsetTo<VariationStore> |
103 varStore; /* Offset to item variation store table. */ |
105 varStore; /* Offset to item variation store table. */ |
104 HBUINT8 values[VAR]; /* Array of value records. The records must be |
106 UnsizedArrayOf<HBUINT8> |
|
107 valuesZ; /* Array of value records. The records must be |
105 * in binary order of their valueTag field. */ |
108 * in binary order of their valueTag field. */ |
106 |
109 |
107 public: |
110 public: |
108 DEFINE_SIZE_ARRAY (12, values); |
111 DEFINE_SIZE_ARRAY (12, valuesZ); |
109 }; |
112 }; |
110 |
113 |
111 } /* namespace OT */ |
114 } /* namespace OT */ |
112 |
115 |
113 |
116 |