/src/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh
Line | Count | Source |
1 | | #ifndef OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH |
2 | | #define OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH |
3 | | |
4 | | #include "Common.hh" |
5 | | |
6 | | namespace OT { |
7 | | namespace Layout { |
8 | | namespace GPOS_impl { |
9 | | |
10 | | struct SinglePosFormat2 : ValueBase |
11 | | { |
12 | | protected: |
13 | | HBUINT16 format; /* Format identifier--format = 2 */ |
14 | | Offset16To<Coverage> |
15 | | coverage; /* Offset to Coverage table--from |
16 | | * beginning of subtable */ |
17 | | ValueFormat valueFormat; /* Defines the types of data in the |
18 | | * ValueRecord */ |
19 | | HBUINT16 valueCount; /* Number of ValueRecords */ |
20 | | ValueRecord values; /* Array of ValueRecords--positioning |
21 | | * values applied to glyphs */ |
22 | | public: |
23 | | DEFINE_SIZE_ARRAY (8, values); |
24 | | |
25 | | bool sanitize (hb_sanitize_context_t *c) const |
26 | 0 | { |
27 | 0 | TRACE_SANITIZE (this); |
28 | 0 | return_trace (c->check_struct (this) && |
29 | 0 | coverage.sanitize (c, this) && |
30 | 0 | valueFormat.sanitize_values (c, this, values, valueCount)); |
31 | 0 | } |
32 | | |
33 | | bool intersects (const hb_set_t *glyphs) const |
34 | 0 | { return (this+coverage).intersects (glyphs); } |
35 | | |
36 | 0 | void closure_lookups (hb_closure_lookups_context_t *c) const {} |
37 | | void collect_variation_indices (hb_collect_variation_indices_context_t *c) const |
38 | 0 | { |
39 | 0 | if (!valueFormat.has_device ()) return; |
40 | 0 |
|
41 | 0 | auto it = |
42 | 0 | + hb_zip (this+coverage, hb_range ((unsigned) valueCount)) |
43 | 0 | | hb_filter (c->glyph_set, hb_first) |
44 | 0 | ; |
45 | 0 |
|
46 | 0 | if (!it) return; |
47 | 0 |
|
48 | 0 | unsigned sub_length = valueFormat.get_len (); |
49 | 0 | const hb_array_t<const Value> values_array = values.as_array (valueCount * sub_length); |
50 | 0 |
|
51 | 0 | for (unsigned i : + it |
52 | 0 | | hb_map (hb_second)) |
53 | 0 | valueFormat.collect_variation_indices (c, this, values_array.sub_array (i * sub_length, sub_length)); |
54 | 0 |
|
55 | 0 | } |
56 | | |
57 | | void collect_glyphs (hb_collect_glyphs_context_t *c) const |
58 | 0 | { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; } |
59 | | |
60 | 0 | const Coverage &get_coverage () const { return this+coverage; } |
61 | | |
62 | 0 | ValueFormat get_value_format () const { return valueFormat; } |
63 | | |
64 | | bool apply (hb_ot_apply_context_t *c) const |
65 | 0 | { |
66 | 0 | TRACE_APPLY (this); |
67 | 0 | hb_buffer_t *buffer = c->buffer; |
68 | 0 | unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); |
69 | 0 | if (index == NOT_COVERED) return_trace (false); |
70 | | |
71 | 0 | if (unlikely (index >= valueCount)) return_trace (false); |
72 | | |
73 | 0 | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) |
74 | 0 | { |
75 | 0 | c->buffer->message (c->font, |
76 | 0 | "positioning glyph at %u", |
77 | 0 | c->buffer->idx); |
78 | 0 | } |
79 | |
|
80 | 0 | valueFormat.apply_value (c, this, |
81 | 0 | &values[index * valueFormat.get_len ()], |
82 | 0 | buffer->cur_pos()); |
83 | |
|
84 | 0 | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) |
85 | 0 | { |
86 | 0 | c->buffer->message (c->font, |
87 | 0 | "positioned glyph at %u", |
88 | 0 | c->buffer->idx); |
89 | 0 | } |
90 | |
|
91 | 0 | buffer->idx++; |
92 | 0 | return_trace (true); |
93 | 0 | } |
94 | | |
95 | | bool |
96 | | position_single (hb_font_t *font, |
97 | | hb_blob_t *table_blob, |
98 | | hb_direction_t direction, |
99 | | hb_codepoint_t gid, |
100 | | hb_glyph_position_t &pos) const |
101 | 0 | { |
102 | 0 | unsigned int index = (this+coverage).get_coverage (gid); |
103 | 0 | if (likely (index == NOT_COVERED)) return false; |
104 | 0 | if (unlikely (index >= valueCount)) return false; |
105 | | |
106 | | /* This is ugly... */ |
107 | 0 | hb_buffer_t buffer; |
108 | 0 | buffer.props.direction = direction; |
109 | 0 | OT::hb_ot_apply_context_t c (1, font, &buffer, table_blob); |
110 | |
|
111 | 0 | valueFormat.apply_value (&c, this, |
112 | 0 | &values[index * valueFormat.get_len ()], |
113 | 0 | pos); |
114 | 0 | return true; |
115 | 0 | } |
116 | | |
117 | | |
118 | | template<typename Iterator, |
119 | | typename SrcLookup, |
120 | | hb_requires (hb_is_iterator (Iterator))> |
121 | | void serialize (hb_serialize_context_t *c, |
122 | | const SrcLookup *src, |
123 | | Iterator it, |
124 | | ValueFormat newFormat, |
125 | | const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) |
126 | 0 | { |
127 | 0 | auto out = c->extend_min (this); |
128 | 0 | if (unlikely (!out)) return; |
129 | 0 | if (unlikely (!c->check_assign (valueFormat, newFormat, HB_SERIALIZE_ERROR_INT_OVERFLOW))) return; |
130 | 0 | if (unlikely (!c->check_assign (valueCount, it.len (), HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return; |
131 | 0 |
|
132 | 0 | + it |
133 | 0 | | hb_map (hb_second) |
134 | 0 | | hb_apply ([&] (hb_array_t<const Value> _) |
135 | 0 | { src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_delta_map); }) |
136 | 0 | ; |
137 | 0 |
|
138 | 0 | auto glyphs = |
139 | 0 | + it |
140 | 0 | | hb_map_retains_sorting (hb_first) |
141 | 0 | ; |
142 | 0 |
|
143 | 0 | coverage.serialize_serialize (c, glyphs); |
144 | 0 | } Unexecuted instantiation: _ZN2OT6Layout9GPOS_impl16SinglePosFormat29serializeI13hb_zip_iter_tI13hb_map_iter_tIN23hb_bit_set_invertible_t6iter_tERK8hb_map_tL24hb_function_sortedness_t1ELPv0EE16hb_repeat_iter_tI10hb_array_tIKNS_7NumTypeILb1EtLj2EEEEEENS1_16SinglePosFormat1ETnPN12hb_enable_ifIXsr17hb_is_iterator_ofIT_NSO_6item_tEEE5valueEvE4typeELSC_0EEEvP22hb_serialize_context_tPKT0_SO_NS1_11ValueFormatEPK12hb_hashmap_tIj9hb_pair_tIjiELb0EE Unexecuted instantiation: hb-ot-face.cc:_ZN2OT6Layout9GPOS_impl16SinglePosFormat29serializeI13hb_map_iter_tI16hb_filter_iter_tI13hb_zip_iter_tINS0_6Common8Coverage6iter_tE15hb_range_iter_tIjjEERK8hb_set_tRK3$_6LPv0EEZNKS2_6subsetEP19hb_subset_context_tEUlRK9hb_pair_tIjjEE_L24hb_function_sortedness_t1ELSJ_0EES2_TnPN12hb_enable_ifIXsr17hb_is_iterator_ofIT_NSV_6item_tEEE5valueEvE4typeELSJ_0EEEvP22hb_serialize_context_tPKT0_SV_NS1_11ValueFormatEPK12hb_hashmap_tIjSN_IjiELb0EE Unexecuted instantiation: hb-aat-layout.cc:_ZN2OT6Layout9GPOS_impl16SinglePosFormat29serializeI13hb_map_iter_tI16hb_filter_iter_tI13hb_zip_iter_tINS0_6Common8Coverage6iter_tE15hb_range_iter_tIjjEERK8hb_set_tRK3$_6LPv0EEZNKS2_6subsetEP19hb_subset_context_tEUlRK9hb_pair_tIjjEE_L24hb_function_sortedness_t1ELSJ_0EES2_TnPN12hb_enable_ifIXsr17hb_is_iterator_ofIT_NSV_6item_tEEE5valueEvE4typeELSJ_0EEEvP22hb_serialize_context_tPKT0_SV_NS1_11ValueFormatEPK12hb_hashmap_tIjSN_IjiELb0EE Unexecuted instantiation: hb-ot-layout.cc:_ZN2OT6Layout9GPOS_impl16SinglePosFormat29serializeI13hb_map_iter_tI16hb_filter_iter_tI13hb_zip_iter_tINS0_6Common8Coverage6iter_tE15hb_range_iter_tIjjEERK8hb_set_tRK3$_6LPv0EEZNKS2_6subsetEP19hb_subset_context_tEUlRK9hb_pair_tIjjEE_L24hb_function_sortedness_t1ELSJ_0EES2_TnPN12hb_enable_ifIXsr17hb_is_iterator_ofIT_NSV_6item_tEEE5valueEvE4typeELSJ_0EEEvP22hb_serialize_context_tPKT0_SV_NS1_11ValueFormatEPK12hb_hashmap_tIjSN_IjiELb0EE Unexecuted instantiation: hb-ot-shape-fallback.cc:_ZN2OT6Layout9GPOS_impl16SinglePosFormat29serializeI13hb_map_iter_tI16hb_filter_iter_tI13hb_zip_iter_tINS0_6Common8Coverage6iter_tE15hb_range_iter_tIjjEERK8hb_set_tRK3$_6LPv0EEZNKS2_6subsetEP19hb_subset_context_tEUlRK9hb_pair_tIjjEE_L24hb_function_sortedness_t1ELSJ_0EES2_TnPN12hb_enable_ifIXsr17hb_is_iterator_ofIT_NSV_6item_tEEE5valueEvE4typeELSJ_0EEEvP22hb_serialize_context_tPKT0_SV_NS1_11ValueFormatEPK12hb_hashmap_tIjSN_IjiELb0EE |
145 | | |
146 | | template<typename Iterator, |
147 | | hb_requires (hb_is_iterator (Iterator))> |
148 | | unsigned compute_effective_format (const hb_face_t *face, |
149 | | Iterator it, |
150 | | bool is_instancing, bool strip_hints, |
151 | | bool has_gdef_varstore, |
152 | | const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map) const |
153 | 0 | { |
154 | 0 | hb_blob_t* blob = hb_face_reference_table (face, HB_TAG ('f','v','a','r')); |
155 | 0 | bool has_fvar = (blob != hb_blob_get_empty ()); |
156 | 0 | hb_blob_destroy (blob); |
157 | 0 |
|
158 | 0 | unsigned new_format = 0; |
159 | 0 | if (is_instancing) |
160 | 0 | { |
161 | 0 | new_format = new_format | valueFormat.get_effective_format (+ it | hb_map (hb_second), false, false, this, varidx_delta_map); |
162 | 0 | } |
163 | 0 | /* do not strip hints for VF */ |
164 | 0 | else if (strip_hints) |
165 | 0 | { |
166 | 0 | bool strip = !has_fvar; |
167 | 0 | if (has_fvar && !has_gdef_varstore) |
168 | 0 | strip = true; |
169 | 0 | new_format = new_format | valueFormat.get_effective_format (+ it | hb_map (hb_second), strip, true, this, nullptr); |
170 | 0 | } |
171 | 0 | else |
172 | 0 | new_format = valueFormat; |
173 | 0 |
|
174 | 0 | return new_format; |
175 | 0 | } Unexecuted instantiation: hb-ot-face.cc:_ZNK2OT6Layout9GPOS_impl16SinglePosFormat224compute_effective_formatI13hb_map_iter_tI16hb_filter_iter_tI13hb_zip_iter_tINS0_6Common8Coverage6iter_tE15hb_range_iter_tIjjEERK8hb_set_tRK3$_6LPv0EEZNKS2_6subsetEP19hb_subset_context_tEUlRK9hb_pair_tIjjEE_L24hb_function_sortedness_t1ELSJ_0EETnPN12hb_enable_ifIXsr17hb_is_iterator_ofIT_NSV_6item_tEEE5valueEvE4typeELSJ_0EEEjPK9hb_face_tSV_bbbPK12hb_hashmap_tIjSN_IjiELb0EE Unexecuted instantiation: hb-aat-layout.cc:_ZNK2OT6Layout9GPOS_impl16SinglePosFormat224compute_effective_formatI13hb_map_iter_tI16hb_filter_iter_tI13hb_zip_iter_tINS0_6Common8Coverage6iter_tE15hb_range_iter_tIjjEERK8hb_set_tRK3$_6LPv0EEZNKS2_6subsetEP19hb_subset_context_tEUlRK9hb_pair_tIjjEE_L24hb_function_sortedness_t1ELSJ_0EETnPN12hb_enable_ifIXsr17hb_is_iterator_ofIT_NSV_6item_tEEE5valueEvE4typeELSJ_0EEEjPK9hb_face_tSV_bbbPK12hb_hashmap_tIjSN_IjiELb0EE Unexecuted instantiation: hb-ot-layout.cc:_ZNK2OT6Layout9GPOS_impl16SinglePosFormat224compute_effective_formatI13hb_map_iter_tI16hb_filter_iter_tI13hb_zip_iter_tINS0_6Common8Coverage6iter_tE15hb_range_iter_tIjjEERK8hb_set_tRK3$_6LPv0EEZNKS2_6subsetEP19hb_subset_context_tEUlRK9hb_pair_tIjjEE_L24hb_function_sortedness_t1ELSJ_0EETnPN12hb_enable_ifIXsr17hb_is_iterator_ofIT_NSV_6item_tEEE5valueEvE4typeELSJ_0EEEjPK9hb_face_tSV_bbbPK12hb_hashmap_tIjSN_IjiELb0EE Unexecuted instantiation: hb-ot-shape-fallback.cc:_ZNK2OT6Layout9GPOS_impl16SinglePosFormat224compute_effective_formatI13hb_map_iter_tI16hb_filter_iter_tI13hb_zip_iter_tINS0_6Common8Coverage6iter_tE15hb_range_iter_tIjjEERK8hb_set_tRK3$_6LPv0EEZNKS2_6subsetEP19hb_subset_context_tEUlRK9hb_pair_tIjjEE_L24hb_function_sortedness_t1ELSJ_0EETnPN12hb_enable_ifIXsr17hb_is_iterator_ofIT_NSV_6item_tEEE5valueEvE4typeELSJ_0EEEjPK9hb_face_tSV_bbbPK12hb_hashmap_tIjSN_IjiELb0EE |
176 | | |
177 | | bool subset (hb_subset_context_t *c) const |
178 | 0 | { |
179 | 0 | TRACE_SUBSET (this); |
180 | 0 | const hb_set_t &glyphset = *c->plan->glyphset_gsub (); |
181 | 0 | const hb_map_t &glyph_map = *c->plan->glyph_map; |
182 | 0 |
|
183 | 0 | unsigned sub_length = valueFormat.get_len (); |
184 | 0 | auto values_array = values.as_array (valueCount * sub_length); |
185 | 0 |
|
186 | 0 | auto it = |
187 | 0 | + hb_zip (this+coverage, hb_range ((unsigned) valueCount)) |
188 | 0 | | hb_filter (glyphset, hb_first) |
189 | 0 | | hb_map_retains_sorting ([&] (const hb_pair_t<hb_codepoint_t, unsigned>& _) |
190 | 0 | { |
191 | 0 | return hb_pair (glyph_map[_.first], |
192 | 0 | values_array.sub_array (_.second * sub_length, |
193 | 0 | sub_length)); |
194 | 0 | }) |
195 | 0 | ; |
196 | 0 |
|
197 | 0 | unsigned new_format = compute_effective_format (c->plan->source, it, |
198 | 0 | bool (c->plan->normalized_coords), |
199 | 0 | bool (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING), |
200 | 0 | c->plan->has_gdef_varstore, |
201 | 0 | &c->plan->layout_variation_idx_delta_map); |
202 | 0 | bool ret = bool (it); |
203 | 0 | SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, new_format); |
204 | 0 | return_trace (ret); |
205 | 0 | } |
206 | | }; |
207 | | |
208 | | |
209 | | } |
210 | | } |
211 | | } |
212 | | |
213 | | #endif /* OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH */ |