diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 23ac41a2a..8b62bb15a 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -300,13 +300,54 @@ struct hb_ot_face_cmap_accelerator_t } }; +template +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(&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 glyf; }; @@ -390,7 +431,7 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, 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 6320b02db..b3b6300f5 100644 --- a/test/shaping/Makefile.am +++ b/test/shaping/Makefile.am @@ -47,6 +47,7 @@ TESTS = \ 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 000000000..fb4534abf Binary files /dev/null and b/test/shaping/fonts/sha1sum/7ef276fc886ea502a03b9b0e5c8b547d5dc2b61c.ttf differ diff --git a/test/shaping/tests/fallback-positioning.test b/test/shaping/tests/fallback-positioning.test new file mode 100644 index 000000000..499db7d80 --- /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]