[HarfBuzz] harfbuzz: Branch 'master' - 7 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Thu Aug 2 08:30:21 UTC 2018


 src/dump-emoji.cc                          |    4 
 src/hb-aat-layout.cc                       |    2 
 src/hb-blob-private.hh                     |    5 -
 src/hb-coretext.cc                         |   46 ++++-----
 src/hb-directwrite.cc                      |   28 ++---
 src/hb-face.cc                             |   21 ++--
 src/hb-face.h                              |   16 +--
 src/hb-fallback-shape.cc                   |   24 ++---
 src/hb-graphite2.cc                        |   26 ++---
 src/hb-machinery-private.hh                |  137 ++++++++++++++---------------
 src/hb-ot-font.cc                          |   19 ++--
 src/hb-ot-layout-private.hh                |   11 +-
 src/hb-ot-layout.cc                        |   17 +--
 src/hb-ot-shape-complex-arabic-fallback.hh |   18 +--
 src/hb-ot-shape.cc                         |   20 ++--
 src/hb-shaper-private.hh                   |   10 +-
 src/hb-static.cc                           |    4 
 src/hb-subset-glyf.cc                      |    2 
 src/hb-subset.cc                           |    8 -
 src/hb-uniscribe.cc                        |   36 +++----
 20 files changed, 231 insertions(+), 223 deletions(-)

New commits:
commit ff7826e90bce46985651015059872d1d8559b6ce
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 2 01:27:40 2018 -0700

    Reduce storage by sharing face amongst lazy_loaders

diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh
index dbabeadd..081cbbfd 100644
--- a/src/hb-machinery-private.hh
+++ b/src/hb-machinery-private.hh
@@ -590,93 +590,106 @@ struct BEInt<Type, 4>
  * Lazy struct and blob loaders.
  */
 
-template <typename Subclass,
+template <unsigned int WheresFace,
+	  typename Subclass,
 	  typename Returned,
 	  typename Stored = Returned>
 struct hb_base_lazy_loader_t
 {
+  static_assert (WheresFace > 0, "");
+
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
   inline const Subclass* thiz (void) const { return static_cast<const Subclass *> (this); }
+  inline Subclass* thiz (void) { return static_cast<Subclass *> (this); }
 
-  inline void init (hb_face_t *face_)
+  inline void init (void)
   {
-    face = face_;
     instance = nullptr;
   }
-
-  inline const Returned * operator-> (void) const
+  inline void fini (void)
   {
-    return thiz ()->get ();
+    if (instance)
+      thiz ()->destroy (instance);
   }
 
-  protected:
-  hb_face_t *face;
-  mutable Stored *instance;
-};
-
-template <typename T>
-struct hb_lazy_loader_t : hb_base_lazy_loader_t<hb_lazy_loader_t<T>, T>
-{
-  inline void fini (void)
+  inline const Returned * operator-> (void) const
   {
-    if (this->instance && this->instance != &Null(T))
-    {
-      this->instance->fini();
-      free (this->instance);
-    }
+    return thiz ()->get ();
   }
 
-  inline const T* get (void) const
+  inline Stored * get_stored (void) const
   {
   retry:
-    T *p = (T *) hb_atomic_ptr_get (&this->instance);
+    Stored *p = (Stored *) hb_atomic_ptr_get (&this->instance);
     if (unlikely (!p))
     {
-      p = (T *) calloc (1, sizeof (T));
-      if (unlikely (!p))
-        p = const_cast<T *> (&Null(T));
-      else
-	p->init (this->face);
-      if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&this->instance), nullptr, p)))
+      hb_face_t *face = *(((hb_face_t **) this) - WheresFace);
+      p = thiz ()->create (face);
+      if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<Stored **>(&this->instance), nullptr, p)))
       {
-	if (p != &Null(T))
-	  p->fini ();
+        thiz ()->destroy (p);
 	goto retry;
       }
     }
     return p;
   }
+
+  inline const Returned * get (void) const
+  {
+    return thiz ()->convert (get_stored ());
+  }
+
+  static inline const Returned* convert (const Stored *p)
+  {
+    return p;
+  }
+
+  private:
+  /* Must only have one pointer. */
+  mutable Stored *instance;
 };
 
-template <typename T>
-struct hb_table_lazy_loader_t : hb_base_lazy_loader_t<hb_table_lazy_loader_t<T>, T, hb_blob_t>
+template <unsigned int WheresFace, typename T>
+struct hb_lazy_loader_t : hb_base_lazy_loader_t<WheresFace, hb_lazy_loader_t<WheresFace, T>, T>
 {
-  inline void fini (void)
+  static inline T *create (hb_face_t *face)
   {
-    hb_blob_destroy (this->instance);
+    T *p = (T *) calloc (1, sizeof (T));
+    if (unlikely (!p))
+      p = const_cast<T *> (&Null(T));
+    else
+      p->init (face);
+    return p;
   }
-
-  inline hb_blob_t* get_blob (void) const
+  static inline void destroy (T *p)
   {
-  retry:
-    hb_blob_t *b = (hb_blob_t *) hb_atomic_ptr_get (&this->instance);
-    if (unlikely (!b))
+    if (p != &Null(T))
     {
-      b = hb_sanitize_context_t ().reference_table<T> (this->face);
-      if (!hb_atomic_ptr_cmpexch (&this->instance, nullptr, b))
-      {
-	hb_blob_destroy (b);
-	goto retry;
-      }
-      this->instance = b;
+      p->fini();
+      free (p);
     }
-    return b;
   }
+};
 
-  inline const T* get (void) const
+template <unsigned int WheresFace, typename T>
+struct hb_table_lazy_loader_t : hb_base_lazy_loader_t<WheresFace, hb_table_lazy_loader_t<WheresFace, T>, T, hb_blob_t>
+{
+  static inline hb_blob_t *create (hb_face_t *face)
+  {
+    return hb_sanitize_context_t ().reference_table<T> (face);
+  }
+  static inline void destroy (hb_blob_t *p)
+  {
+    hb_blob_destroy (p);
+  }
+  static inline const T* convert (const hb_blob_t *blob)
+  {
+    return blob->as<T> ();
+  }
+
+  inline hb_blob_t* get_blob (void) const
   {
-    hb_blob_t *b = get_blob ();
-    return b->as<T> ();
+    return this->get_stored ();
   }
 };
 
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 5085aa82..d80d8c4c 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -44,10 +44,12 @@ struct hb_ot_font_t
   OT::cmap::accelerator_t cmap;
   OT::hmtx::accelerator_t h_metrics;
   OT::vmtx::accelerator_t v_metrics;
-  hb_lazy_loader_t<OT::glyf::accelerator_t> glyf;
-  hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt;
-  hb_lazy_loader_t<OT::post::accelerator_t> post;
-  hb_lazy_loader_t<OT::kern::accelerator_t> kern;
+
+  hb_face_t *face; /* MUST be before the lazy loaders. */
+  hb_lazy_loader_t<1, OT::glyf::accelerator_t> glyf;
+  hb_lazy_loader_t<2, OT::CBDT::accelerator_t> cbdt;
+  hb_lazy_loader_t<3, OT::post::accelerator_t> post;
+  hb_lazy_loader_t<4, OT::kern::accelerator_t> kern;
 };
 
 
@@ -62,10 +64,11 @@ _hb_ot_font_create (hb_face_t *face)
   ot_font->cmap.init (face);
   ot_font->h_metrics.init (face);
   ot_font->v_metrics.init (face, ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
-  ot_font->glyf.init (face);
-  ot_font->cbdt.init (face);
-  ot_font->post.init (face);
-  ot_font->kern.init (face);
+  ot_font->face = face;
+  ot_font->glyf.init ();
+  ot_font->cbdt.init ();
+  ot_font->post.init ();
+  ot_font->kern.init ();
 
   return ot_font;
 }
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index a3cf137d..3a99937c 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -172,11 +172,12 @@ struct hb_ot_layout_t
   const struct OT::GPOS *gpos;
 
   /* TODO Move the following out of this struct. */
-  hb_table_lazy_loader_t<struct OT::BASE> base;
-  hb_table_lazy_loader_t<struct OT::MATH> math;
-  hb_table_lazy_loader_t<struct OT::fvar> fvar;
-  hb_table_lazy_loader_t<struct OT::avar> avar;
-  hb_table_lazy_loader_t<struct AAT::morx> morx;
+  hb_face_t *face; /* MUST be before the lazy loaders. */
+  hb_table_lazy_loader_t<1, struct OT::BASE> base;
+  hb_table_lazy_loader_t<2, struct OT::MATH> math;
+  hb_table_lazy_loader_t<3, struct OT::fvar> fvar;
+  hb_table_lazy_loader_t<4, struct OT::avar> avar;
+  hb_table_lazy_loader_t<5, struct AAT::morx> morx;
 
   unsigned int gsub_lookup_count;
   unsigned int gpos_lookup_count;
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 4cf469c3..8a9eae45 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -63,10 +63,11 @@ _hb_ot_layout_create (hb_face_t *face)
   layout->gpos_blob = hb_sanitize_context_t ().reference_table<OT::GPOS> (face);
   layout->gpos = layout->gpos_blob->as<OT::GPOS> ();
 
-  layout->math.init (face);
-  layout->fvar.init (face);
-  layout->avar.init (face);
-  layout->morx.init (face);
+  layout->face = face;
+  layout->math.init ();
+  layout->fvar.init ();
+  layout->avar.init ();
+  layout->morx.init ();
 
   {
     /*
commit bdd3c11a19d87999eeaff2c82f21c6938d1d9342
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 2 00:38:46 2018 -0700

    Internal templatization of lazy-loaders

diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh
index 6328fb00..dbabeadd 100644
--- a/src/hb-machinery-private.hh
+++ b/src/hb-machinery-private.hh
@@ -590,38 +590,54 @@ struct BEInt<Type, 4>
  * Lazy struct and blob loaders.
  */
 
-/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t.
- * I mean, yeah, only every method is different. */
-template <typename T>
-struct hb_lazy_loader_t
+template <typename Subclass,
+	  typename Returned,
+	  typename Stored = Returned>
+struct hb_base_lazy_loader_t
 {
+  /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
+  inline const Subclass* thiz (void) const { return static_cast<const Subclass *> (this); }
+
   inline void init (hb_face_t *face_)
   {
     face = face_;
     instance = nullptr;
   }
 
+  inline const Returned * operator-> (void) const
+  {
+    return thiz ()->get ();
+  }
+
+  protected:
+  hb_face_t *face;
+  mutable Stored *instance;
+};
+
+template <typename T>
+struct hb_lazy_loader_t : hb_base_lazy_loader_t<hb_lazy_loader_t<T>, T>
+{
   inline void fini (void)
   {
-    if (instance && instance != &Null(T))
+    if (this->instance && this->instance != &Null(T))
     {
-      instance->fini();
-      free (instance);
+      this->instance->fini();
+      free (this->instance);
     }
   }
 
   inline const T* get (void) const
   {
   retry:
-    T *p = (T *) hb_atomic_ptr_get (&instance);
+    T *p = (T *) hb_atomic_ptr_get (&this->instance);
     if (unlikely (!p))
     {
       p = (T *) calloc (1, sizeof (T));
       if (unlikely (!p))
         p = const_cast<T *> (&Null(T));
       else
-	p->init (face);
-      if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
+	p->init (this->face);
+      if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&this->instance), nullptr, p)))
       {
 	if (p != &Null(T))
 	  p->fini ();
@@ -630,46 +646,29 @@ struct hb_lazy_loader_t
     }
     return p;
   }
-
-  inline const T* operator-> (void) const
-  {
-    return get ();
-  }
-
-  private:
-  hb_face_t *face;
-  mutable T *instance;
 };
 
-/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t.
- * I mean, yeah, only every method is different. */
 template <typename T>
-struct hb_table_lazy_loader_t
+struct hb_table_lazy_loader_t : hb_base_lazy_loader_t<hb_table_lazy_loader_t<T>, T, hb_blob_t>
 {
-  inline void init (hb_face_t *face_)
-  {
-    face = face_;
-    blob = nullptr;
-  }
-
   inline void fini (void)
   {
-    hb_blob_destroy (blob);
+    hb_blob_destroy (this->instance);
   }
 
   inline hb_blob_t* get_blob (void) const
   {
   retry:
-    hb_blob_t *b = (hb_blob_t *) hb_atomic_ptr_get (&blob);
+    hb_blob_t *b = (hb_blob_t *) hb_atomic_ptr_get (&this->instance);
     if (unlikely (!b))
     {
-      b = hb_sanitize_context_t ().reference_table<T> (face);
-      if (!hb_atomic_ptr_cmpexch (&blob, nullptr, b))
+      b = hb_sanitize_context_t ().reference_table<T> (this->face);
+      if (!hb_atomic_ptr_cmpexch (&this->instance, nullptr, b))
       {
 	hb_blob_destroy (b);
 	goto retry;
       }
-      blob = b;
+      this->instance = b;
     }
     return b;
   }
@@ -679,15 +678,6 @@ struct hb_table_lazy_loader_t
     hb_blob_t *b = get_blob ();
     return b->as<T> ();
   }
-
-  inline const T* operator-> (void) const
-  {
-    return get();
-  }
-
-  private:
-  hb_face_t *face;
-  mutable hb_blob_t *blob;
 };
 
 
commit ed7b2e58fc9afb547656cf28eb4a253d989de43c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Aug 1 23:59:09 2018 -0700

    Remove OT namespace from hb-machinery-private.hh

diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc
index 400b890a..65214692 100644
--- a/src/dump-emoji.cc
+++ b/src/dump-emoji.cc
@@ -233,10 +233,10 @@ int main (int argc, char **argv)
   svg.dump (svg_callback);
   svg.fini ();
 
-  hb_blob_t* colr_blob = OT::hb_sanitize_context_t().reference_table<OT::COLR> (face);
+  hb_blob_t* colr_blob = hb_sanitize_context_t ().reference_table<OT::COLR> (face);
   const OT::COLR *colr = colr_blob->as<OT::COLR> ();
 
-  hb_blob_t* cpal_blob = OT::hb_sanitize_context_t().reference_table<OT::CPAL> (face);
+  hb_blob_t* cpal_blob = hb_sanitize_context_t ().reference_table<OT::CPAL> (face);
   const OT::CPAL *cpal = cpal_blob->as<OT::CPAL> ();
 
   cairo_font_face_t *cairo_face;
diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc
index 405aafcc..3417033f 100644
--- a/src/hb-aat-layout.cc
+++ b/src/hb-aat-layout.cc
@@ -61,7 +61,7 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
 // static inline void
 // _hb_aat_layout_create (hb_face_t *face)
 // {
-//   hb_blob_t *morx_blob = OT::hb_sanitize_context_t().reference_table<AAT::morx> (face);
+//   hb_blob_t *morx_blob = hb_sanitize_context_t ().reference_table<AAT::morx> (face);
 //   morx_blob->as<AAT::morx> ();
 
 //   if (0)
diff --git a/src/hb-face.cc b/src/hb-face.cc
index 22b36a91..75dc486e 100644
--- a/src/hb-face.cc
+++ b/src/hb-face.cc
@@ -52,7 +52,7 @@ hb_face_count (hb_blob_t *blob)
 
   /* TODO We shouldn't be sanitizing blob.  Port to run sanitizer and return if not sane. */
   /* Make API signature const after. */
-  hb_blob_t *sanitized = OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob));
+  hb_blob_t *sanitized = hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob));
   const OT::OpenTypeFontFile& ot = *sanitized->as<OT::OpenTypeFontFile> ();
   unsigned int ret = ot.get_face_count ();
   hb_blob_destroy (sanitized);
@@ -190,7 +190,7 @@ hb_face_create (hb_blob_t    *blob,
   if (unlikely (!blob))
     blob = hb_blob_get_empty ();
 
-  hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob)), index);
+  hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob)), index);
 
   if (unlikely (!closure))
     return hb_face_get_empty ();
diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh
index 6617264b..6328fb00 100644
--- a/src/hb-machinery-private.hh
+++ b/src/hb-machinery-private.hh
@@ -35,9 +35,6 @@
 #include "hb-iter-private.hh"
 
 
-namespace OT {
-
-
 /*
  * Casts
  */
@@ -593,7 +590,8 @@ struct BEInt<Type, 4>
  * Lazy struct and blob loaders.
  */
 
-/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
+/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t.
+ * I mean, yeah, only every method is different. */
 template <typename T>
 struct hb_lazy_loader_t
 {
@@ -643,7 +641,8 @@ struct hb_lazy_loader_t
   mutable T *instance;
 };
 
-/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
+/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t.
+ * I mean, yeah, only every method is different. */
 template <typename T>
 struct hb_table_lazy_loader_t
 {
@@ -664,7 +663,7 @@ struct hb_table_lazy_loader_t
     hb_blob_t *b = (hb_blob_t *) hb_atomic_ptr_get (&blob);
     if (unlikely (!b))
     {
-      b = OT::hb_sanitize_context_t().reference_table<T> (face);
+      b = hb_sanitize_context_t ().reference_table<T> (face);
       if (!hb_atomic_ptr_cmpexch (&blob, nullptr, b))
       {
 	hb_blob_destroy (b);
@@ -692,7 +691,4 @@ struct hb_table_lazy_loader_t
 };
 
 
-} /* namespace OT */
-
-
 #endif /* HB_MACHINERY_PRIVATE_HH */
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 83102303..5085aa82 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -44,10 +44,10 @@ struct hb_ot_font_t
   OT::cmap::accelerator_t cmap;
   OT::hmtx::accelerator_t h_metrics;
   OT::vmtx::accelerator_t v_metrics;
-  OT::hb_lazy_loader_t<OT::glyf::accelerator_t> glyf;
-  OT::hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt;
-  OT::hb_lazy_loader_t<OT::post::accelerator_t> post;
-  OT::hb_lazy_loader_t<OT::kern::accelerator_t> kern;
+  hb_lazy_loader_t<OT::glyf::accelerator_t> glyf;
+  hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt;
+  hb_lazy_loader_t<OT::post::accelerator_t> post;
+  hb_lazy_loader_t<OT::kern::accelerator_t> kern;
 };
 
 
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 6fe673e9..a3cf137d 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -172,11 +172,11 @@ struct hb_ot_layout_t
   const struct OT::GPOS *gpos;
 
   /* TODO Move the following out of this struct. */
-  OT::hb_table_lazy_loader_t<struct OT::BASE> base;
-  OT::hb_table_lazy_loader_t<struct OT::MATH> math;
-  OT::hb_table_lazy_loader_t<struct OT::fvar> fvar;
-  OT::hb_table_lazy_loader_t<struct OT::avar> avar;
-  OT::hb_table_lazy_loader_t<struct AAT::morx> morx;
+  hb_table_lazy_loader_t<struct OT::BASE> base;
+  hb_table_lazy_loader_t<struct OT::MATH> math;
+  hb_table_lazy_loader_t<struct OT::fvar> fvar;
+  hb_table_lazy_loader_t<struct OT::avar> avar;
+  hb_table_lazy_loader_t<struct AAT::morx> morx;
 
   unsigned int gsub_lookup_count;
   unsigned int gpos_lookup_count;
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index c790c3ce..4cf469c3 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -54,13 +54,13 @@ _hb_ot_layout_create (hb_face_t *face)
   if (unlikely (!layout))
     return nullptr;
 
-  layout->gdef_blob = OT::hb_sanitize_context_t().reference_table<OT::GDEF> (face);
+  layout->gdef_blob = hb_sanitize_context_t ().reference_table<OT::GDEF> (face);
   layout->gdef = layout->gdef_blob->as<OT::GDEF> ();
 
-  layout->gsub_blob = OT::hb_sanitize_context_t().reference_table<OT::GSUB> (face);
+  layout->gsub_blob = hb_sanitize_context_t ().reference_table<OT::GSUB> (face);
   layout->gsub = layout->gsub_blob->as<OT::GSUB> ();
 
-  layout->gpos_blob = OT::hb_sanitize_context_t().reference_table<OT::GPOS> (face);
+  layout->gpos_blob = hb_sanitize_context_t ().reference_table<OT::GPOS> (face);
   layout->gpos = layout->gpos_blob->as<OT::GPOS> ();
 
   layout->math.init (face);
@@ -1116,7 +1116,7 @@ struct GPOSProxy
 
 
 struct hb_get_subtables_context_t :
-       OT::hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
+       hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
 {
   template <typename Type>
   static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh
index 5a257f04..40c5015c 100644
--- a/src/hb-ot-shape-complex-arabic-fallback.hh
+++ b/src/hb-ot-shape-complex-arabic-fallback.hh
@@ -79,12 +79,12 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
    * May not be good-enough for presidential candidate interviews, but good-enough for us... */
   hb_stable_sort (&glyphs[0], num_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &substitutes[0]);
 
-  OT::Supplier<OT::GlyphID> glyphs_supplier      (glyphs, num_glyphs);
-  OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
+  Supplier<OT::GlyphID> glyphs_supplier      (glyphs, num_glyphs);
+  Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
 
   /* Each glyph takes four bytes max, and there's some overhead. */
   char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
-  OT::hb_serialize_context_t c (buf, sizeof (buf));
+  hb_serialize_context_t c (buf, sizeof (buf));
   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
   bool ret = lookup->serialize_single (&c,
 				       OT::LookupFlag::IgnoreMarks,
@@ -155,15 +155,15 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
   if (!num_ligatures)
     return nullptr;
 
-  OT::Supplier<OT::GlyphID>   first_glyphs_supplier                      (first_glyphs, num_first_glyphs);
-  OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier    (ligature_per_first_glyph_count_list, num_first_glyphs);
-  OT::Supplier<OT::GlyphID>   ligatures_supplier                         (ligature_list, num_ligatures);
-  OT::Supplier<unsigned int > component_count_supplier                   (component_count_list, num_ligatures);
-  OT::Supplier<OT::GlyphID>   component_supplier                         (component_list, num_ligatures);
+  Supplier<OT::GlyphID>   first_glyphs_supplier                      (first_glyphs, num_first_glyphs);
+  Supplier<unsigned int > ligature_per_first_glyph_count_supplier    (ligature_per_first_glyph_count_list, num_first_glyphs);
+  Supplier<OT::GlyphID>   ligatures_supplier                         (ligature_list, num_ligatures);
+  Supplier<unsigned int > component_count_supplier                   (component_count_list, num_ligatures);
+  Supplier<OT::GlyphID>   component_supplier                         (component_list, num_ligatures);
 
   /* 16 bytes per ligature ought to be enough... */
   char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
-  OT::hb_serialize_context_t c (buf, sizeof (buf));
+  hb_serialize_context_t c (buf, sizeof (buf));
   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
   bool ret = lookup->serialize_ligature (&c,
 					 OT::LookupFlag::IgnoreMarks,
diff --git a/src/hb-static.cc b/src/hb-static.cc
index e6920e7e..bd0943f5 100644
--- a/src/hb-static.cc
+++ b/src/hb-static.cc
@@ -38,7 +38,7 @@ hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_
 void
 hb_face_t::load_num_glyphs (void) const
 {
-  OT::hb_sanitize_context_t c = OT::hb_sanitize_context_t();
+  hb_sanitize_context_t c = hb_sanitize_context_t ();
   c.set_num_glyphs (0); /* So we don't recurse ad infinitum. */
   hb_blob_t *maxp_blob = c.reference_table<OT::maxp> (this);
   const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> ();
@@ -49,7 +49,7 @@ hb_face_t::load_num_glyphs (void) const
 void
 hb_face_t::load_upem (void) const
 {
-  hb_blob_t *head_blob = OT::hb_sanitize_context_t().reference_table<OT::head> (this);
+  hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<OT::head> (this);
   const OT::head *head_table = head_blob->as<OT::head> ();
   upem = head_table->get_upem ();
   hb_blob_destroy (head_blob);
diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
index 2b97a010..36af3bea 100644
--- a/src/hb-subset-glyf.cc
+++ b/src/hb-subset-glyf.cc
@@ -292,7 +292,7 @@ hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
                          hb_blob_t       **glyf_prime, /* OUT */
                          hb_blob_t       **loca_prime /* OUT */)
 {
-  hb_blob_t *glyf_blob = OT::hb_sanitize_context_t().reference_table<OT::glyf> (plan->source);
+  hb_blob_t *glyf_blob = hb_sanitize_context_t ().reference_table<OT::glyf> (plan->source);
   const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr);
 
   OT::glyf::accelerator_t glyf;
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index 308c7eb2..9e8e2aff 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -78,7 +78,7 @@ template<typename TableType>
 static bool
 _subset (hb_subset_plan_t *plan)
 {
-  hb_blob_t *source_blob = OT::hb_sanitize_context_t().reference_table<TableType> (plan->source);
+  hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
   const TableType *table = source_blob->as<TableType> ();
 
   hb_tag_t tag = TableType::tableTag;
@@ -157,14 +157,14 @@ _hb_subset_face_data_reference_blob (hb_subset_face_data_t *data)
   if (unlikely (!buf))
     return nullptr;
 
-  OT::hb_serialize_context_t c (buf, face_length);
+  hb_serialize_context_t c (buf, face_length);
   OT::OpenTypeFontFile *f = c.start_serialize<OT::OpenTypeFontFile> ();
 
   bool is_cff = data->tables.lsearch (HB_TAG ('C','F','F',' ')) || data->tables.lsearch (HB_TAG ('C','F','F','2'));
   hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag;
 
-  OT::Supplier<hb_tag_t>    tags_supplier  (&data->tables[0].tag, table_count, sizeof (data->tables[0]));
-  OT::Supplier<hb_blob_t *> blobs_supplier (&data->tables[0].blob, table_count, sizeof (data->tables[0]));
+  Supplier<hb_tag_t>    tags_supplier  (&data->tables[0].tag, table_count, sizeof (data->tables[0]));
+  Supplier<hb_blob_t *> blobs_supplier (&data->tables[0].blob, table_count, sizeof (data->tables[0]));
   bool ret = f->serialize_single (&c,
 				  sfnt_tag,
 				  tags_supplier,
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index c835c75d..7f7f10d0 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -358,7 +358,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
    * full, PS. All of them point to the same name data with our unique name.
    */
 
-  blob = OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (blob);
+  blob = hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (blob);
 
   unsigned int length, new_length, name_str_len;
   const char *orig_sfnt_data = hb_blob_get_data (blob, &length);
commit cb1491f92e24649433988ff81a89347dccf07c8b
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Aug 1 22:50:45 2018 -0700

    Minor

diff --git a/src/hb-blob-private.hh b/src/hb-blob-private.hh
index 56a7b668..93fbc2d5 100644
--- a/src/hb-blob-private.hh
+++ b/src/hb-blob-private.hh
@@ -57,11 +57,6 @@ struct hb_blob_t
   HB_INTERNAL bool try_make_writable_inplace (void);
   HB_INTERNAL bool try_make_writable_inplace_unix (void);
 
-  inline void lock (void)
-  {
-    hb_blob_make_immutable (this);
-  }
-
   template <typename Type>
   inline const Type* as (void) const
   {
diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh
index ff56b1dc..6617264b 100644
--- a/src/hb-machinery-private.hh
+++ b/src/hb-machinery-private.hh
@@ -30,6 +30,8 @@
 #define HB_MACHINERY_PRIVATE_HH
 
 #include "hb-private.hh"
+#include "hb-blob-private.hh"
+
 #include "hb-iter-private.hh"
 
 
@@ -188,7 +190,7 @@ struct hb_sanitize_context_t :
 
   inline void start_processing (void)
   {
-    this->start = hb_blob_get_data (this->blob, nullptr);
+    this->start = this->blob->data;
     this->end = this->start + this->blob->length;
     assert (this->start <= this->end); /* Must not overflow. */
     this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
@@ -336,7 +338,7 @@ struct hb_sanitize_context_t :
     DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED");
     if (sane)
     {
-      blob->lock ();
+      hb_blob_make_immutable (blob);
       return blob;
     }
     else
@@ -350,8 +352,8 @@ struct hb_sanitize_context_t :
   inline hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag)
   {
     if (!num_glyphs_set)
-      set_num_glyphs (face->get_num_glyphs ());
-    return sanitize_blob<Type> (face->reference_table (tableTag));
+      set_num_glyphs (hb_face_get_glyph_count (face));
+    return sanitize_blob<Type> (hb_face_reference_table (face, tableTag));
   }
 
   mutable unsigned int debug_depth;
commit 16ccfafbbd48c7a9737ce1d12e75406a050b71a9
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Aug 1 22:50:06 2018 -0700

    [face] Sprinkle const in the API

diff --git a/src/hb-face.cc b/src/hb-face.cc
index fab2aa3a..22b36a91 100644
--- a/src/hb-face.cc
+++ b/src/hb-face.cc
@@ -51,6 +51,7 @@ hb_face_count (hb_blob_t *blob)
     return 0;
 
   /* TODO We shouldn't be sanitizing blob.  Port to run sanitizer and return if not sane. */
+  /* Make API signature const after. */
   hb_blob_t *sanitized = OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob));
   const OT::OpenTypeFontFile& ot = *sanitized->as<OT::OpenTypeFontFile> ();
   unsigned int ret = ot.get_face_count ();
@@ -302,7 +303,7 @@ hb_face_set_user_data (hb_face_t          *face,
  * Since: 0.9.2
  **/
 void *
-hb_face_get_user_data (hb_face_t          *face,
+hb_face_get_user_data (const hb_face_t    *face,
 		       hb_user_data_key_t *key)
 {
   return hb_object_get_user_data (face, key);
@@ -336,7 +337,7 @@ hb_face_make_immutable (hb_face_t *face)
  * Since: 0.9.2
  **/
 hb_bool_t
-hb_face_is_immutable (hb_face_t *face)
+hb_face_is_immutable (const hb_face_t *face)
 {
   return face->immutable;
 }
@@ -354,8 +355,8 @@ hb_face_is_immutable (hb_face_t *face)
  * Since: 0.9.2
  **/
 hb_blob_t *
-hb_face_reference_table (hb_face_t *face,
-			 hb_tag_t   tag)
+hb_face_reference_table (const hb_face_t *face,
+			 hb_tag_t tag)
 {
   return face->reference_table (tag);
 }
@@ -406,7 +407,7 @@ hb_face_set_index (hb_face_t    *face,
  * Since: 0.9.2
  **/
 unsigned int
-hb_face_get_index (hb_face_t    *face)
+hb_face_get_index (const hb_face_t *face)
 {
   return face->index;
 }
@@ -441,7 +442,7 @@ hb_face_set_upem (hb_face_t    *face,
  * Since: 0.9.2
  **/
 unsigned int
-hb_face_get_upem (hb_face_t *face)
+hb_face_get_upem (const hb_face_t *face)
 {
   return face->get_upem ();
 }
@@ -476,7 +477,7 @@ hb_face_set_glyph_count (hb_face_t    *face,
  * Since: 0.9.7
  **/
 unsigned int
-hb_face_get_glyph_count (hb_face_t *face)
+hb_face_get_glyph_count (const hb_face_t *face)
 {
   return face->get_num_glyphs ();
 }
@@ -492,7 +493,7 @@ hb_face_get_glyph_count (hb_face_t *face)
  * Since: 1.6.0
  **/
 unsigned int
-hb_face_get_table_tags (hb_face_t    *face,
+hb_face_get_table_tags (const hb_face_t *face,
 			unsigned int  start_offset,
 			unsigned int *table_count, /* IN/OUT */
 			hb_tag_t     *table_tags /* OUT */)
diff --git a/src/hb-face.h b/src/hb-face.h
index 983ee56b..208092ef 100644
--- a/src/hb-face.h
+++ b/src/hb-face.h
@@ -76,19 +76,19 @@ hb_face_set_user_data (hb_face_t          *face,
 		       hb_bool_t           replace);
 
 HB_EXTERN void *
-hb_face_get_user_data (hb_face_t          *face,
+hb_face_get_user_data (const hb_face_t    *face,
 		       hb_user_data_key_t *key);
 
 HB_EXTERN void
 hb_face_make_immutable (hb_face_t *face);
 
 HB_EXTERN hb_bool_t
-hb_face_is_immutable (hb_face_t *face);
+hb_face_is_immutable (const hb_face_t *face);
 
 
 HB_EXTERN hb_blob_t *
-hb_face_reference_table (hb_face_t *face,
-			 hb_tag_t   tag);
+hb_face_reference_table (const hb_face_t *face,
+			 hb_tag_t tag);
 
 HB_EXTERN hb_blob_t *
 hb_face_reference_blob (hb_face_t *face);
@@ -98,24 +98,24 @@ hb_face_set_index (hb_face_t    *face,
 		   unsigned int  index);
 
 HB_EXTERN unsigned int
-hb_face_get_index (hb_face_t    *face);
+hb_face_get_index (const hb_face_t *face);
 
 HB_EXTERN void
 hb_face_set_upem (hb_face_t    *face,
 		  unsigned int  upem);
 
 HB_EXTERN unsigned int
-hb_face_get_upem (hb_face_t *face);
+hb_face_get_upem (const hb_face_t *face);
 
 HB_EXTERN void
 hb_face_set_glyph_count (hb_face_t    *face,
 			 unsigned int  glyph_count);
 
 HB_EXTERN unsigned int
-hb_face_get_glyph_count (hb_face_t *face);
+hb_face_get_glyph_count (const hb_face_t *face);
 
 HB_EXTERN unsigned int
-hb_face_get_table_tags (hb_face_t    *face,
+hb_face_get_table_tags (const hb_face_t *face,
 			unsigned int  start_offset,
 			unsigned int *table_count, /* IN/OUT */
 			hb_tag_t     *table_tags /* OUT */);
commit 3d22aefedebb5277c5d79011e48e7be1a26a53c1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Aug 1 18:03:32 2018 -0700

    Rename

diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc
index 3bdc3f78..13ab9886 100644
--- a/src/hb-coretext.cc
+++ b/src/hb-coretext.cc
@@ -269,7 +269,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
   return ct_font;
 }
 
-hb_coretext_shaper_face_data_t *
+hb_coretext_face_data_t *
 _hb_coretext_shaper_face_data_create (hb_face_t *face)
 {
   CGFontRef cg_font = create_cg_font (face);
@@ -280,11 +280,11 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face)
     return nullptr;
   }
 
-  return (hb_coretext_shaper_face_data_t *) cg_font;
+  return (hb_coretext_face_data_t *) cg_font;
 }
 
 void
-_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
+_hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data)
 {
   CFRelease ((CGFontRef) data);
 }
@@ -306,7 +306,7 @@ hb_coretext_face_get_cg_font (hb_face_t *face)
 }
 
 
-hb_coretext_shaper_font_data_t *
+hb_coretext_font_data_t *
 _hb_coretext_shaper_font_data_create (hb_font_t *font)
 {
   hb_face_t *face = font->face;
@@ -321,11 +321,11 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
     return nullptr;
   }
 
-  return (hb_coretext_shaper_font_data_t *) ct_font;
+  return (hb_coretext_font_data_t *) ct_font;
 }
 
 void
-_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
+_hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data)
 {
   CFRelease ((CTFontRef) data);
 }
@@ -348,7 +348,7 @@ hb_coretext_font_create (CTFontRef ct_font)
   hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
 
   /* Let there be dragons here... */
-  HB_SHAPER_DATA_GET (font) = (hb_coretext_shaper_font_data_t *) CFRetain (ct_font);
+  HB_SHAPER_DATA_GET (font) = (hb_coretext_font_data_t *) CFRetain (ct_font);
 
   return font;
 }
@@ -366,20 +366,20 @@ hb_coretext_font_get_ct_font (hb_font_t *font)
  * shaper shape_plan data
  */
 
-struct hb_coretext_shaper_shape_plan_data_t {};
+struct hb_coretext_shape_plan_data_t {};
 
-hb_coretext_shaper_shape_plan_data_t *
+hb_coretext_shape_plan_data_t *
 _hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
 					     const hb_feature_t *user_features HB_UNUSED,
 					     unsigned int        num_user_features HB_UNUSED,
 					     const int          *coords HB_UNUSED,
 					     unsigned int        num_coords HB_UNUSED)
 {
-  return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_coretext_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_t *data HB_UNUSED)
+_hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shape_plan_data_t *data HB_UNUSED)
 {
 }
 
@@ -1329,9 +1329,9 @@ HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font)
  * shaper face data
  */
 
-struct hb_coretext_aat_shaper_face_data_t {};
+struct hb_coretext_aat_face_data_t {};
 
-hb_coretext_aat_shaper_face_data_t *
+hb_coretext_aat_face_data_t *
 _hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
 {
   static const hb_tag_t tags[] = {HB_CORETEXT_TAG_MORX, HB_CORETEXT_TAG_MORT, HB_CORETEXT_TAG_KERX};
@@ -1342,7 +1342,7 @@ _hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
     if (hb_blob_get_length (blob))
     {
       hb_blob_destroy (blob);
-      return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
+      return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
     }
     hb_blob_destroy (blob);
   }
@@ -1351,7 +1351,7 @@ _hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
 }
 
 void
-_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *data HB_UNUSED)
+_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_face_data_t *data HB_UNUSED)
 {
 }
 
@@ -1360,16 +1360,16 @@ _hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *d
  * shaper font data
  */
 
-struct hb_coretext_aat_shaper_font_data_t {};
+struct hb_coretext_aat_font_data_t {};
 
-hb_coretext_aat_shaper_font_data_t *
+hb_coretext_aat_font_data_t *
 _hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
 {
-  return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
+  return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
 }
 
 void
-_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED)
+_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_font_data_t *data HB_UNUSED)
 {
 }
 
@@ -1378,20 +1378,20 @@ _hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *d
  * shaper shape_plan data
  */
 
-struct hb_coretext_aat_shaper_shape_plan_data_t {};
+struct hb_coretext_aat_shape_plan_data_t {};
 
-hb_coretext_aat_shaper_shape_plan_data_t *
+hb_coretext_aat_shape_plan_data_t *
 _hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
 					     const hb_feature_t *user_features HB_UNUSED,
 					     unsigned int        num_user_features HB_UNUSED,
 					     const int          *coords HB_UNUSED,
 					     unsigned int        num_coords HB_UNUSED)
 {
-  return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_coretext_aat_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED)
+_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shape_plan_data_t *data HB_UNUSED)
 {
 }
 
diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc
index 7c688494..baad8188 100644
--- a/src/hb-directwrite.cc
+++ b/src/hb-directwrite.cc
@@ -133,7 +133,7 @@ public:
 * shaper face data
 */
 
-struct hb_directwrite_shaper_face_data_t
+struct hb_directwrite_face_data_t
 {
   IDWriteFactory *dwriteFactory;
   IDWriteFontFile *fontFile;
@@ -143,10 +143,10 @@ struct hb_directwrite_shaper_face_data_t
   hb_blob_t *faceBlob;
 };
 
-hb_directwrite_shaper_face_data_t *
+hb_directwrite_face_data_t *
 _hb_directwrite_shaper_face_data_create (hb_face_t *face)
 {
-  hb_directwrite_shaper_face_data_t *data = new hb_directwrite_shaper_face_data_t;
+  hb_directwrite_face_data_t *data = new hb_directwrite_face_data_t;
   if (unlikely (!data))
     return nullptr;
 
@@ -206,7 +206,7 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
 }
 
 void
-_hb_directwrite_shaper_face_data_destroy (hb_directwrite_shaper_face_data_t *data)
+_hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data)
 {
   if (data->fontFace)
     data->fontFace->Release ();
@@ -233,16 +233,16 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_shaper_face_data_t *dat
  * shaper font data
  */
 
-struct hb_directwrite_shaper_font_data_t
+struct hb_directwrite_font_data_t
 {
 };
 
-hb_directwrite_shaper_font_data_t *
+hb_directwrite_font_data_t *
 _hb_directwrite_shaper_font_data_create (hb_font_t *font)
 {
   if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return nullptr;
 
-  hb_directwrite_shaper_font_data_t *data = new hb_directwrite_shaper_font_data_t;
+  hb_directwrite_font_data_t *data = new hb_directwrite_font_data_t;
   if (unlikely (!data))
     return nullptr;
 
@@ -250,7 +250,7 @@ _hb_directwrite_shaper_font_data_create (hb_font_t *font)
 }
 
 void
-_hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *data)
+_hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data)
 {
   delete data;
 }
@@ -260,20 +260,20 @@ _hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *dat
  * shaper shape_plan data
  */
 
-struct hb_directwrite_shaper_shape_plan_data_t {};
+struct hb_directwrite_shape_plan_data_t {};
 
-hb_directwrite_shaper_shape_plan_data_t *
+hb_directwrite_shape_plan_data_t *
 _hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
 					       const hb_feature_t *user_features HB_UNUSED,
 					       unsigned int        num_user_features HB_UNUSED,
 					       const int          *coords HB_UNUSED,
 					       unsigned int        num_coords HB_UNUSED)
 {
-  return (hb_directwrite_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_directwrite_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shaper_shape_plan_data_t *data HB_UNUSED)
+_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shape_plan_data_t *data HB_UNUSED)
 {
 }
 
@@ -555,8 +555,8 @@ _hb_directwrite_shape_full (hb_shape_plan_t    *shape_plan,
   float               lineWidth)
 {
   hb_face_t *face = font->face;
-  hb_directwrite_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
-  hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+  hb_directwrite_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+  hb_directwrite_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
   IDWriteFactory *dwriteFactory = face_data->dwriteFactory;
   IDWriteFontFace *fontFace = face_data->fontFace;
 
diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc
index 3f09c3f5..eff20f70 100644
--- a/src/hb-fallback-shape.cc
+++ b/src/hb-fallback-shape.cc
@@ -36,16 +36,16 @@ HB_SHAPER_DATA_ENSURE_DEFINE(fallback, font)
  * shaper face data
  */
 
-struct hb_fallback_shaper_face_data_t {};
+struct hb_fallback_face_data_t {};
 
-hb_fallback_shaper_face_data_t *
+hb_fallback_face_data_t *
 _hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
 {
-  return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_fallback_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
+_hb_fallback_shaper_face_data_destroy (hb_fallback_face_data_t *data HB_UNUSED)
 {
 }
 
@@ -54,16 +54,16 @@ _hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_U
  * shaper font data
  */
 
-struct hb_fallback_shaper_font_data_t {};
+struct hb_fallback_font_data_t {};
 
-hb_fallback_shaper_font_data_t *
+hb_fallback_font_data_t *
 _hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
 {
-  return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_fallback_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
+_hb_fallback_shaper_font_data_destroy (hb_fallback_font_data_t *data HB_UNUSED)
 {
 }
 
@@ -72,20 +72,20 @@ _hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_U
  * shaper shape_plan data
  */
 
-struct hb_fallback_shaper_shape_plan_data_t {};
+struct hb_fallback_shape_plan_data_t {};
 
-hb_fallback_shaper_shape_plan_data_t *
+hb_fallback_shape_plan_data_t *
 _hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
 					    const hb_feature_t *user_features HB_UNUSED,
 					    unsigned int        num_user_features HB_UNUSED,
 					    const int          *coords HB_UNUSED,
 					    unsigned int        num_coords HB_UNUSED)
 {
-  return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_fallback_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
+_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shape_plan_data_t *data HB_UNUSED)
 {
 }
 
diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc
index c20f6bef..da7944b8 100644
--- a/src/hb-graphite2.cc
+++ b/src/hb-graphite2.cc
@@ -48,7 +48,7 @@ typedef struct hb_graphite2_tablelist_t {
   unsigned int tag;
 } hb_graphite2_tablelist_t;
 
-struct hb_graphite2_shaper_face_data_t {
+struct hb_graphite2_face_data_t {
   hb_face_t *face;
   gr_face   *grface;
   hb_graphite2_tablelist_t *tlist;
@@ -56,7 +56,7 @@ struct hb_graphite2_shaper_face_data_t {
 
 static const void *hb_graphite2_get_table (const void *data, unsigned int tag, size_t *len)
 {
-  hb_graphite2_shaper_face_data_t *face_data = (hb_graphite2_shaper_face_data_t *) data;
+  hb_graphite2_face_data_t *face_data = (hb_graphite2_face_data_t *) data;
   hb_graphite2_tablelist_t *tlist = face_data->tlist;
 
   hb_blob_t *blob = nullptr;
@@ -93,7 +93,7 @@ retry:
   return d;
 }
 
-hb_graphite2_shaper_face_data_t *
+hb_graphite2_face_data_t *
 _hb_graphite2_shaper_face_data_create (hb_face_t *face)
 {
   hb_blob_t *silf_blob = face->reference_table (HB_GRAPHITE2_TAG_SILF);
@@ -106,7 +106,7 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face)
   }
   hb_blob_destroy (silf_blob);
 
-  hb_graphite2_shaper_face_data_t *data = (hb_graphite2_shaper_face_data_t *) calloc (1, sizeof (hb_graphite2_shaper_face_data_t));
+  hb_graphite2_face_data_t *data = (hb_graphite2_face_data_t *) calloc (1, sizeof (hb_graphite2_shaper_face_data_t));
   if (unlikely (!data))
     return nullptr;
 
@@ -122,7 +122,7 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face)
 }
 
 void
-_hb_graphite2_shaper_face_data_destroy (hb_graphite2_shaper_face_data_t *data)
+_hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data)
 {
   hb_graphite2_tablelist_t *tlist = data->tlist;
 
@@ -154,16 +154,16 @@ hb_graphite2_face_get_gr_face (hb_face_t *face)
  * shaper font data
  */
 
-struct hb_graphite2_shaper_font_data_t {};
+struct hb_graphite2_font_data_t {};
 
-hb_graphite2_shaper_font_data_t *
+hb_graphite2_font_data_t *
 _hb_graphite2_shaper_font_data_create (hb_font_t *font HB_UNUSED)
 {
-  return (hb_graphite2_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_graphite2_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_graphite2_shaper_font_data_destroy (hb_graphite2_shaper_font_data_t *data HB_UNUSED)
+_hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED)
 {
 }
 
@@ -181,20 +181,20 @@ hb_graphite2_font_get_gr_font (hb_font_t *font)
  * shaper shape_plan data
  */
 
-struct hb_graphite2_shaper_shape_plan_data_t {};
+struct hb_graphite2_shape_plan_data_t {};
 
-hb_graphite2_shaper_shape_plan_data_t *
+hb_graphite2_shape_plan_data_t *
 _hb_graphite2_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
 					     const hb_feature_t *user_features HB_UNUSED,
 					     unsigned int        num_user_features HB_UNUSED,
 					     const int          *coords HB_UNUSED,
 					     unsigned int        num_coords HB_UNUSED)
 {
-  return (hb_graphite2_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_graphite2_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_graphite2_shaper_shape_plan_data_destroy (hb_graphite2_shaper_shape_plan_data_t *data HB_UNUSED)
+_hb_graphite2_shaper_shape_plan_data_destroy (hb_graphite2_shape_plan_data_t *data HB_UNUSED)
 {
 }
 
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index e40a0e94..d7f4afea 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -27,8 +27,8 @@
  */
 
 #define HB_SHAPER ot
-#define hb_ot_shaper_face_data_t hb_ot_layout_t
-#define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t
+#define hb_ot_face_data_t hb_ot_layout_t
+#define hb_ot_shape_plan_data_t hb_ot_shape_plan_t
 #include "hb-shaper-impl-private.hh"
 
 #include "hb-ot-shape-private.hh"
@@ -132,14 +132,14 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
 
 HB_SHAPER_DATA_ENSURE_DEFINE(ot, face)
 
-hb_ot_shaper_face_data_t *
+hb_ot_face_data_t *
 _hb_ot_shaper_face_data_create (hb_face_t *face)
 {
   return _hb_ot_layout_create (face);
 }
 
 void
-_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
+_hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data)
 {
   _hb_ot_layout_destroy (data);
 }
@@ -151,16 +151,16 @@ _hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
 
 HB_SHAPER_DATA_ENSURE_DEFINE(ot, font)
 
-struct hb_ot_shaper_font_data_t {};
+struct hb_ot_font_data_t {};
 
-hb_ot_shaper_font_data_t *
+hb_ot_font_data_t *
 _hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED)
 {
-  return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
+_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data)
 {
 }
 
@@ -169,7 +169,7 @@ _hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
  * shaper shape_plan data
  */
 
-hb_ot_shaper_shape_plan_data_t *
+hb_ot_shape_plan_data_t *
 _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan,
 				      const hb_feature_t *user_features,
 				      unsigned int        num_user_features,
@@ -204,7 +204,7 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan,
 }
 
 void
-_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
+_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shape_plan_data_t *plan)
 {
   if (plan->shaper->data_destroy)
     plan->shaper->data_destroy (const_cast<void *> (plan->data));
diff --git a/src/hb-shaper-private.hh b/src/hb-shaper-private.hh
index a7ca36c6..457cd957 100644
--- a/src/hb-shaper-private.hh
+++ b/src/hb-shaper-private.hh
@@ -54,7 +54,7 @@ _hb_shapers_get (void);
 /* Means: tried but failed to create. */
 #define HB_SHAPER_DATA_INVALID ((void *) -1)
 
-#define HB_SHAPER_DATA_TYPE_NAME(shaper, object)	hb_##shaper##_shaper_##object##_data_t
+#define HB_SHAPER_DATA_TYPE_NAME(shaper, object)	hb_##shaper##_##object##_data_t
 #define HB_SHAPER_DATA_TYPE(shaper, object)		struct HB_SHAPER_DATA_TYPE_NAME(shaper, object)
 #define HB_SHAPER_DATA_INSTANCE(shaper, object, instance)	(* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(instance)->shaper_data.shaper)
 #define HB_SHAPER_DATA(shaper, object)			HB_SHAPER_DATA_INSTANCE(shaper, object, object)
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index 0199e65f..c835c75d 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -309,7 +309,7 @@ HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, font)
  * shaper face data
  */
 
-struct hb_uniscribe_shaper_face_data_t {
+struct hb_uniscribe_face_data_t {
   HANDLE fh;
   hb_uniscribe_shaper_funcs_t *funcs;
   wchar_t face_name[LF_FACESIZE];
@@ -439,10 +439,10 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
 			 HB_MEMORY_MODE_WRITABLE, nullptr, free);
 }
 
-hb_uniscribe_shaper_face_data_t *
+hb_uniscribe_face_data_t *
 _hb_uniscribe_shaper_face_data_create (hb_face_t *face)
 {
-  hb_uniscribe_shaper_face_data_t *data = (hb_uniscribe_shaper_face_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_face_data_t));
+  hb_uniscribe_face_data_t *data = (hb_uniscribe_face_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_face_data_t));
   if (unlikely (!data))
     return nullptr;
 
@@ -479,7 +479,7 @@ _hb_uniscribe_shaper_face_data_create (hb_face_t *face)
 }
 
 void
-_hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_shaper_face_data_t *data)
+_hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_face_data_t *data)
 {
   RemoveFontMemResourceEx (data->fh);
   free (data);
@@ -490,7 +490,7 @@ _hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_shaper_face_data_t *data)
  * shaper font data
  */
 
-struct hb_uniscribe_shaper_font_data_t {
+struct hb_uniscribe_font_data_t {
   HDC hdc;
   LOGFONTW log_font;
   HFONT hfont;
@@ -508,19 +508,19 @@ populate_log_font (LOGFONTW  *lf,
   lf->lfCharSet = DEFAULT_CHARSET;
 
   hb_face_t *face = font->face;
-  hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+  hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
 
   memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName));
 
   return true;
 }
 
-hb_uniscribe_shaper_font_data_t *
+hb_uniscribe_font_data_t *
 _hb_uniscribe_shaper_font_data_create (hb_font_t *font)
 {
   if (unlikely (!hb_uniscribe_shaper_face_data_ensure (font->face))) return nullptr;
 
-  hb_uniscribe_shaper_font_data_t *data = (hb_uniscribe_shaper_font_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_font_data_t));
+  hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_font_data_t));
   if (unlikely (!data))
     return nullptr;
 
@@ -559,7 +559,7 @@ _hb_uniscribe_shaper_font_data_create (hb_font_t *font)
 }
 
 void
-_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_shaper_font_data_t *data)
+_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_font_data_t *data)
 {
   if (data->hdc)
     ReleaseDC (nullptr, data->hdc);
@@ -574,7 +574,7 @@ LOGFONTW *
 hb_uniscribe_font_get_logfontw (hb_font_t *font)
 {
   if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
-  hb_uniscribe_shaper_font_data_t *font_data =  HB_SHAPER_DATA_GET (font);
+  hb_uniscribe_font_data_t *font_data =  HB_SHAPER_DATA_GET (font);
   return &font_data->log_font;
 }
 
@@ -582,7 +582,7 @@ HFONT
 hb_uniscribe_font_get_hfont (hb_font_t *font)
 {
   if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
-  hb_uniscribe_shaper_font_data_t *font_data =  HB_SHAPER_DATA_GET (font);
+  hb_uniscribe_font_data_t *font_data =  HB_SHAPER_DATA_GET (font);
   return font_data->hfont;
 }
 
@@ -591,20 +591,20 @@ hb_uniscribe_font_get_hfont (hb_font_t *font)
  * shaper shape_plan data
  */
 
-struct hb_uniscribe_shaper_shape_plan_data_t {};
+struct hb_uniscribe_shape_plan_data_t {};
 
-hb_uniscribe_shaper_shape_plan_data_t *
+hb_uniscribe_shape_plan_data_t *
 _hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
 					     const hb_feature_t *user_features HB_UNUSED,
 					     unsigned int        num_user_features HB_UNUSED,
 					     const int          *coords HB_UNUSED,
 					     unsigned int        num_coords HB_UNUSED)
 {
-  return (hb_uniscribe_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  return (hb_uniscribe_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
-_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shaper_shape_plan_data_t *data HB_UNUSED)
+_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shape_plan_data_t *data HB_UNUSED)
 {
 }
 
@@ -622,8 +622,8 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
 		     unsigned int        num_features)
 {
   hb_face_t *face = font->face;
-  hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
-  hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+  hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+  hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
   hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs;
 
   /*
commit 1a624c6e06763a8a61bc686d2d44272d4ef50d4a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Aug 1 17:53:30 2018 -0700

    Add comment re (our only) race condition

diff --git a/src/hb-shaper-private.hh b/src/hb-shaper-private.hh
index 4bd36b5b..a7ca36c6 100644
--- a/src/hb-shaper-private.hh
+++ b/src/hb-shaper-private.hh
@@ -89,7 +89,13 @@ HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
     /* Note that evaluating condition above can be dangerous if another thread \
      * got here first and destructed data.  That's, as always, bad use pattern. \
      * If you modify the font (change font size), other threads must not be \
-     * using it at the same time. */ \
+     * using it at the same time.  However, since this check is delayed to \
+     * when one actually tries to shape something, this is a XXX race condition \
+     * (and the only know we have that I know of) right now.  Ie. you modify the \
+     * font size in one thread, then (supposedly safely) try to use it from two \
+     * or more threads and BOOM!  I'm not sure how to fix this.  We want RCU. \
+     * Maybe when it doesn't matter when we finally implement AAT shaping, as
+     * this (condition) is currently only used by hb-coretext. */ \
     /* Drop and recreate. */ \
     /* If someone dropped it in the mean time, throw it away and don't touch it. \
      * Otherwise, destruct it. */ \


More information about the HarfBuzz mailing list