From f00ab2a33ab34ba64f38cbbe65830c770a3e071e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 2 May 2016 10:24:00 +0200 Subject: [PATCH] [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. --- src/hb-ot-font.cc | 45 +++++++++++++++++- test/shaping/Makefile.am | 1 + ...f276fc886ea502a03b9b0e5c8b547d5dc2b61c.ttf | Bin 0 -> 784 bytes test/shaping/tests/fallback-positioning.test | 2 + 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 test/shaping/fonts/sha1sum/7ef276fc886ea502a03b9b0e5c8b547d5dc2b61c.ttf create mode 100644 test/shaping/tests/fallback-positioning.test 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 0000000000000000000000000000000000000000..fb4534abf4ace39fa4476a19b146bed50921e99e GIT binary patch literal 784 zcmZXSK}b|V7{~uJ^WM6vmPC@!A(xaW5(}3?%&;WrvL%_pLZLmMyK3yV%kCO0bWps6 zV0B0;3Cuc09qiO05TOp;B2)2FhY}%-Rgj>=zIpxMx*^oO_suuIneY4lGw%%qfO3pL zA=q*GSkvUk!UsV7=InJlVWlvk-T^W~KGz=~j=ineIKuHO+U!8o>MN}8Uts(l^2q^C zRBE5ci{$!&L^ikUsm_w;$<^_sZ6S_H@@;Zu!pfyk4{C{P_p2huDW6dXILRDse4N z;{qZ@VnlCS_o1Gu)?cXb7h~UV?%}S1&*8c5LW8puu>Bcg0J69Y;ZULq?S>DH@-D^z zXVj}z7T1*w8!a@rZ2|iqZEsh~cqH!A8|IW5;+bl