[hb-ot-font] Make 'glyf' table loading lazy

Apparently some clients have reference-table callbacks that copy the table.
As such, avoid loading 'glyf' table which is only needed if fallback positioning
happens.
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 23ac41a..8b62bb1 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -300,13 +300,54 @@
   }
 };
 
+template <typename T>
+struct hb_lazy_loader_t
+{
+  inline void init (hb_face_t *face_)
+  {
+    face = face_;
+    instance = NULL;
+  }
+
+  inline void fini (void)
+  {
+    if (instance && instance != &OT::Null(T))
+    {
+      instance->fini();
+      free (instance);
+    }
+  }
+
+  inline const T* operator-> (void) const
+  {
+  retry:
+    T *p = (T *) hb_atomic_ptr_get (&instance);
+    if (unlikely (!p))
+    {
+      p = (T *) calloc (1, sizeof (T));
+      if (unlikely (!p))
+        return &OT::Null(T);
+      p->init (face);
+      if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), NULL, p)))
+      {
+	p->fini ();
+	goto retry;
+      }
+    }
+    return p;
+  }
+
+  private:
+  hb_face_t *face;
+  T *instance;
+};
 
 struct hb_ot_font_t
 {
   hb_ot_face_cmap_accelerator_t cmap;
   hb_ot_face_metrics_accelerator_t h_metrics;
   hb_ot_face_metrics_accelerator_t v_metrics;
-  hb_ot_face_glyf_accelerator_t glyf;
+  hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf;
 };
 
 
@@ -390,7 +431,7 @@
 			 void *user_data HB_UNUSED)
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
-  bool ret = ot_font->glyf.get_extents (glyph, extents);
+  bool ret = ot_font->glyf->get_extents (glyph, extents);
   extents->x_bearing = font->em_scale_x (extents->x_bearing);
   extents->y_bearing = font->em_scale_y (extents->y_bearing);
   extents->width     = font->em_scale_x (extents->width);
diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am
index 6320b02..b3b6300 100644
--- a/test/shaping/Makefile.am
+++ b/test/shaping/Makefile.am
@@ -47,6 +47,7 @@
 	tests/context-matching.tests \
 	tests/cursive-positioning.tests \
 	tests/default-ignorables.tests \
+	tests/fallback-positioning.test \
 	tests/fuzzed.tests \
 	tests/hangul-jamo.tests \
 	tests/hyphens.tests \
diff --git a/test/shaping/fonts/sha1sum/7ef276fc886ea502a03b9b0e5c8b547d5dc2b61c.ttf b/test/shaping/fonts/sha1sum/7ef276fc886ea502a03b9b0e5c8b547d5dc2b61c.ttf
new file mode 100644
index 0000000..fb4534a
--- /dev/null
+++ b/test/shaping/fonts/sha1sum/7ef276fc886ea502a03b9b0e5c8b547d5dc2b61c.ttf
Binary files differ
diff --git a/test/shaping/tests/fallback-positioning.test b/test/shaping/tests/fallback-positioning.test
new file mode 100644
index 0000000..499db7d
--- /dev/null
+++ b/test/shaping/tests/fallback-positioning.test
@@ -0,0 +1,2 @@
+fonts/sha1sum/7ef276fc886ea502a03b9b0e5c8b547d5dc2b61c.ttf:--font-funcs=ft:U+0078,U+0301,U+0058,U+0301:[x=0+1030|acutecomb=0@-45,-32+0|X=2+1295|acutecomb=2@-171,310+0]
+fonts/sha1sum/7ef276fc886ea502a03b9b0e5c8b547d5dc2b61c.ttf:--font-funcs=ot:U+0078,U+0301,U+0058,U+0301:[gid2=0+1030|gid4=0@-21,-27+0|gid1=2+1295|gid4=2@-147,321+0]