Allow HB_OPTIONS=aat to prefer AAT tables over OT

Fixes https://github.com/harfbuzz/harfbuzz/issues/322
diff --git a/src/hb-common.cc b/src/hb-common.cc
index 41b1601..f698a44 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -47,8 +47,27 @@
   u.i = 0;
   u.opts.initialized = 1;
 
-  char *c = getenv ("HB_OPTIONS");
-  u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
+  const char *c = getenv ("HB_OPTIONS");
+  if (c)
+  {
+    while (*c)
+    {
+      const char *p = strchr (c, ':');
+      if (!p)
+        p = c + strlen (c);
+
+#define OPTION(name, symbol) \
+	if (0 == strncmp (c, name, p - c)) u.opts.symbol = true;
+
+      OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
+      OPTION ("aat", aat);
+
+#undef OPTION
+
+      c = *p ? p + 1 : p;
+    }
+
+  }
 
   /* This is idempotent and threadsafe. */
   _hb_options.set_relaxed (u.i);
diff --git a/src/hb-debug.hh b/src/hb-debug.hh
index 12b6c49..58c190d 100644
--- a/src/hb-debug.hh
+++ b/src/hb-debug.hh
@@ -43,9 +43,10 @@
 
 struct hb_options_t
 {
-  unsigned int unused : 1; /* In-case sign bit is here. */
-  unsigned int initialized : 1;
-  unsigned int uniscribe_bug_compatible : 1;
+  bool unused : 1; /* In-case sign bit is here. */
+  bool initialized : 1;
+  bool uniscribe_bug_compatible : 1;
+  bool aat : 1;
 };
 
 union hb_options_union_t {
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index cf808c2..7a15d52 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -42,6 +42,17 @@
 #include "hb-aat-layout.hh"
 
 
+static bool
+_hb_apply_morx (hb_face_t *face)
+{
+  if (hb_options ().aat &&
+      hb_aat_layout_has_substitution (face))
+    return true;
+
+  return !hb_ot_layout_has_substitution (face) &&
+	 hb_aat_layout_has_substitution (face);
+}
+
 void
 hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
 				const int          *coords,
@@ -76,17 +87,15 @@
    * Decide who does substitutions. GSUB, morx, or fallback.
    */
 
-  if (!hb_ot_layout_has_substitution (face))
-  { /* No GSUB. */
-    if (hb_aat_layout_has_substitution (face))
-      plan.apply_morx = true;
-  }
+  plan.apply_morx = _hb_apply_morx (face);
 
   /*
    * Decide who does positioning. GPOS, kerx, kern, or fallback.
    */
 
-  if (!disable_gpos && hb_ot_layout_has_positioning (face))
+  if (hb_options ().aat && hb_aat_layout_has_positioning (face))
+    plan.apply_kerx = true;
+  else if (!disable_gpos && hb_ot_layout_has_positioning (face))
     plan.apply_gpos = true;
   else if (hb_aat_layout_has_positioning (face))
     plan.apply_kerx = true;
@@ -263,8 +272,7 @@
 
   /* Ugly that we have to do this here...
    * If we are going to apply morx, choose default shaper. */
-  if (!hb_ot_layout_has_substitution (planner.face) &&
-       hb_aat_layout_has_substitution (planner.face))
+  if (_hb_apply_morx (planner.face))
     planner.shaper = &_hb_ot_complex_shaper_default;
   else
     planner.shaper = hb_ot_shape_complex_categorize (&planner);