83 hb_face_t *face, |
83 hb_face_t *face, |
84 unsigned int table_index, |
84 unsigned int table_index, |
85 unsigned int feature_index, |
85 unsigned int feature_index, |
86 unsigned int variations_index, |
86 unsigned int variations_index, |
87 hb_mask_t mask, |
87 hb_mask_t mask, |
|
88 bool auto_zwnj, |
88 bool auto_zwj) |
89 bool auto_zwj) |
89 { |
90 { |
90 unsigned int lookup_indices[32]; |
91 unsigned int lookup_indices[32]; |
91 unsigned int offset, len; |
92 unsigned int offset, len; |
92 unsigned int table_lookup_count; |
93 unsigned int table_lookup_count; |
110 hb_ot_map_t::lookup_map_t *lookup = m.lookups[table_index].push (); |
111 hb_ot_map_t::lookup_map_t *lookup = m.lookups[table_index].push (); |
111 if (unlikely (!lookup)) |
112 if (unlikely (!lookup)) |
112 return; |
113 return; |
113 lookup->mask = mask; |
114 lookup->mask = mask; |
114 lookup->index = lookup_indices[i]; |
115 lookup->index = lookup_indices[i]; |
|
116 lookup->auto_zwnj = auto_zwnj; |
115 lookup->auto_zwj = auto_zwj; |
117 lookup->auto_zwj = auto_zwj; |
116 } |
118 } |
117 |
119 |
118 offset += len; |
120 offset += len; |
119 } while (len == ARRAY_LENGTH (lookup_indices)); |
121 } while (len == ARRAY_LENGTH (lookup_indices)); |
134 void |
136 void |
135 hb_ot_map_builder_t::compile (hb_ot_map_t &m, |
137 hb_ot_map_builder_t::compile (hb_ot_map_t &m, |
136 const int *coords, |
138 const int *coords, |
137 unsigned int num_coords) |
139 unsigned int num_coords) |
138 { |
140 { |
139 m.global_mask = 1; |
141 static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), ""); |
|
142 unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1; |
|
143 unsigned int global_bit_shift = _hb_popcount32 (HB_GLYPH_FLAG_DEFINED); |
|
144 |
|
145 m.global_mask = global_bit_mask; |
140 |
146 |
141 unsigned int required_feature_index[2]; |
147 unsigned int required_feature_index[2]; |
142 hb_tag_t required_feature_tag[2]; |
148 hb_tag_t required_feature_tag[2]; |
143 /* We default to applying required feature in stage 0. If the required |
149 /* We default to applying required feature in stage 0. If the required |
144 * feature has a tag that is known to the shaper, we apply required feature |
150 * feature has a tag that is known to the shaper, we apply required feature |
186 feature_infos.shrink (j + 1); |
192 feature_infos.shrink (j + 1); |
187 } |
193 } |
188 |
194 |
189 |
195 |
190 /* Allocate bits now */ |
196 /* Allocate bits now */ |
191 unsigned int next_bit = 1; |
197 unsigned int next_bit = global_bit_shift + 1; |
|
198 |
192 for (unsigned int i = 0; i < feature_infos.len; i++) |
199 for (unsigned int i = 0; i < feature_infos.len; i++) |
193 { |
200 { |
194 const feature_info_t *info = &feature_infos[i]; |
201 const feature_info_t *info = &feature_infos[i]; |
195 |
202 |
196 unsigned int bits_needed; |
203 unsigned int bits_needed; |
241 map->tag = info->tag; |
248 map->tag = info->tag; |
242 map->index[0] = feature_index[0]; |
249 map->index[0] = feature_index[0]; |
243 map->index[1] = feature_index[1]; |
250 map->index[1] = feature_index[1]; |
244 map->stage[0] = info->stage[0]; |
251 map->stage[0] = info->stage[0]; |
245 map->stage[1] = info->stage[1]; |
252 map->stage[1] = info->stage[1]; |
|
253 map->auto_zwnj = !(info->flags & F_MANUAL_ZWNJ); |
246 map->auto_zwj = !(info->flags & F_MANUAL_ZWJ); |
254 map->auto_zwj = !(info->flags & F_MANUAL_ZWJ); |
247 if ((info->flags & F_GLOBAL) && info->max_value == 1) { |
255 if ((info->flags & F_GLOBAL) && info->max_value == 1) { |
248 /* Uses the global bit */ |
256 /* Uses the global bit */ |
249 map->shift = 0; |
257 map->shift = global_bit_shift; |
250 map->mask = 1; |
258 map->mask = global_bit_mask; |
251 } else { |
259 } else { |
252 map->shift = next_bit; |
260 map->shift = next_bit; |
253 map->mask = (1u << (next_bit + bits_needed)) - (1u << next_bit); |
261 map->mask = (1u << (next_bit + bits_needed)) - (1u << next_bit); |
254 next_bit += bits_needed; |
262 next_bit += bits_needed; |
255 m.global_mask |= (info->default_value << map->shift) & map->mask; |
263 m.global_mask |= (info->default_value << map->shift) & map->mask; |
259 |
267 |
260 } |
268 } |
261 feature_infos.shrink (0); /* Done with these */ |
269 feature_infos.shrink (0); /* Done with these */ |
262 |
270 |
263 |
271 |
264 add_gsub_pause (NULL); |
272 add_gsub_pause (nullptr); |
265 add_gpos_pause (NULL); |
273 add_gpos_pause (nullptr); |
266 |
274 |
267 for (unsigned int table_index = 0; table_index < 2; table_index++) |
275 for (unsigned int table_index = 0; table_index < 2; table_index++) |
268 { |
276 { |
269 /* Collect lookup indices for features */ |
277 /* Collect lookup indices for features */ |
270 |
278 |
282 if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX && |
290 if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX && |
283 required_feature_stage[table_index] == stage) |
291 required_feature_stage[table_index] == stage) |
284 add_lookups (m, face, table_index, |
292 add_lookups (m, face, table_index, |
285 required_feature_index[table_index], |
293 required_feature_index[table_index], |
286 variations_index, |
294 variations_index, |
287 1 /* mask */, |
295 global_bit_mask); |
288 true /* auto_zwj */); |
|
289 |
296 |
290 for (unsigned i = 0; i < m.features.len; i++) |
297 for (unsigned i = 0; i < m.features.len; i++) |
291 if (m.features[i].stage[table_index] == stage) |
298 if (m.features[i].stage[table_index] == stage) |
292 add_lookups (m, face, table_index, |
299 add_lookups (m, face, table_index, |
293 m.features[i].index[table_index], |
300 m.features[i].index[table_index], |
294 variations_index, |
301 variations_index, |
295 m.features[i].mask, |
302 m.features[i].mask, |
|
303 m.features[i].auto_zwnj, |
296 m.features[i].auto_zwj); |
304 m.features[i].auto_zwj); |
297 |
305 |
298 /* Sort lookups and merge duplicates */ |
306 /* Sort lookups and merge duplicates */ |
299 if (last_num_lookups < m.lookups[table_index].len) |
307 if (last_num_lookups < m.lookups[table_index].len) |
300 { |
308 { |
305 if (m.lookups[table_index][i].index != m.lookups[table_index][j].index) |
313 if (m.lookups[table_index][i].index != m.lookups[table_index][j].index) |
306 m.lookups[table_index][++j] = m.lookups[table_index][i]; |
314 m.lookups[table_index][++j] = m.lookups[table_index][i]; |
307 else |
315 else |
308 { |
316 { |
309 m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask; |
317 m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask; |
|
318 m.lookups[table_index][j].auto_zwnj &= m.lookups[table_index][i].auto_zwnj; |
310 m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj; |
319 m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj; |
311 } |
320 } |
312 m.lookups[table_index].shrink (j + 1); |
321 m.lookups[table_index].shrink (j + 1); |
313 } |
322 } |
314 |
323 |