Add hb_ot_shape_glyphs_closure()

Experimental API for now.
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index d5fc4ce..3811206 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -69,6 +69,10 @@
   inline void position (hb_font_t *font, hb_buffer_t *buffer) const
   { apply (1, (hb_ot_map_t::apply_lookup_func_t) hb_ot_layout_position_lookup, font, buffer); }
 
+  HB_INTERNAL void substitute_closure (hb_face_t *face,
+				       hb_set_t *glyphs) const;
+
+
   inline void finish (void) {
     features.finish ();
     lookups[0].finish ();
@@ -125,9 +129,6 @@
 			  void *face_or_font,
 			  hb_buffer_t *buffer) const;
 
-  HB_INTERNAL void substitute_closure (hb_face_t *face,
-				       hb_set_t *glyphs) const;
-
   hb_mask_t global_mask;
 
   hb_tag_t chosen_script[2];
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index b31cdc5..167b1d7 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -30,6 +30,7 @@
 #include "hb-ot-shape-normalize-private.hh"
 
 #include "hb-font-private.hh"
+#include "hb-set-private.hh"
 
 
 
@@ -478,3 +479,37 @@
 
   return TRUE;
 }
+
+
+void
+hb_ot_shape_glyphs_closure (hb_font_t          *font,
+			    hb_buffer_t        *buffer,
+			    const hb_feature_t *features,
+			    unsigned int        num_features,
+			    hb_set_t           *glyphs)
+{
+  hb_ot_shape_plan_t plan;
+
+  buffer->guess_properties ();
+
+  hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_features);
+
+  /* TODO: normalization? have shapers do closure()? */
+  /* TODO: Deal with mirrored chars? */
+  hb_map_glyphs (font, buffer);
+
+  /* Seed it.  It's user's responsibility to have cleard glyphs
+   * if that's what they desire. */
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    hb_set_add (glyphs, buffer->info[i].codepoint);
+
+  /* And find transitive closure. */
+  hb_set_t copy;
+  copy.init ();
+
+  do {
+    copy.set (glyphs);
+    plan.map.substitute_closure (font->face, glyphs);
+  } while (!copy.equal (glyphs));
+}
diff --git a/src/hb-ot.h b/src/hb-ot.h
index a4cb371..2d750c3 100644
--- a/src/hb-ot.h
+++ b/src/hb-ot.h
@@ -34,6 +34,14 @@
 #include "hb-ot-tag.h"
 
 HB_BEGIN_DECLS
+
+void
+hb_ot_shape_glyphs_closure (hb_font_t          *font,
+			    hb_buffer_t        *buffer,
+			    const hb_feature_t *features,
+			    unsigned int        num_features,
+			    hb_set_t           *glyphs);
+
 HB_END_DECLS
 
 #undef HB_OT_H_IN
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
index 660aaee..c7f4aa0 100644
--- a/src/hb-set-private.hh
+++ b/src/hb-set-private.hh
@@ -35,6 +35,9 @@
 
 struct _hb_set_t
 {
+  inline void init (void) {
+    clear ();
+  }
   inline void clear (void) {
     memset (elts, 0, sizeof elts);
   }