[layout] move alternate buffer iteration logic to AlternateSet
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index b7f5f64..6883308 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -522,8 +522,6 @@
 
 struct AlternateSet
 {
-  friend struct AlternateSubstFormat1;
-
   bool intersects (const hb_set_t *glyphs) const
   { return hb_any (alternates, glyphs); }
 
@@ -558,6 +556,20 @@
     return_trace (true);
   }
 
+  unsigned
+  get_alternates (unsigned        start_offset,
+		  unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
+		  hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
+  {
+    if (alternate_count)
+    {
+      + alternates.sub_array (start_offset, alternate_count)
+      | hb_sink (hb_array (alternate_glyphs, *alternate_count))
+      ;
+    }
+    return alternates.len;
+  }
+
   template <typename Iterator,
 	    hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c,
@@ -630,13 +642,15 @@
   bool would_apply (hb_would_apply_context_t *c) const
   { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
-  const ArrayOf<HBGlyphID> &get_alternates (hb_codepoint_t gid) const
-  {
-    unsigned index = (this+coverage).get_coverage (gid);
-    if (index == NOT_COVERED) return Null (ArrayOf<HBGlyphID>);
+  unsigned get_coverage_index (hb_codepoint_t gid) const
+  { return (this+coverage).get_coverage (gid); }
 
-    return (this+alternateSet[index]).alternates;
-  }
+  unsigned
+  get_alternates (unsigned        index,
+		  unsigned        start_offset,
+		  unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
+		  hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
+  { return (this+alternateSet[index]).get_alternates (start_offset, alternate_count, alternate_glyphs); }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -725,11 +739,24 @@
     }
   }
 
-  const ArrayOf<HBGlyphID> &get_alternates (hb_codepoint_t gid) const
+  unsigned
+  get_coverage_index (hb_codepoint_t gid) const
   {
     switch (u.format) {
-    case 1: return u.format1.get_alternates (gid);
-    default:return Null (ArrayOf<HBGlyphID>);
+    case 1: return u.format1.get_coverage_index (gid);
+    default:return NOT_COVERED;
+    }
+  }
+
+  unsigned
+  get_alternates (unsigned        index,
+		  unsigned        start_offset,
+		  unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
+		  hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.get_alternates (index, start_offset, alternate_count, alternate_glyphs);
+    default:assert (0); return 0;
     }
   }
 
@@ -1481,16 +1508,25 @@
 			     substitute_glyphs_list));
   }
 
-  const ArrayOf<HBGlyphID> &get_alternates (hb_codepoint_t gid) const
+  unsigned
+  get_alternates (hb_codepoint_t  gid,
+		  unsigned        start_offset,
+		  unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
+		  hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
   {
-    if (get_type () != SubTable::Alternate) return Null (ArrayOf<HBGlyphID>);
-    unsigned size = get_subtable_count ();
-    for (unsigned i = 0; i < size; ++i)
+    if (get_type () == SubTable::Alternate)
     {
-      const ArrayOf<HBGlyphID> &alternates = get_subtable (i).u.alternate.get_alternates (gid);
-      if (alternates.len) return alternates;
+      unsigned size = get_subtable_count ();
+      for (unsigned i = 0; i < size; ++i)
+      {
+	const AlternateSubst &alternate_subtable = get_subtable (i).u.alternate;
+	unsigned index = alternate_subtable.get_coverage_index (gid);
+	if (index != NOT_COVERED)
+	  return alternate_subtable.get_alternates (index, start_offset, alternate_count, alternate_glyphs);
+      }
     }
-    return Null (ArrayOf<HBGlyphID>);
+    if (alternate_count) *alternate_count = 0;
+    return 0;
   }
 
   bool serialize_alternate (hb_serialize_context_t *c,
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 972d716..c58b667 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -1992,18 +1992,11 @@
 				    unsigned        lookup_index,
 				    hb_codepoint_t  glyph,
 				    unsigned        start_offset,
-				    unsigned       *alternate_count /* IN/OUT */,
-				    hb_codepoint_t *alternate_glyphs)
+				    unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
+				    hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */)
 {
   const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index);
-  const OT::ArrayOf<OT::HBGlyphID> &alternates = lookup.get_alternates (glyph);
-  if (alternate_count)
-  {
-    + alternates.sub_array (start_offset, alternate_count)
-    | hb_sink (hb_array (alternate_glyphs, *alternate_count))
-    ;
-  }
-  return alternates.len;
+  return lookup.get_alternates (glyph, start_offset, alternate_count, alternate_glyphs);
 }
 
 #endif