[subset] fix for collect_features and remove_redundant_lamngsys

previously remove_redundant_sys () is missing in harfbuzz, after
redundant langsys removal, some features are removed as well in
prune_features() in fonttools. This change is trying to get the same
result between harfbuzz and fonttools.
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index ec47e9a..5b758a8 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -94,6 +94,60 @@
                                           bool use_class_zero,
 					  hb_map_t *klass_map /*INOUT*/);
 
+
+struct hb_prune_langsys_context_t
+{
+  hb_prune_langsys_context_t (const void         *table_,
+                              hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_,
+                              const hb_map_t     *duplicate_feature_map_,
+                              hb_set_t           *new_collected_feature_indexes_)
+      :table (table_),
+      script_langsys_map (script_langsys_map_),
+      duplicate_feature_map (duplicate_feature_map_),
+      new_feature_indexes (new_collected_feature_indexes_),
+      script_count (0),langsys_count (0) {}
+
+  bool visitedScript (const void *s)
+  {
+    if (script_count++ > HB_MAX_SCRIPTS)
+      return true;
+
+    return visited (s, visited_script);
+  }
+
+  bool visitedLangsys (const void *l)
+  {
+    if (langsys_count++ > HB_MAX_LANGSYS)
+      return true;
+
+    return visited (l, visited_langsys);
+  }
+
+  private:
+  template <typename T>
+  bool visited (const T *p, hb_set_t &visited_set)
+  {
+    hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) p - (uintptr_t) table);
+     if (visited_set.has (delta))
+      return true;
+
+    visited_set.add (delta);
+    return false;
+  }
+
+  public:
+  const void *table;
+  hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map;
+  const hb_map_t     *duplicate_feature_map;
+  hb_set_t           *new_feature_indexes;
+
+  private:
+  hb_set_t visited_script;
+  hb_set_t visited_langsys;
+  unsigned script_count;
+  unsigned langsys_count;
+};
+
 struct hb_subset_layout_context_t :
   hb_dispatch_context_t<hb_subset_layout_context_t, hb_empty_t, HB_DEBUG_SUBSET>
 {
@@ -125,16 +179,21 @@
   hb_subset_context_t *subset_context;
   const hb_tag_t table_tag;
   const hb_map_t *lookup_index_map;
+  const hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map;
   const hb_map_t *feature_index_map;
+  unsigned cur_script_index;
 
   hb_subset_layout_context_t (hb_subset_context_t *c_,
 			      hb_tag_t tag_,
 			      hb_map_t *lookup_map_,
-			      hb_map_t *feature_map_) :
+			      hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_,
+			      hb_map_t *feature_index_map_) :
 				subset_context (c_),
 				table_tag (tag_),
 				lookup_index_map (lookup_map_),
-				feature_index_map (feature_map_),
+				script_langsys_map (script_langsys_map_),
+				feature_index_map (feature_index_map_),
+				cur_script_index (0xFFFFu),
 				script_count (0),
 				langsys_count (0),
 				feature_index_count (0),
@@ -407,6 +466,30 @@
   }
 };
 
+struct Script;
+struct RecordListOfScript : RecordListOf<Script>
+{
+  bool subset (hb_subset_context_t *c,
+               hb_subset_layout_context_t *l) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+
+    unsigned count = this->len;
+    for (auto _ : + hb_zip (*this, hb_range (count)))
+    {
+      auto snap = c->serializer->snapshot ();
+      l->cur_script_index = _.second;
+      bool ret = _.first.subset (l, this);
+      if (!ret) c->serializer->revert (snap);
+      else out->len++;
+    }
+    
+    return_trace (true);
+  }
+};
+
 struct RangeRecord
 {
   int cmp (hb_codepoint_t g) const
@@ -506,18 +589,46 @@
     return_trace (c->embed (*this));
   }
 
-  bool operator == (const LangSys& o) const
+  bool compare (const LangSys& o, const hb_map_t *feature_index_map) const
   {
-    if (featureIndex.len != o.featureIndex.len ||
-	reqFeatureIndex != o.reqFeatureIndex)
+    if (reqFeatureIndex != o.reqFeatureIndex)
       return false;
 
-    for (const auto _ : + hb_zip (featureIndex, o.featureIndex))
+    auto iter =
+    + hb_iter (featureIndex)
+    | hb_filter (feature_index_map)
+    | hb_map (feature_index_map)
+    ;
+
+    auto o_iter =
+    + hb_iter (o.featureIndex)
+    | hb_filter (feature_index_map)
+    | hb_map (feature_index_map)
+    ;
+
+    if (iter.len () != o_iter.len ())
+      return false;
+
+    for (const auto _ : + hb_zip (iter, o_iter))
       if (_.first != _.second) return false;
 
     return true;
   }
 
+  void collect_features (hb_prune_langsys_context_t *c) const
+  {
+    if (!has_required_feature () && !get_feature_count ()) return;
+    if (c->visitedLangsys (this)) return;
+    if (has_required_feature () &&
+        c->duplicate_feature_map->has (reqFeatureIndex))
+      c->new_feature_indexes->add (get_required_feature_index ());
+
+    + hb_iter (featureIndex)
+    | hb_filter (c->duplicate_feature_map)
+    | hb_sink (c->new_feature_indexes)
+    ;
+  }
+
   bool subset (hb_subset_context_t        *c,
 	       hb_subset_layout_context_t *l,
 	       const Tag                  *tag = nullptr) const
@@ -581,6 +692,42 @@
   bool has_default_lang_sys () const           { return defaultLangSys != 0; }
   const LangSys& get_default_lang_sys () const { return this+defaultLangSys; }
 
+  void prune_langsys (hb_prune_langsys_context_t *c,
+                      unsigned script_index) const
+  {
+    if (!has_default_lang_sys () && !get_lang_sys_count ()) return;
+    if (c->visitedScript (this)) return;
+
+    if (!c->script_langsys_map->has (script_index))
+      c->script_langsys_map->set (script_index, hb_set_create ());
+    
+    unsigned langsys_count = get_lang_sys_count ();
+    if (has_default_lang_sys ())
+    {
+      //only collect features from non-redundant langsys
+      const LangSys& d = get_default_lang_sys ();
+      d.collect_features (c);
+
+      for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
+      {
+        const LangSys& l = this+_.first.offset;
+        if (l.compare (d, c->duplicate_feature_map)) continue;
+
+        l.collect_features (c);
+        c->script_langsys_map->get (script_index)->add (_.second);
+      }
+    }
+    else
+    {
+      for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
+      {
+        const LangSys& l = this+_.first.offset;
+        l.collect_features (c);
+        c->script_langsys_map->get (script_index)->add (_.second);
+      }
+    }
+  }
+
   bool subset (hb_subset_context_t         *c,
 	       hb_subset_layout_context_t  *l,
 	       const Tag                   *tag) const
@@ -609,16 +756,17 @@
       }
     }
 
-    + langSys.iter ()
-    | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); })
-    | hb_filter ([&] (const Record<LangSys>& record)
-		 {
-		   const LangSys& d = this+defaultLangSys;
-		   const LangSys& l = this+record.offset;
-		   return !(l == d);
-		 })
-    | hb_apply (subset_record_array (l, &(out->langSys), this))
-    ;
+    const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index);
+    if (active_langsys)
+    {
+      unsigned count = langSys.len;
+      + hb_zip (langSys, hb_range (count))
+      | hb_filter (active_langsys, hb_second)
+      | hb_map (hb_first)
+      | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); })
+      | hb_apply (subset_record_array (l, &(out->langSys), this))
+      ;
+    }
 
     return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB);
   }
@@ -641,7 +789,7 @@
   DEFINE_SIZE_ARRAY_SIZED (4, langSys);
 };
 
-typedef RecordListOf<Script> ScriptList;
+typedef RecordListOfScript ScriptList;
 
 
 /* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 85ff4bc..72a44bf 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -2666,7 +2666,7 @@
 
   bool subset (hb_subset_context_t *c) const
   {
-    hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_features);
+    hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features);
     return GSUBGPOS::subset<PosLookup> (&l);
   }
 
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 5d20a7e..ee95bbc 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1596,7 +1596,7 @@
 
   bool subset (hb_subset_context_t *c) const
   {
-    hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_features);
+    hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_langsys, c->plan->gsub_features);
     return GSUBGPOS::subset<SubstLookup> (&l);
   }
 
diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh
index 887a759..6fdf190 100644
--- a/src/hb-ot-layout-gsubgpos.hh
+++ b/src/hb-ot-layout-gsubgpos.hh
@@ -52,7 +52,7 @@
   const hb_set_t *glyphs;
 
   hb_intersects_context_t (const hb_set_t *glyphs_) :
-			     glyphs (glyphs_) {}
+                            glyphs (glyphs_) {}
 };
 
 struct hb_have_non_1to1_context_t :
@@ -3587,6 +3587,20 @@
     hb_set_subtract (lookup_indexes, &inactive_lookups);
   }
 
+  void prune_langsys (const hb_map_t *duplicate_feature_map,
+                      hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map,
+                      hb_set_t       *new_feature_indexes /* OUT */) const
+  {
+    hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes);
+    
+    unsigned count = get_script_count ();
+    for (unsigned script_index = 0; script_index < count; script_index++)
+    {
+      const Script& s = get_script (script_index);
+      s.prune_langsys (&c, script_index);
+    }
+  }
+
   template <typename TLookup>
   bool subset (hb_subset_layout_context_t *c) const
   {
@@ -3627,8 +3641,65 @@
     return_trace (true);
   }
 
+  void find_duplicate_features (const hb_map_t *lookup_indices,
+                                const hb_set_t *feature_indices,
+                                hb_map_t *duplicate_feature_map /* OUT */) const
+  {
+    //find out duplicate features after subset
+    unsigned prev = 0xFFFFu;
+    for (unsigned i : feature_indices->iter ())
+    {
+      if (prev == 0xFFFFu)
+      {
+        duplicate_feature_map->set (i, i);
+        prev = i;
+        continue;
+      }
+
+      hb_tag_t t = get_feature_tag (i);
+      hb_tag_t prev_t = get_feature_tag (prev);
+      if (t != prev_t)
+      {
+        duplicate_feature_map->set (i, i);
+        prev = i;
+        continue;
+      }
+
+      const Feature& f = get_feature (i);
+      const Feature& prev_f = get_feature (prev);
+
+      auto f_iter =
+      + hb_iter (f.lookupIndex)
+      | hb_filter (lookup_indices)
+      ;
+
+      auto prev_iter =
+      + hb_iter (prev_f.lookupIndex)
+      | hb_filter (lookup_indices)
+      ;
+
+      if (f_iter.len () != prev_iter.len ())
+      {
+        duplicate_feature_map->set (i, i);
+        prev = i;
+        continue;
+      }
+
+      bool is_equal = true;
+      for (auto _ : + hb_zip (f_iter, prev_iter))
+        if (_.first != _.second) { is_equal = false; break; }
+
+      if (is_equal == true) duplicate_feature_map->set (i, prev);
+      else
+      {
+        duplicate_feature_map->set (i, i);
+        prev = i;
+      }
+    }
+  }
+
   void prune_features (const hb_map_t *lookup_indices, /* IN */
-                       hb_set_t       *feature_indices /* IN/OUT */) const
+		       hb_set_t       *feature_indices /* IN/OUT */) const
   {
 #ifndef HB_NO_VAR
     // This is the set of feature indices which have alternate versions defined
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index d055783..e7e8053 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -39,6 +39,7 @@
 #include "hb-ot-stat-table.hh"
 
 
+typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map;
 #ifndef HB_NO_SUBSET_CFF
 static inline void
 _add_cff_seac_components (const OT::cff1::accelerator_t &cff,
@@ -70,7 +71,8 @@
 _gsub_closure_glyphs_lookups_features (hb_face_t *face,
 				       hb_set_t *gids_to_retain,
 				       hb_map_t *gsub_lookups,
-				       hb_map_t *gsub_features)
+				       hb_map_t *gsub_features,
+				       script_langsys_map *gsub_langsys)
 {
   hb_set_t lookup_indices;
   hb_ot_layout_collect_lookups (face,
@@ -96,7 +98,13 @@
                                  nullptr,
                                  nullptr,
                                  &feature_indices);
+
   gsub->prune_features (gsub_lookups, &feature_indices);
+  hb_map_t duplicate_feature_map;
+  gsub->find_duplicate_features (gsub_lookups, &feature_indices, &duplicate_feature_map);
+
+  feature_indices.clear ();
+  gsub->prune_langsys (&duplicate_feature_map, gsub_langsys, &feature_indices);
   _remap_indexes (&feature_indices, gsub_features);
 
   gsub.destroy ();
@@ -106,7 +114,8 @@
 _gpos_closure_lookups_features (hb_face_t      *face,
 				const hb_set_t *gids_to_retain,
 				hb_map_t       *gpos_lookups,
-				hb_map_t       *gpos_features)
+				hb_map_t       *gpos_features,
+				script_langsys_map *gpos_langsys)
 {
   hb_set_t lookup_indices;
   hb_ot_layout_collect_lookups (face,
@@ -129,8 +138,15 @@
                                  nullptr,
                                  nullptr,
                                  &feature_indices);
+
   gpos->prune_features (gpos_lookups, &feature_indices);
+  hb_map_t duplicate_feature_map;
+  gpos->find_duplicate_features (gpos_lookups, &feature_indices, &duplicate_feature_map);
+
+  feature_indices.clear ();
+  gpos->prune_langsys (&duplicate_feature_map, gpos_langsys, &feature_indices);
   _remap_indexes (&feature_indices, gpos_features);
+
   gpos.destroy ();
 }
 #endif
@@ -231,10 +247,10 @@
 #ifndef HB_NO_SUBSET_LAYOUT
   if (close_over_gsub)
     // closure all glyphs/lookups/features needed for GSUB substitutions.
-    _gsub_closure_glyphs_lookups_features (plan->source, plan->_glyphset_gsub, plan->gsub_lookups, plan->gsub_features);
+    _gsub_closure_glyphs_lookups_features (plan->source, plan->_glyphset_gsub, plan->gsub_lookups, plan->gsub_features, plan->gsub_langsys);
 
   if (close_over_gpos)
-    _gpos_closure_lookups_features (plan->source, plan->_glyphset_gsub, plan->gpos_lookups, plan->gpos_features);
+    _gpos_closure_lookups_features (plan->source, plan->_glyphset_gsub, plan->gpos_lookups, plan->gpos_features, plan->gpos_langsys);
 #endif
   _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
 
@@ -356,6 +372,12 @@
   plan->reverse_glyph_map = hb_map_create ();
   plan->gsub_lookups = hb_map_create ();
   plan->gpos_lookups = hb_map_create ();
+  
+  plan->gsub_langsys = hb_object_create<script_langsys_map> ();
+  plan->gsub_langsys->init_shallow ();
+
+  plan->gpos_langsys = hb_object_create<script_langsys_map> ();
+  plan->gpos_langsys->init_shallow ();
   plan->gsub_features = hb_map_create ();
   plan->gpos_features = hb_map_create ();
   plan->layout_variation_indices = hb_set_create ();
@@ -407,6 +429,19 @@
   hb_set_destroy (plan->layout_variation_indices);
   hb_map_destroy (plan->layout_variation_idx_map);
 
+  for (auto _ : plan->gsub_langsys->iter ())
+    hb_set_destroy (_.second);
+  
+  hb_object_destroy (plan->gsub_langsys);
+  plan->gsub_langsys->fini_shallow ();
+  free (plan->gsub_langsys);
+
+  for (auto _ : plan->gpos_langsys->iter ())
+    hb_set_destroy (_.second);
+  
+  hb_object_destroy (plan->gpos_langsys);
+  plan->gpos_langsys->fini_shallow ();
+  free (plan->gpos_langsys);
 
   free (plan);
 }
diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh
index cc9cb7a..1c070f9 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -79,7 +79,11 @@
   hb_map_t *gsub_lookups;
   hb_map_t *gpos_lookups;
 
-  //active features we'd like to retain
+  //active langsys we'd like to retain
+  hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gsub_langsys;
+  hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gpos_langsys;
+
+  //active features after removing redundant langsys and prune_features
   hb_map_t *gsub_features;
   hb_map_t *gpos_features;
 
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,623,62D,644,627,645,2E.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,623,62D,644,627,645,2E.ttf
index 7ae9c56..494dee0 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,623,62D,644,627,645,2E.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,623,62D,644,627,645,2E.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,62D,628.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,62D,628.ttf
index d298491..f4a1ce4 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,62D,628.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,62D,628.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644.ttf
index 1b90606..45f1177 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.633,645,627,621,20,644,627.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.633,645,627,621,20,644,627.ttf
index 969fda2..82976b0 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.633,645,627,621,20,644,627.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.633,645,627,621,20,644,627.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.63A,64A,631.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.63A,64A,631.ttf
index 54ef721..ebc2866 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.63A,64A,631.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.63A,64A,631.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,623,62D,644,627,645,2E.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,623,62D,644,627,645,2E.ttf
index 3a64b97..9862336 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,623,62D,644,627,645,2E.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,623,62D,644,627,645,2E.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,62D,628.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,62D,628.ttf
index a9c3d36..00f7803 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,62D,628.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,62D,628.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644.ttf
index a535889..c153715 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.633,645,627,621,20,644,627.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.633,645,627,621,20,644,627.ttf
index 0577408..0e5dd57 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.633,645,627,621,20,644,627.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.633,645,627,621,20,644,627.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.63A,64A,631.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.63A,64A,631.ttf
index 8e4c014..7d27cb6 100644
--- a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.63A,64A,631.ttf
+++ b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.63A,64A,631.ttf
Binary files differ
diff --git a/test/subset/data/fonts/Amiri-Regular.ttf b/test/subset/data/fonts/Amiri-Regular.ttf
index 47cb4e1..508a1bf 100644
--- a/test/subset/data/fonts/Amiri-Regular.ttf
+++ b/test/subset/data/fonts/Amiri-Regular.ttf
Binary files differ