[subset] Don't assume FeatureList is sorted
Though the spec said FeatureRecords are sorted alphabetically by feature tag, there're font files with unsorted FeatureList. And harfbuzz is not able to subset these files correctly because we use binary search in finding featureRecords when collecting lookups. Also find_duplicate_features needs to be updated to handle this.
This commit is contained in:
parent
49c9392412
commit
364b6b3989
|
@ -3658,24 +3658,33 @@ struct GSUBGPOS
|
|||
const hb_set_t *feature_indices,
|
||||
hb_map_t *duplicate_feature_map /* OUT */) const
|
||||
{
|
||||
hb_set_t unique_features;
|
||||
hb_tag_t prev_t = get_feature_tag (feature_indices->get_min ());
|
||||
if (feature_indices->is_empty ()) return;
|
||||
hb_hashmap_t<hb_tag_t, hb_set_t *, (unsigned)-1, nullptr> unique_features;
|
||||
//find out duplicate features after subset
|
||||
for (unsigned i : feature_indices->iter ())
|
||||
{
|
||||
hb_tag_t t = get_feature_tag (i);
|
||||
if (t != prev_t)
|
||||
if (!unique_features.has (t))
|
||||
{
|
||||
prev_t = t;
|
||||
unique_features.clear ();
|
||||
unique_features.add (i);
|
||||
hb_set_t* indices = hb_set_create ();
|
||||
if (unlikely (indices == hb_set_get_empty () ||
|
||||
!unique_features.set (t, indices)))
|
||||
{
|
||||
hb_set_destroy (indices);
|
||||
for (auto _ : unique_features.iter ())
|
||||
hb_set_destroy (_.second);
|
||||
return;
|
||||
}
|
||||
if (unique_features.get (t))
|
||||
unique_features.get (t)->add (i);
|
||||
duplicate_feature_map->set (i, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
for (unsigned other_f_index : unique_features.iter ())
|
||||
hb_set_t* same_tag_features = unique_features.get (t);
|
||||
for (unsigned other_f_index : same_tag_features->iter ())
|
||||
{
|
||||
const Feature& f = get_feature (i);
|
||||
const Feature& other_f = get_feature (other_f_index);
|
||||
|
@ -3707,10 +3716,13 @@ struct GSUBGPOS
|
|||
|
||||
if (found == false)
|
||||
{
|
||||
unique_features.add (i);
|
||||
same_tag_features->add (i);
|
||||
duplicate_feature_map->set (i, i);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto _ : unique_features.iter ())
|
||||
hb_set_destroy (_.second);
|
||||
}
|
||||
|
||||
void prune_features (const hb_map_t *lookup_indices, /* IN */
|
||||
|
|
|
@ -1013,25 +1013,16 @@ struct hb_collect_features_context_t
|
|||
}
|
||||
|
||||
has_feature_filter = true;
|
||||
hb_set_t features_set;
|
||||
for (; *features; features++)
|
||||
{
|
||||
hb_tag_t tag = *features;
|
||||
unsigned index;
|
||||
g.find_feature_index (tag, &index);
|
||||
if (index == OT::Index::NOT_FOUND_INDEX) continue;
|
||||
features_set.add (*features);
|
||||
|
||||
feature_indices_filter.add(index);
|
||||
for (int i = (int) index - 1; i >= 0; i--)
|
||||
for (unsigned i = 0; i < g.get_feature_count (); i++)
|
||||
{
|
||||
if (g.get_feature_tag (i) != tag) break;
|
||||
hb_tag_t tag = g.get_feature_tag (i);
|
||||
if (features_set.has (tag))
|
||||
feature_indices_filter.add(i);
|
||||
}
|
||||
for (unsigned i = index + 1; i < g.get_feature_count (); i++)
|
||||
{
|
||||
if (g.get_feature_tag (i) != tag) break;
|
||||
feature_indices_filter.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool visited (const OT::Script &s)
|
||||
|
|
|
@ -36,6 +36,7 @@ EXTRA_DIST += \
|
|||
expected/layout.notonastaliqurdu \
|
||||
expected/layout.tinos \
|
||||
expected/layout.duplicate_features \
|
||||
expected/layout.unsorted_featurelist \
|
||||
expected/cmap \
|
||||
expected/cmap14 \
|
||||
expected/sbix \
|
||||
|
|
|
@ -34,6 +34,7 @@ TESTS = \
|
|||
tests/layout.tests \
|
||||
tests/layout.tinos.tests \
|
||||
tests/layout.duplicate_features.tests \
|
||||
tests/layout.unsorted_featurelist.tests \
|
||||
tests/sbix.tests \
|
||||
tests/variable.tests \
|
||||
tests/glyph_names.tests \
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,11 @@
|
|||
FONTS:
|
||||
NotoIKEAHebrewLatin-Regular.ttf
|
||||
|
||||
PROFILES:
|
||||
layout-test.txt
|
||||
default.txt
|
||||
retain-gids.txt
|
||||
|
||||
SUBSETS:
|
||||
U+392,U+3a7,U+3b2,U+3c7
|
||||
*
|
|
@ -28,6 +28,7 @@ tests = [
|
|||
'layout.notonastaliqurdu',
|
||||
'layout.tinos',
|
||||
'layout.duplicate_features',
|
||||
'layout.unsorted_featurelist',
|
||||
'cmap',
|
||||
'cmap14',
|
||||
'sbix',
|
||||
|
|
Loading…
Reference in New Issue