src/hb-ot-layout-gsub-table.hh | 15 +++++++++++++-- src/hb-ot-layout-gsubgpos-private.hh | 20 ++++++++++++++++++++ src/hb-ot-layout.cc | 6 ++++-- src/hb-set-private.hh | 13 +++++++++++++ src/hb-set.cc | 22 ++++++++++++++++++++-- src/hb-set.h | 4 ++++ test/api/test-set.c | 4 ++++ test/api/test-subset-glyf.c | 11 +++++------ 8 files changed, 83 insertions(+), 12 deletions(-)
New commits: commit 11f1f4131b722f0e0338bee222a78110806f5a3d Author: Behdad Esfahbod <beh...@behdad.org> Date: Wed Jun 6 16:46:50 2018 -0700 [set] Add is_subset New API: +hb_set_is_subset() diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh index 50be93b8..ed753e68 100644 --- a/src/hb-set-private.hh +++ b/src/hb-set-private.hh @@ -400,6 +400,19 @@ struct hb_set_t return true; } + inline bool is_subset (const hb_set_t *larger_set) const + { + if (get_population () > larger_set->get_population ()) + return false; + + hb_codepoint_t c = INVALID; + while (next (&c)) + if (!larger_set->has (c)) + return false; + + return true; + } + template <class Op> inline void process (const hb_set_t *other) { diff --git a/src/hb-set.cc b/src/hb-set.cc index b5753222..25027e6c 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -267,11 +267,11 @@ hb_set_del_range (hb_set_t *set, /** * hb_set_is_equal: * @set: a set. - * @other: + * @other: other set. * * * - * Return value: + * Return value: %TRUE if the two sets are equal, %FALSE otherwise. * * Since: 0.9.7 **/ @@ -283,6 +283,24 @@ hb_set_is_equal (const hb_set_t *set, } /** + * hb_set_is_subset: + * @set: a set. + * @larger_set: other set. + * + * + * + * Return value: %TRUE if the @set is a subset of (or equal to) @larger_set, %FALSE otherwise. + * + * Since: 1.8.1 + **/ +hb_bool_t +hb_set_is_subset (const hb_set_t *set, + const hb_set_t *larger_set) +{ + return set->is_subset (larger_set); +} + +/** * hb_set_set: * @set: a set. * @other: diff --git a/src/hb-set.h b/src/hb-set.h index 764d4eba..ed0e05db 100644 --- a/src/hb-set.h +++ b/src/hb-set.h @@ -104,6 +104,10 @@ HB_EXTERN hb_bool_t hb_set_is_equal (const hb_set_t *set, const hb_set_t *other); +HB_EXTERN hb_bool_t +hb_set_is_subset (const hb_set_t *set, + const hb_set_t *larger_set); + HB_EXTERN void hb_set_set (hb_set_t *set, const hb_set_t *other); diff --git a/test/api/test-set.c b/test/api/test-set.c index 15958c57..e6590f45 100644 --- a/test/api/test-set.c +++ b/test/api/test-set.c @@ -146,8 +146,12 @@ test_set_algebra (void) test_empty (s); g_assert (!hb_set_is_equal (s, o)); + g_assert (hb_set_is_subset (s, o)); + g_assert (!hb_set_is_subset (o, s)); hb_set_set (s, o); g_assert (hb_set_is_equal (s, o)); + g_assert (hb_set_is_subset (s, o)); + g_assert (hb_set_is_subset (o, s)); test_not_empty (s); g_assert_cmpint (hb_set_get_population (s), ==, 2); diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c index 4ea2d891..acc6143e 100644 --- a/test/api/test-subset-glyf.c +++ b/test/api/test-subset-glyf.c @@ -178,12 +178,11 @@ test_subset_glyf_strip_hints_invalid (void) hb_set_t *codepoints = hb_set_create(); const hb_codepoint_t text[] = - { - 'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2', - '3', '@', '_', '%', '&', ')', '*', '$', '!' - }; - int i; - for (i = 0; i < sizeof (text) / sizeof (hb_codepoint_t); i++) + { + 'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2', + '3', '@', '_', '%', '&', ')', '*', '$', '!' + }; + for (unsigned int i = 0; i < sizeof (text) / sizeof (hb_codepoint_t); i++) { hb_set_add (codepoints, text[i]); // hb_set_add (codepoints_drop_hints, text[i]); commit 45186b9b8cbffa7b5c8509624fb431a0f79f5130 Author: Garret Rieger <grie...@google.com> Date: Tue Jun 5 17:14:42 2018 -0700 [subset] Add memoization of GSUB lookup closures. diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 6e57195b..34d9d6e9 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<hb_closure_context_t>); + 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 <typename context_t> 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 <typename context_t> inline typename context_t::return_t dispatch (context_t *c) const { return Lookup::dispatch<SubstLookupSubTable> (c); } diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 3cf9d578..b4a9bf19 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 8d1471a3..a7607f62 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<hb_map_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); } /* _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz