[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
src
test/subset
data
Makefile.amMakefile.sources
meson.buildexpected/layout.unsorted_featurelist
NotoIKEAHebrewLatin-Regular.default.392,3a7,3b2,3c7.ttfNotoIKEAHebrewLatin-Regular.default.retain-all-codepoint.ttfNotoIKEAHebrewLatin-Regular.layout-test.392,3a7,3b2,3c7.ttfNotoIKEAHebrewLatin-Regular.layout-test.retain-all-codepoint.ttfNotoIKEAHebrewLatin-Regular.retain-gids.392,3a7,3b2,3c7.ttfNotoIKEAHebrewLatin-Regular.retain-gids.retain-all-codepoint.ttf
fonts
tests
|
@ -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,24 +1013,15 @@ struct hb_collect_features_context_t
|
|||
}
|
||||
|
||||
has_feature_filter = true;
|
||||
hb_set_t features_set;
|
||||
for (; *features; features++)
|
||||
features_set.add (*features);
|
||||
|
||||
for (unsigned i = 0; i < g.get_feature_count (); i++)
|
||||
{
|
||||
hb_tag_t tag = *features;
|
||||
unsigned index;
|
||||
g.find_feature_index (tag, &index);
|
||||
if (index == OT::Index::NOT_FOUND_INDEX) continue;
|
||||
|
||||
feature_indices_filter.add(index);
|
||||
for (int i = (int) index - 1; i >= 0; 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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