Switch to shape_plan

Not optimized yet.  Eats babies.  And no shaper uses the shape_plan.
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 372543b..db21e88 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -48,7 +48,9 @@
   return data != NULL && !HB_SHAPER_DATA_IS_INVALID (data); \
 }
 
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face)
+#define HB_SHAPER_IMPLEMENT(shaper) \
+	HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \
+	HB_SHAPER_DATA_ENSURE_DECLARE(shaper, font)
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
 
@@ -65,7 +67,6 @@
 #define HB_SHAPER_PLAN(shaper) \
 	HB_STMT_START { \
 	  if (hb_##shaper##_face_data_ensure (shape_plan->face)) { \
-	    /* TODO Ensure face shaper data. */ \
 	    HB_SHAPER_DATA_TYPE (shaper, shape_plan) *data= \
 	      HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
 	    if (data) { \
@@ -157,3 +158,35 @@
 
   free (shape_plan);
 }
+
+
+hb_bool_t
+hb_shape_plan_execute (hb_shape_plan      *shape_plan,
+		       hb_font_t          *font,
+		       hb_buffer_t        *buffer,
+		       const hb_feature_t *features,
+		       unsigned int        num_features)
+{
+  if (unlikely (shape_plan->face != font->face))
+    return false;
+
+#define HB_SHAPER_EXECUTE(shaper) \
+	HB_STMT_START { \
+	  if (hb_##shaper##_font_data_ensure (font) && \
+	      _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features)) \
+	    return true; \
+	} HB_STMT_END
+
+  for (hb_shape_func_t **shaper_func = shape_plan->shapers; *shaper_func; shaper_func++)
+    if (0)
+      ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+    else if (*shaper_func == _hb_##shaper##_shape) \
+      HB_SHAPER_EXECUTE (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+#undef HB_SHAPER_EXECUTE
+
+  return false;
+}
diff --git a/src/hb-shape-plan.h b/src/hb-shape-plan.h
index 5160b95..a4786a8 100644
--- a/src/hb-shape-plan.h
+++ b/src/hb-shape-plan.h
@@ -57,4 +57,12 @@
 hb_shape_plan_destroy (hb_shape_plan_t *shape_plan);
 
 
+HB_INTERNAL hb_bool_t
+hb_shape_plan_execute (hb_shape_plan      *shape_plan,
+		       hb_font_t          *font,
+		       hb_buffer_t        *buffer,
+		       const hb_feature_t *features,
+		       unsigned int        num_features);
+
+
 #endif /* HB_SHAPE_PLAN_H */
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index d017425..0087618 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -32,7 +32,6 @@
 #include "hb-font-private.hh"
 
 
-
 static const char **static_shaper_list;
 
 static
@@ -83,28 +82,10 @@
 	       unsigned int        num_features,
 	       const char * const *shaper_list)
 {
-//  hb_shape_plan_t *shape_plan = hb_shape_plan_create (font->face, &buffer->props, features, num_features, shaper_list);
-
-  const hb_shaper_pair_t *shapers = _hb_shapers_get ();
-
-  hb_font_make_immutable (font); /* So we can safely cache stuff on it */
-
-  if (likely (!shaper_list)) {
-    for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
-      if (likely (shapers[i].func (NULL, font, buffer, features, num_features)))
-        return true;
-  } else {
-    while (*shaper_list) {
-      for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
-	if (0 == strcmp (*shaper_list, shapers[i].name)) {
-	  if (likely (shapers[i].func (NULL, font, buffer, features, num_features)))
-	    return true;
-	  break;
-	}
-      shaper_list++;
-    }
-  }
-  return false;
+  hb_shape_plan_t *shape_plan = hb_shape_plan_create (font->face, &buffer->props, features, num_features, shaper_list);
+  hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
+  hb_shape_plan_destroy (shape_plan);
+  return res;
 }
 
 void