diff --git a/src/hb-ot-layout-math-table.hh b/src/hb-ot-layout-math-table.hh index f4ecf3f0e..7b3c0c7d2 100644 --- a/src/hb-ot-layout-math-table.hh +++ b/src/hb-ot-layout-math-table.hh @@ -38,18 +38,18 @@ namespace OT { struct MATH { - static const hb_tag_t tableTag = HB_OT_TAG_MATH; + static const hb_tag_t tableTag = HB_OT_TAG_MATH; inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && - likely (version.major == 1)); + likely (version.major == 1)); } protected: - FixedVersion<>version; /* Version of the MATH table - initially set to 0x00010000u */ + FixedVersion<>version; /* Version of the MATH table + * initially set to 0x00010000u */ public: DEFINE_SIZE_STATIC (4); }; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 24d290c5c..e6316e192 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -61,7 +61,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 rarer so we only try and load it in _get_math + /* The MATH table is rarely used, so only try and load it in _get_math. */ layout->math_blob = NULL; layout->math = NULL; @@ -182,8 +182,7 @@ _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); - - if (layout->math_blob) hb_blob_destroy (layout->math_blob); + hb_blob_destroy (layout->math_blob); free (layout); } @@ -213,13 +212,22 @@ _get_math (hb_face_t *face) hb_ot_layout_t * layout = hb_ot_layout_from_face (face); - // If the MATH table is not loaded yet, do it now. - if (!layout->math_blob) { - layout->math_blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_MATH)); - layout->math = OT::Sanitizer::lock_instance (layout->math_blob); +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 *layout->math; + return *math; } @@ -1213,8 +1221,9 @@ hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, apply_string (c, lookup, accel); } + /* - * OT::MATH + * MATH */ /** @@ -1228,7 +1237,7 @@ hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, * * Return value: #TRUE if face has a MATH table and #FALSE otherwise * - * Since: ???? + * Since: 1.4 **/ hb_bool_t hb_ot_layout_has_math_data (hb_face_t *face) diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 7cbd794ce..e78679051 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -304,6 +304,8 @@ hb_ot_layout_get_size_params (hb_face_t *face, HB_EXTERN hb_bool_t hb_ot_layout_has_math_data (hb_face_t *face); + + HB_END_DECLS #endif /* HB_OT_LAYOUT_H */ diff --git a/test/api/Makefile.am b/test/api/Makefile.am index dae8700c3..322cd7d2a 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -52,10 +52,8 @@ if HAVE_FREETYPE TEST_PROGS += \ test-ot-layout-math \ $(NULL) -test_ot_layout_math_LDADD = $(LDADD) -test_ot_layout_math_CPPFLAGS = $(AM_CPPFLAGS) -test_ot_layout_math_CPPFLAGS += $(FREETYPE_CFLAGS) -test_ot_layout_math_LDADD += $(FREETYPE_LIBS) +test_ot_layout_math_LDADD = $(LDADD) $(FREETYPE_LIBS) +test_ot_layout_math_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS) endif # HAVE_FREETYPE endif # HAVE_OT diff --git a/test/api/test-ot-layout-math.c b/test/api/test-ot-layout-math.c index cf7d76c16..3e8fec6e0 100644 --- a/test/api/test-ot-layout-math.c +++ b/test/api/test-ot-layout-math.c @@ -37,16 +37,16 @@ static FT_Face ft_face; static hb_font_t *hb_font; static hb_face_t *hb_face; -static void -initFreeType() +static inline void +initFreeType (void) { FT_Error ft_error; if ((ft_error = FT_Init_FreeType (&ft_library))) abort(); } -static void -cleanupFreeType() +static inline void +cleanupFreeType (void) { FT_Done_FreeType (ft_library); } @@ -57,15 +57,17 @@ openFont(const char* fontFile) FT_Error ft_error; if ((ft_error = FT_New_Face (ft_library, fontFile, 0, &ft_face))) abort(); - unsigned int fontSize = 1000; + +#define fontSize 1000 + if ((ft_error = FT_Set_Char_Size (ft_face, fontSize, fontSize, 0, 0))) abort(); hb_font = hb_ft_font_create (ft_face, NULL); hb_face = hb_ft_face_create_cached(ft_face); } -static void -closeFont() +static inline void +closeFont (void) { hb_font_destroy (hb_font); FT_Done_Face (ft_face);