From 45186b9b8cbffa7b5c8509624fb431a0f79f5130 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Tue, 5 Jun 2018 17:14:42 -0700 Subject: [PATCH] [subset] Add memoization of GSUB lookup closures. --- src/hb-ot-layout-gsub-table.hh | 15 +++++++++++++-- src/hb-ot-layout-gsubgpos-private.hh | 20 ++++++++++++++++++++ src/hb-ot-layout.cc | 6 ++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 6e57195b3..34d9d6e98 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1156,10 +1156,13 @@ struct SubstLookup : Lookup return_trace (dispatch (c)); } - inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const + inline hb_closure_context_t::return_t closure (hb_closure_context_t *c, unsigned int this_index) const { TRACE_CLOSURE (this); - c->set_recurse_func (dispatch_recurse_func); + if (!c->start_lookup (this_index)) + return_trace (HB_VOID); + + c->set_recurse_func (dispatch_closure_recurse_func); return_trace (dispatch (c)); } @@ -1258,6 +1261,14 @@ struct SubstLookup : Lookup template static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); + static inline hb_closure_context_t::return_t dispatch_closure_recurse_func + (hb_closure_context_t *c, unsigned int lookup_index) + { + if (!c->start_lookup (lookup_index)) + return HB_VOID; + return dispatch_recurse_func (c, lookup_index); + } + template inline typename context_t::return_t dispatch (context_t *c) const { return Lookup::dispatch (c); } diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 3cf9d5782..b4a9bf190 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -32,6 +32,7 @@ #include "hb-private.hh" #include "hb-debug.hh" #include "hb-buffer-private.hh" +#include "hb-map-private.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-set-private.hh" @@ -59,6 +60,20 @@ struct hb_closure_context_t : return HB_VOID; } + bool start_lookup (unsigned int lookup_index) + { + if (is_lookup_done (lookup_index)) + return false; + done_lookups->set (lookup_index, glyphs->get_population ()); + return true; + } + + bool is_lookup_done (unsigned int lookup_index) + { + // Have we visited this lookup with the current set of glyphs? + return done_lookups->get (lookup_index) == glyphs->get_population (); + } + hb_face_t *face; hb_set_t *glyphs; recurse_func_t recurse_func; @@ -67,14 +82,19 @@ struct hb_closure_context_t : hb_closure_context_t (hb_face_t *face_, hb_set_t *glyphs_, + hb_map_t *done_lookups_, unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), + done_lookups (done_lookups_), recurse_func (nullptr), nesting_level_left (nesting_level_left_), debug_depth (0) {} void set_recurse_func (recurse_func_t func) { recurse_func = func; } + + private: + hb_map_t *done_lookups; }; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 8d1471a33..a7607f626 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -44,6 +44,7 @@ #include "hb-ot-color-sbix-table.hh" #include "hb-ot-color-svg-table.hh" #include "hb-ot-name-table.hh" +#include "hb-map-private.hh" hb_ot_layout_t * @@ -943,11 +944,12 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, unsigned int lookup_index, hb_set_t *glyphs) { - OT::hb_closure_context_t c (face, glyphs); + hb_auto_t done_lookups; + OT::hb_closure_context_t c (face, glyphs, &done_lookups); const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index); - l.closure (&c); + l.closure (&c, lookup_index); } /*