Skip to content

Commit

Permalink
[ot-map] Speed up feature finding
Browse files Browse the repository at this point in the history
New API:
- hb_ot_layout_collect_feature_map()
  • Loading branch information
behdad committed Jul 30, 2023
1 parent ebdfa98 commit dc35a0f
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 8 deletions.
1 change: 1 addition & 0 deletions docs/harfbuzz-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 38 additions & 1 deletion src/hb-ot-layout.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions src/hb-ot-layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
22 changes: 15 additions & 7 deletions src/hb-ot-map.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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))), "");
Expand All @@ -261,20 +268,21 @@ 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++)
{
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))
{
Expand Down

0 comments on commit dc35a0f

Please sign in to comment.