[ot-map] Speed up feature finding

New API:
- hb_ot_layout_collect_feature_map()
pull/4352/head
Behdad Esfahbod 2 years ago
parent ebdfa9838b
commit dc35a0fbcb
  1. 1
      docs/harfbuzz-sections.txt
  2. 39
      src/hb-ot-layout.cc
  3. 7
      src/hb-ot-layout.h
  4. 22
      src/hb-ot-map.cc

@ -619,6 +619,7 @@ hb_ot_tags_from_script_and_language
hb_ot_tags_to_script_and_language
hb_ot_layout_collect_lookups
hb_ot_layout_collect_features
hb_ot_layout_collect_features_map
hb_ot_layout_feature_get_characters
hb_ot_layout_feature_get_lookups
hb_ot_layout_feature_get_name_ids

@ -1241,7 +1241,7 @@ script_collect_features (hb_collect_features_context_t *c,
* terminated by %HB_TAG_NONE
* @features: (nullable) (array zero-terminated=1): The array of features to collect,
* terminated by %HB_TAG_NONE
* @feature_indexes: (out): The array of feature indexes found for the query
* @feature_indexes: (out): The set of feature indexes found for the query
*
* Fetches a list of all feature indexes in the specified face's GSUB table
* or GPOS table, underneath the specified scripts, languages, and features.
@ -1282,6 +1282,43 @@ hb_ot_layout_collect_features (hb_face_t *face,
}
}
/**
* hb_ot_layout_collect_features_map:
* @face: #hb_face_t to work upon
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_index: The index of the requested script tag
* @language_index: The index of the requested language tag
* @feature_map: (out): The map of feature tag to feature index.
*
* Fetches the mapping from feature tags to feature indexes for
* the specified script and language.
*
* XSince: REPLACEME
**/
void
hb_ot_layout_collect_features_map (hb_face_t *face,
hb_tag_t table_tag,
unsigned script_index,
unsigned language_index,
hb_map_t *feature_map /* OUT */)
{
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
unsigned int count = l.get_feature_indexes (0, nullptr, nullptr);
for (unsigned int i = 0; i < count; i++)
{
unsigned feature_index = 0;
unsigned feature_count = 1;
l.get_feature_indexes (i, &feature_count, &feature_index);
if (!feature_count)
break;
hb_tag_t feature_tag = g.get_feature_tag (feature_index);
feature_map->set (feature_tag, feature_index);
}
}
/**
* hb_ot_layout_collect_lookups:

@ -324,6 +324,13 @@ hb_ot_layout_collect_features (hb_face_t *face,
const hb_tag_t *features,
hb_set_t *feature_indexes /* OUT */);
HB_EXTERN void
hb_ot_layout_collect_features_map (hb_face_t *face,
hb_tag_t table_tag,
unsigned script_index,
unsigned language_index,
hb_map_t *feature_map /* OUT */);
HB_EXTERN void
hb_ot_layout_collect_lookups (hb_face_t *face,
hb_tag_t table_tag,

@ -239,6 +239,13 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
feature_infos.shrink (j + 1);
}
hb_map_t feature_indices[2];
for (unsigned int table_index = 0; table_index < 2; table_index++)
hb_ot_layout_collect_features_map (face,
table_tags[table_index],
script_index[table_index],
language_index[table_index],
&feature_indices[table_index]);
/* Allocate bits now */
static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
@ -261,7 +268,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
if (!info->max_value || next_bit + bits_needed >= global_bit_shift)
continue; /* Feature disabled, or not enough bits. */
bool found = false;
unsigned int feature_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++)
@ -269,12 +275,14 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
if (required_feature_tag[table_index] == info->tag)
required_feature_stage[table_index] = info->stage[table_index];
found |= (bool) hb_ot_layout_language_find_feature (face,
table_tags[table_index],
script_index[table_index],
language_index[table_index],
info->tag,
&feature_index[table_index]);
hb_codepoint_t *index;
if (feature_indices[table_index].has (info->tag, &index))
{
feature_index[table_index] = *index;
found = true;
}
else
feature_index[table_index] = HB_OT_LAYOUT_NO_FEATURE_INDEX;
}
if (!found && (info->flags & F_GLOBAL_SEARCH))
{

Loading…
Cancel
Save