HB_BEGIN_DECLS
-#define MAX_LOOKUPS 1000 /* FIXME */
-
static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
struct hb_ot_map_t {
}
inline void substitute (hb_face_t *face, hb_buffer_t *buffer) const {
- for (unsigned int i = 0; i < lookup_count[0]; i++)
+ for (unsigned int i = 0; i < lookup_maps[0].len; i++)
hb_ot_layout_substitute_lookup (face, buffer, lookup_maps[0][i].index, lookup_maps[0][i].mask);
}
inline void position (hb_font_t *font, hb_face_t *face, hb_buffer_t *buffer) const {
- for (unsigned int i = 0; i < lookup_count[1]; i++)
+ for (unsigned int i = 0; i < lookup_maps[1].len; i++)
hb_ot_layout_position_lookup (font, buffer, lookup_maps[1][i].index, lookup_maps[1][i].mask);
}
hb_mask_t global_mask;
- hb_prealloced_array_t<feature_info_t,16> feature_infos; /* used before compile() only */
- hb_prealloced_array_t<feature_map_t, 16> feature_maps;
+ hb_prealloced_array_t<feature_info_t,8> feature_infos; /* used before compile() only */
+ hb_prealloced_array_t<feature_map_t, 8> feature_maps;
- lookup_map_t lookup_maps[2][MAX_LOOKUPS]; /* GSUB/GPOS */
- unsigned int lookup_count[2];
+ hb_prealloced_array_t<lookup_map_t, 32> lookup_maps[2]; /* GSUB/GPOS */
};
unsigned int feature_index,
hb_mask_t mask)
{
- unsigned int i = MAX_LOOKUPS - lookup_count[table_index];
- lookup_map_t *lookups = lookup_maps[table_index] + lookup_count[table_index];
-
- unsigned int *lookup_indices = (unsigned int *) lookups;
-
- hb_ot_layout_feature_get_lookup_indexes (face,
- table_tags[table_index],
- feature_index,
- 0, &i,
- lookup_indices);
-
- lookup_count[table_index] += i;
+ unsigned int lookup_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (lookup_indices);
+ hb_ot_layout_feature_get_lookup_indexes (face,
+ table_tags[table_index],
+ feature_index,
+ offset, &len,
+ lookup_indices);
+
+ for (unsigned int i = 0; i < len; i++) {
+ lookup_map_t *lookup = lookup_maps[table_index].push ();
+ if (unlikely (!lookup))
+ return;
+ lookup->mask = mask;
+ lookup->index = lookup_indices[i];
+ }
- while (i--) {
- lookups[i].mask = mask;
- lookups[i].index = lookup_indices[i];
- }
+ offset += len;
+ } while (len == ARRAY_LENGTH (lookup_indices));
}
const hb_segment_properties_t *props)
{
global_mask = 1;
- lookup_count[0] = lookup_count[1] = 0;
if (!feature_infos.len)
return;
add_lookups (face, table_index, feature_maps[i].index[table_index], feature_maps[i].mask);
/* Sort lookups and merge duplicates */
- qsort (lookup_maps[table_index], lookup_count[table_index], sizeof (lookup_maps[table_index][0]), (hb_compare_func_t) lookup_map_t::cmp);
- if (lookup_count[table_index])
+ lookup_maps[table_index].sort ();
+ if (lookup_maps[table_index].len)
{
unsigned int j = 0;
- for (unsigned int i = 1; i < lookup_count[table_index]; i++)
+ for (unsigned int i = 1; i < lookup_maps[table_index].len; i++)
if (lookup_maps[table_index][i].index != lookup_maps[table_index][j].index)
lookup_maps[table_index][++j] = lookup_maps[table_index][i];
else
lookup_maps[table_index][j].mask |= lookup_maps[table_index][i].mask;
- j++;
- lookup_count[table_index] = j;
+ lookup_maps[table_index].shrink (j + 1);
}
}
}