diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 6ee4fae9e..e0d5fae6f 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -1064,6 +1064,7 @@ struct SortedArrayOf : ArrayOf /* Lazy struct and blob loaders. */ +/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */ template struct hb_lazy_loader_t { @@ -1082,7 +1083,7 @@ struct hb_lazy_loader_t } } - inline const T* operator-> (void) const + inline const T* get (void) const { retry: T *p = (T *) hb_atomic_ptr_get (&instance); @@ -1103,11 +1104,17 @@ struct hb_lazy_loader_t return p; } + inline const T* operator-> (void) const + { + return get (); + } + private: hb_face_t *face; T *instance; }; +/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */ template struct hb_lazy_table_loader_t { @@ -1123,14 +1130,14 @@ struct hb_lazy_table_loader_t hb_blob_destroy (blob); } - inline const T* operator-> (void) const + inline const T* get (void) const { retry: - T *p = (T *) hb_atomic_ptr_get (&instance); + const T *p = (T *) hb_atomic_ptr_get (&instance); if (unlikely (!p)) { hb_blob_t *blob_ = OT::Sanitizer::sanitize (face->reference_table (T::tableTag)); - p = OT::Sanitizer::lock_instance (blob); + p = OT::Sanitizer::lock_instance (blob_); if (!hb_atomic_ptr_cmpexch (const_cast(&instance), NULL, p)) { hb_blob_destroy (blob_); @@ -1141,10 +1148,15 @@ struct hb_lazy_table_loader_t return p; } + inline const T* operator-> (void) const + { + return get(); + } + private: hb_face_t *face; T *instance; - hb_blob_t *blob; + mutable hb_blob_t *blob; }; diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index a4272de63..1c398e9bd 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -34,6 +34,7 @@ #include "hb-font-private.hh" #include "hb-buffer-private.hh" #include "hb-set-private.hh" +#include "hb-open-type-private.hh" /* Private API corresponding to hb-ot-layout.h: */ @@ -153,12 +154,11 @@ struct hb_ot_layout_t hb_blob_t *gdef_blob; hb_blob_t *gsub_blob; hb_blob_t *gpos_blob; - hb_blob_t *math_blob; const struct OT::GDEF *gdef; const struct OT::GSUB *gsub; const struct OT::GPOS *gpos; - const struct OT::MATH *math; + OT::hb_lazy_table_loader_t math; 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 145ec7638..d1654025e 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -60,9 +60,7 @@ _hb_ot_layout_create (hb_face_t *face) layout->gpos_blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_GPOS)); layout->gpos = OT::Sanitizer::lock_instance (layout->gpos_blob); - /* The MATH table is rarely used, so only try and load it in _get_math. */ - layout->math_blob = NULL; - layout->math = NULL; + layout->math.init (face); { /* @@ -181,7 +179,8 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) hb_blob_destroy (layout->gdef_blob); hb_blob_destroy (layout->gsub_blob); hb_blob_destroy (layout->gpos_blob); - hb_blob_destroy (layout->math_blob); + + layout->math.fini (); free (layout); } diff --git a/src/hb-ot-math.cc b/src/hb-ot-math.cc index 3028cc494..40414ebee 100644 --- a/src/hb-ot-math.cc +++ b/src/hb-ot-math.cc @@ -37,22 +37,7 @@ _get_math (hb_face_t *face) hb_ot_layout_t * layout = hb_ot_layout_from_face (face); -retry: - const OT::MATH *math = (const OT::MATH *) hb_atomic_ptr_get (&layout->math); - - if (unlikely (!math)) - { - hb_blob_t *blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_MATH)); - math = OT::Sanitizer::lock_instance (blob); - if (!hb_atomic_ptr_cmpexch (&layout->math, NULL, math)) - { - hb_blob_destroy (blob); - goto retry; - } - layout->math_blob = blob; - } - - return *math; + return *(layout->math.get ()); } /*