src/hb-dsalgs.hh | 17 +- src/hb-set.hh | 2 src/hb-shape-plan.cc | 328 ++++++++++++++++++++++----------------------------- src/hb-shape-plan.hh | 39 ++++-- src/hb-shape.cc | 2 src/hb-shaper.cc | 16 +- src/hb-shaper.hh | 4 7 files changed, 199 insertions(+), 209 deletions(-)
New commits: commit 7ac03f88a22325fb4d6b77ee7694ad11f6a99bcb Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 12 17:50:30 2018 -0500 [shape-plan] Minor diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index ecef784a..4c3ae062 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -303,6 +303,22 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, return hb_object_get_user_data (shape_plan, key); } +/** + * hb_shape_plan_get_shaper: + * @shape_plan: a shape plan. + * + * + * + * Return value: (transfer none): + * + * Since: 0.9.7 + **/ +const char * +hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) +{ + return shape_plan->key.shaper_name; +} + /** * hb_shape_plan_execute: @@ -520,19 +536,3 @@ retry: return hb_shape_plan_reference (shape_plan); } - -/** - * hb_shape_plan_get_shaper: - * @shape_plan: a shape plan. - * - * - * - * Return value: (transfer none): - * - * Since: 0.9.7 - **/ -const char * -hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) -{ - return shape_plan->key.shaper_name; -} commit c7be933439af1bc8251b2b19df75b42bd0f3bdb5 Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 12 17:49:15 2018 -0500 [shape-plan] Refactor some more diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 8b1dbd4e..ecef784a 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -44,22 +44,50 @@ **/ -static void -hb_shape_plan_key_choose_shaper (hb_shape_plan_key_t *key, - hb_face_t *face, - const hb_feature_t *user_features, - unsigned int num_user_features, - const int *coords, - unsigned int num_coords, - const char * const *shaper_list) +/* + * hb_shape_plan_key_t + */ + +bool +hb_shape_plan_key_t::init (bool copy, + hb_face_t *face, + const hb_segment_properties_t *props, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *orig_coords, + unsigned int num_coords, + const char * const *shaper_list) { + hb_feature_t *features = nullptr; + int *coords = nullptr; + if (copy && num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t)))) + goto bail; + if (copy && num_coords && !(coords = (int *) calloc (num_coords, sizeof (int)))) + goto bail; + + this->props = *props; + this->num_user_features = num_user_features; + this->user_features = copy ? features : user_features; + if (copy && num_user_features) + memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); + this->num_coords = num_coords; + this->coords = copy ? coords : orig_coords; + if (copy && num_coords) + memcpy (coords, orig_coords, num_coords * sizeof (int)); + this->shaper_func = nullptr; + this->shaper_name = nullptr; + + /* + * Choose shaper. + */ + #define HB_SHAPER_PLAN(shaper) \ HB_STMT_START { \ if (hb_##shaper##_shaper_face_data_ensure (face)) \ { \ - key->shaper_func = _hb_##shaper##_shape; \ - key->shaper_name = #shaper; \ - return; \ + this->shaper_func = _hb_##shaper##_shape; \ + this->shaper_name = #shaper; \ + return true; \ } \ } HB_STMT_END @@ -74,18 +102,24 @@ hb_shape_plan_key_choose_shaper (hb_shape_plan_key_t *key, #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT } - - const hb_shaper_pair_static_t *shapers = _hb_shapers_get (); - for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) - if (false) - ; + else + { + const hb_shaper_pair_static_t *shapers = _hb_shapers_get (); + for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) + if (false) + ; #define HB_SHAPER_IMPLEMENT(shaper) \ - else if (shapers[i].func == _hb_##shaper##_shape) \ - HB_SHAPER_PLAN (shaper); + else if (shapers[i].func == _hb_##shaper##_shape) \ + HB_SHAPER_PLAN (shaper); #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT - + } #undef HB_SHAPER_PLAN + +bail: + ::free (coords); + ::free (features); + return false; } @@ -126,7 +160,7 @@ hb_shape_plan_create2 (hb_face_t *face, const hb_segment_properties_t *props, const hb_feature_t *user_features, unsigned int num_user_features, - const int *orig_coords, + const int *coords, unsigned int num_coords, const char * const *shaper_list) { @@ -140,16 +174,9 @@ hb_shape_plan_create2 (hb_face_t *face, assert (props->direction != HB_DIRECTION_INVALID); hb_shape_plan_t *shape_plan; - hb_feature_t *features = nullptr; - int *coords = nullptr; if (unlikely (!props)) goto bail; - if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t)))) - goto bail; - if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int)))) - goto bail; - if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) goto bail; @@ -158,37 +185,30 @@ hb_shape_plan_create2 (hb_face_t *face, hb_face_make_immutable (face); shape_plan->face_unsafe = face; - { - hb_shape_plan_key_t *key = &shape_plan->key; - key->props = *props; - key->num_user_features = num_user_features; - key->user_features = features; - if (num_user_features) - memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); - key->num_coords = num_coords; - key->coords = coords; - if (num_coords) - memcpy (coords, orig_coords, num_coords * sizeof (int)); - hb_shape_plan_key_choose_shaper (key, - face, - user_features, num_user_features, - coords, num_coords, - shaper_list); - } - + if (unlikely (!shape_plan->key.init (true, + face, + props, + user_features, + num_user_features, + coords, + num_coords, + shaper_list))) + goto bail2; if (unlikely (!shape_plan->ot.init0 (face, props, user_features, num_user_features, coords, num_coords))) - goto bail; + goto bail3; return shape_plan; +bail3: + shape_plan->key.free (); +bail2: + free (shape_plan); bail: - free (coords); - free (features); return hb_shape_plan_get_empty (); } @@ -237,10 +257,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) if (!hb_object_destroy (shape_plan)) return; shape_plan->ot.fini (); - - free ((void *) shape_plan->key.user_features); - free ((void *) shape_plan->key.coords); - + shape_plan->key.free (); free (shape_plan); } @@ -347,7 +364,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, /* - * caching + * Caching */ static inline bool @@ -453,20 +470,16 @@ hb_shape_plan_create_cached2 (hb_face_t *face, num_user_features, shaper_list); - hb_shape_plan_key_t key = - { - *props, - user_features, - num_user_features, - coords, - num_coords, - nullptr - }; - hb_shape_plan_key_choose_shaper (&key, - face, - user_features, num_user_features, - coords, num_coords, - shaper_list); + hb_shape_plan_key_t key; + if (!key.init (false, + face, + props, + user_features, + num_user_features, + coords, + num_coords, + shaper_list)) + return hb_shape_plan_get_empty (); retry: hb_face_t::plan_node_t *cached_plan_nodes = face->shape_plans; diff --git a/src/hb-shape-plan.hh b/src/hb-shape-plan.hh index 98688f54..8b34fa0a 100644 --- a/src/hb-shape-plan.hh +++ b/src/hb-shape-plan.hh @@ -44,6 +44,21 @@ struct hb_shape_plan_key_t hb_shape_func_t *shaper_func; const char *shaper_name; + + HB_INTERNAL inline bool init (bool copy, + hb_face_t *face, + const hb_segment_properties_t *props, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *orig_coords, + unsigned int num_coords, + const char * const *shaper_list); + + HB_INTERNAL inline void free (void) + { + ::free ((void *) user_features); + ::free ((void *) coords); + } }; struct hb_shape_plan_t commit fc27777833e052dab91ca5777802e6c4e956deb4 Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 12 17:27:34 2018 -0500 [shape-plan] Refactor more diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 186ae88b..8b1dbd4e 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -382,12 +382,15 @@ hb_shape_plan_key_equal (const hb_shape_plan_key_t *key1, key1->shaper_func == key2->shaper_func; } -static inline hb_bool_t -hb_non_global_user_features_present (const hb_feature_t *user_features, - unsigned int num_user_features) +static inline bool +hb_shape_plan_key_has_non_global_user_features (const hb_shape_plan_key_t *key) { - while (num_user_features) { - if (user_features->start != 0 || user_features->end != (unsigned int) -1) + unsigned int num_user_features = key->num_user_features; + const hb_feature_t *user_features = key->user_features; + while (num_user_features) + { + if (user_features->start != HB_FEATURE_GLOBAL_START || + user_features->end != HB_FEATURE_GLOBAL_END) return true; num_user_features--; user_features++; @@ -395,11 +398,17 @@ hb_non_global_user_features_present (const hb_feature_t *user_features, return false; } -static inline hb_bool_t -hb_coords_present (const int *coords HB_UNUSED, - unsigned int num_coords) +static inline bool +hb_shape_plan_key_has_coords (const hb_shape_plan_key_t *key) { - return num_coords != 0; + return key->num_coords; +} + +static inline bool +hb_shape_plan_key_dont_cache (const hb_shape_plan_key_t *key) +{ + return hb_shape_plan_key_has_non_global_user_features (key) || + hb_shape_plan_key_has_coords (key); } /** @@ -462,8 +471,10 @@ hb_shape_plan_create_cached2 (hb_face_t *face, retry: hb_face_t::plan_node_t *cached_plan_nodes = face->shape_plans; - /* Don't look for plan in the cache if there were variation coordinates XXX Fix me. */ - if (!hb_coords_present (coords, num_coords)) + bool dont_cache = hb_shape_plan_key_dont_cache (&key) || + hb_object_is_inert (face); + + if (!dont_cache) for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next) if (hb_shape_plan_key_equal (&node->shape_plan->key, &key)) { @@ -471,21 +482,12 @@ retry: return hb_shape_plan_reference (node->shape_plan); } - /* Not found. */ hb_shape_plan_t *shape_plan = hb_shape_plan_create2 (face, props, user_features, num_user_features, coords, num_coords, shaper_list); - /* Don't add to the cache if face is inert. */ - if (unlikely (hb_object_is_inert (face))) - return shape_plan; - - /* Don't add the plan to the cache if there were user features with non-global ranges */ - if (hb_non_global_user_features_present (user_features, num_user_features)) - return shape_plan; - /* Don't add the plan to the cache if there were variation coordinates XXX Fix me. */ - if (hb_coords_present (coords, num_coords)) + if (dont_cache) return shape_plan; hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t)); commit 566612295b7c9bc003e9f1723f2491113724b788 Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 12 17:19:45 2018 -0500 [shape-plan] Turn hb_shape_plan_proposal_t into hb_shape_plan_key_t And include it in hb_shape_plan_t itself. diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index a2467101..186ae88b 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -45,41 +45,26 @@ static void -hb_shape_plan_choose_shaper (hb_shape_plan_t *shape_plan, - const hb_feature_t *user_features, - unsigned int num_user_features, - const int *coords, - unsigned int num_coords, - const char * const *shaper_list) +hb_shape_plan_key_choose_shaper (hb_shape_plan_key_t *key, + hb_face_t *face, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *coords, + unsigned int num_coords, + const char * const *shaper_list) { - DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, - "num_features=%d num_coords=%d shaper_list=%p", - num_user_features, - num_coords, - shaper_list); - - const hb_shaper_pair_static_t *shapers = _hb_shapers_get (); - #define HB_SHAPER_PLAN(shaper) \ HB_STMT_START { \ - if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) \ + if (hb_##shaper##_shaper_face_data_ensure (face)) \ { \ - shape_plan->shaper_func = _hb_##shaper##_shape; \ - shape_plan->shaper_name = #shaper; \ + key->shaper_func = _hb_##shaper##_shape; \ + key->shaper_name = #shaper; \ return; \ } \ } HB_STMT_END - if (likely (!shaper_list)) { - for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) - if (false) - ; -#define HB_SHAPER_IMPLEMENT(shaper) \ - else if (shapers[i].func == _hb_##shaper##_shape) \ - HB_SHAPER_PLAN (shaper); -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - } else { + if (unlikely (shaper_list)) + { for (; *shaper_list; shaper_list++) if (false) ; @@ -90,6 +75,16 @@ hb_shape_plan_choose_shaper (hb_shape_plan_t *shape_plan, #undef HB_SHAPER_IMPLEMENT } + const hb_shaper_pair_static_t *shapers = _hb_shapers_get (); + for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) + if (false) + ; +#define HB_SHAPER_IMPLEMENT(shaper) \ + else if (shapers[i].func == _hb_##shaper##_shape) \ + HB_SHAPER_PLAN (shaper); +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + #undef HB_SHAPER_PLAN } @@ -142,6 +137,8 @@ hb_shape_plan_create2 (hb_face_t *face, num_coords, shaper_list); + assert (props->direction != HB_DIRECTION_INVALID); + hb_shape_plan_t *shape_plan; hb_feature_t *features = nullptr; int *coords = nullptr; @@ -152,30 +149,32 @@ hb_shape_plan_create2 (hb_face_t *face, goto bail; if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int)))) goto bail; + if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) goto bail; - assert (props->direction != HB_DIRECTION_INVALID); - if (unlikely (!face)) face = hb_face_get_empty (); hb_face_make_immutable (face); - shape_plan->face_unsafe = face; - shape_plan->props = *props; - shape_plan->num_user_features = num_user_features; - shape_plan->user_features = features; - if (num_user_features) - memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); - shape_plan->num_coords = num_coords; - shape_plan->coords = coords; - if (num_coords) - memcpy (coords, orig_coords, num_coords * sizeof (int)); - shape_plan->custom_shaper_list = shaper_list; - hb_shape_plan_choose_shaper (shape_plan, - user_features, num_user_features, - coords, num_coords, - shaper_list); + + { + hb_shape_plan_key_t *key = &shape_plan->key; + key->props = *props; + key->num_user_features = num_user_features; + key->user_features = features; + if (num_user_features) + memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); + key->num_coords = num_coords; + key->coords = coords; + if (num_coords) + memcpy (coords, orig_coords, num_coords * sizeof (int)); + hb_shape_plan_key_choose_shaper (key, + face, + user_features, num_user_features, + coords, num_coords, + shaper_list); + } if (unlikely (!shape_plan->ot.init0 (face, props, @@ -239,8 +238,8 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) shape_plan->ot.fini (); - free (shape_plan->user_features); - free (shape_plan->coords); + free ((void *) shape_plan->key.user_features); + free ((void *) shape_plan->key.coords); free (shape_plan); } @@ -312,8 +311,8 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, "num_features=%d shaper_func=%p, shaper_name=%s", num_features, - shape_plan->shaper_func, - shape_plan->shaper_name); + shape_plan->key.shaper_func, + shape_plan->key.shaper_name); if (unlikely (!buffer->len)) return true; @@ -325,7 +324,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, return false; assert (shape_plan->face_unsafe == font->face); - assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props)); + assert (hb_segment_properties_equal (&shape_plan->key.props, &buffer->props)); #define HB_SHAPER_EXECUTE(shaper) \ HB_STMT_START { \ @@ -336,7 +335,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, if (false) ; #define HB_SHAPER_IMPLEMENT(shaper) \ - else if (shape_plan->shaper_func == _hb_##shaper##_shape) \ + else if (shape_plan->key.shaper_func == _hb_##shaper##_shape) \ HB_SHAPER_EXECUTE (shaper); #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT @@ -351,67 +350,36 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, * caching */ -#if 0 -static unsigned int -hb_shape_plan_hash (const hb_shape_plan_t *shape_plan) -{ - return hb_segment_properties_hash (&shape_plan->props) + - shape_plan->custom_shaper_list ? (intptr_t) shape_plan->shaper_func : 0; -} -#endif - -/* User-feature caching is currently somewhat dumb: - * it only finds matches where the feature array is identical, - * not cases where the feature lists would be compatible for plan purposes - * but have different ranges, for example. - */ -struct hb_shape_plan_proposal_t -{ - const hb_segment_properties_t props; - const hb_feature_t *user_features; - unsigned int num_user_features; - const int *coords; - unsigned int num_coords; - bool custom_shaper_list; - hb_shape_func_t *shaper_func; -}; - -static inline hb_bool_t -hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan, - const hb_shape_plan_proposal_t *proposal) +static inline bool +hb_shape_plan_key_user_features_equal (const hb_shape_plan_key_t *key1, + const hb_shape_plan_key_t *key2) { - if (proposal->num_user_features != shape_plan->num_user_features) + if (key1->num_user_features != key2->num_user_features) return false; - for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++) - if (proposal->user_features[i].tag != shape_plan->user_features[i].tag || - proposal->user_features[i].value != shape_plan->user_features[i].value || - proposal->user_features[i].start != shape_plan->user_features[i].start || - proposal->user_features[i].end != shape_plan->user_features[i].end) - return false; - return true; + return 0 == hb_memcmp(key1->user_features, + key2->user_features, + key1->num_user_features * sizeof (key1->user_features[0])); } -static inline hb_bool_t -hb_shape_plan_coords_match (const hb_shape_plan_t *shape_plan, - const hb_shape_plan_proposal_t *proposal) +static inline bool +hb_shape_plan_key_coords_equal (const hb_shape_plan_key_t *key2, + const hb_shape_plan_key_t *key1) { - if (proposal->num_coords != shape_plan->num_coords) + if (key1->num_coords != key2->num_coords) return false; - for (unsigned int i = 0, n = proposal->num_coords; i < n; i++) - if (proposal->coords[i] != shape_plan->coords[i]) - return false; - return true; + return 0 == hb_memcmp(key1->coords, + key2->coords, + key1->num_coords * sizeof (key1->coords[0])); } -static hb_bool_t -hb_shape_plan_matches (const hb_shape_plan_t *shape_plan, - const hb_shape_plan_proposal_t *proposal) +static bool +hb_shape_plan_key_equal (const hb_shape_plan_key_t *key1, + const hb_shape_plan_key_t *key2) { - return hb_segment_properties_equal (&shape_plan->props, &proposal->props) && - hb_shape_plan_user_features_match (shape_plan, proposal) && - hb_shape_plan_coords_match (shape_plan, proposal) && - ((!shape_plan->custom_shaper_list && !proposal->custom_shaper_list) || - (shape_plan->shaper_func == proposal->shaper_func)); + return hb_segment_properties_equal (&key1->props, &key2->props) && + hb_shape_plan_key_user_features_equal (key1, key2) && + hb_shape_plan_key_coords_equal (key1, key2) && + key1->shaper_func == key2->shaper_func; } static inline hb_bool_t @@ -476,38 +444,20 @@ hb_shape_plan_create_cached2 (hb_face_t *face, num_user_features, shaper_list); - hb_shape_plan_proposal_t proposal = + hb_shape_plan_key_t key = { *props, user_features, num_user_features, coords, num_coords, - shaper_list, nullptr }; - - if (shaper_list) - { - /* Choose shaper. Adapted from hb_shape_plan_choose_shaper(). - * Must choose shaper exactly the same way as that function. */ - for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++) - if (false) - ; -#define HB_SHAPER_IMPLEMENT(shaper) \ - else if (0 == strcmp (*shaper_item, #shaper) && \ - hb_##shaper##_shaper_face_data_ensure (face)) \ - { \ - proposal.shaper_func = _hb_##shaper##_shape; \ - break; \ - } -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - - if (unlikely (!proposal.shaper_func)) - return hb_shape_plan_get_empty (); - } - + hb_shape_plan_key_choose_shaper (&key, + face, + user_features, num_user_features, + coords, num_coords, + shaper_list); retry: hb_face_t::plan_node_t *cached_plan_nodes = face->shape_plans; @@ -515,7 +465,7 @@ retry: /* Don't look for plan in the cache if there were variation coordinates XXX Fix me. */ if (!hb_coords_present (coords, num_coords)) for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next) - if (hb_shape_plan_matches (node->shape_plan, &proposal)) + if (hb_shape_plan_key_equal (&node->shape_plan->key, &key)) { DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache"); return hb_shape_plan_reference (node->shape_plan); @@ -569,5 +519,5 @@ retry: const char * hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) { - return shape_plan->shaper_name; + return shape_plan->key.shaper_name; } diff --git a/src/hb-shape-plan.hh b/src/hb-shape-plan.hh index 2849e180..98688f54 100644 --- a/src/hb-shape-plan.hh +++ b/src/hb-shape-plan.hh @@ -32,24 +32,25 @@ #include "hb-ot-shape.hh" -struct hb_shape_plan_t +struct hb_shape_plan_key_t { - hb_object_header_t header; - - hb_face_t *face_unsafe; /* We don't carry a reference to face. */ - - hb_segment_properties_t props; + hb_segment_properties_t props; - hb_feature_t *user_features; - unsigned int num_user_features; + const hb_feature_t *user_features; + unsigned int num_user_features; - int *coords; - unsigned int num_coords; + const int *coords; + unsigned int num_coords; - bool custom_shaper_list; - hb_shape_func_t *shaper_func; - const char *shaper_name; + hb_shape_func_t *shaper_func; + const char *shaper_name; +}; +struct hb_shape_plan_t +{ + hb_object_header_t header; + hb_face_t *face_unsafe; /* We don't carry a reference to face. */ + hb_shape_plan_key_t key; hb_ot_shape_plan_t ot; }; commit af123bd1b814b4fb881ea3d11f1ef0bcced75942 Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 12 16:27:08 2018 -0500 Add hb_memcmp() diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 2540d438..7a207f5d 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -264,6 +264,17 @@ static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } /* A const version, but does not detect erratically being called on pointers. */ #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0]))) + +static inline int +hb_memcmp (const void *a, const void *b, unsigned int len) +{ + /* It's illegal to pass NULL to memcmp(), even if len is zero. + * So, wrap it. + * https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */ + if (!len) return 0; + return memcmp (a, b, len); +} + static inline bool hb_unsigned_mul_overflows (unsigned int count, unsigned int size) { @@ -535,11 +546,7 @@ struct hb_bytes_t { if (len != a.len) return (int) a.len - (int) len; - - if (!len) - return 0; /* glibc's memcmp() declares args non-NULL, and UBSan doesn't like that. :( */ - - return memcmp (a.arrayZ, arrayZ, len); + return hb_memcmp (a.arrayZ, arrayZ, len); } static inline int cmp (const void *pa, const void *pb) { diff --git a/src/hb-set.hh b/src/hb-set.hh index c47f77b7..bc26ed3c 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -90,7 +90,7 @@ struct hb_set_t inline bool is_equal (const page_t *other) const { - return 0 == memcmp (&v, &other->v, sizeof (v)); + return 0 == hb_memcmp (&v, &other->v, sizeof (v)); } inline unsigned int get_population (void) const commit 65456bff37ef61094c35574a35c96f6437fd6015 Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 12 16:15:26 2018 -0500 [shape-plan] Minor diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 4bd50abd..a2467101 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -161,7 +161,6 @@ hb_shape_plan_create2 (hb_face_t *face, face = hb_face_get_empty (); hb_face_make_immutable (face); - shape_plan->custom_shaper_list = shaper_list; shape_plan->face_unsafe = face; shape_plan->props = *props; shape_plan->num_user_features = num_user_features; @@ -172,7 +171,7 @@ hb_shape_plan_create2 (hb_face_t *face, shape_plan->coords = coords; if (num_coords) memcpy (coords, orig_coords, num_coords * sizeof (int)); - + shape_plan->custom_shaper_list = shaper_list; hb_shape_plan_choose_shaper (shape_plan, user_features, num_user_features, coords, num_coords, @@ -369,11 +368,11 @@ hb_shape_plan_hash (const hb_shape_plan_t *shape_plan) struct hb_shape_plan_proposal_t { const hb_segment_properties_t props; - const char * const *shaper_list; const hb_feature_t *user_features; unsigned int num_user_features; const int *coords; unsigned int num_coords; + bool custom_shaper_list; hb_shape_func_t *shaper_func; }; @@ -411,7 +410,7 @@ hb_shape_plan_matches (const hb_shape_plan_t *shape_plan, return hb_segment_properties_equal (&shape_plan->props, &proposal->props) && hb_shape_plan_user_features_match (shape_plan, proposal) && hb_shape_plan_coords_match (shape_plan, proposal) && - ((!shape_plan->custom_shaper_list && !proposal->shaper_list) || + ((!shape_plan->custom_shaper_list && !proposal->custom_shaper_list) || (shape_plan->shaper_func == proposal->shaper_func)); } @@ -477,17 +476,19 @@ hb_shape_plan_create_cached2 (hb_face_t *face, num_user_features, shaper_list); - hb_shape_plan_proposal_t proposal = { + hb_shape_plan_proposal_t proposal = + { *props, - shaper_list, user_features, num_user_features, coords, num_coords, + shaper_list, nullptr }; - if (shaper_list) { + if (shaper_list) + { /* Choose shaper. Adapted from hb_shape_plan_choose_shaper(). * Must choose shaper exactly the same way as that function. */ for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++) diff --git a/src/hb-shape-plan.hh b/src/hb-shape-plan.hh index eaa84fd4..2849e180 100644 --- a/src/hb-shape-plan.hh +++ b/src/hb-shape-plan.hh @@ -37,11 +37,8 @@ struct hb_shape_plan_t hb_object_header_t header; hb_face_t *face_unsafe; /* We don't carry a reference to face. */ - bool custom_shaper_list; - hb_segment_properties_t props; - hb_shape_func_t *shaper_func; - const char *shaper_name; + hb_segment_properties_t props; hb_feature_t *user_features; unsigned int num_user_features; @@ -49,6 +46,10 @@ struct hb_shape_plan_t int *coords; unsigned int num_coords; + bool custom_shaper_list; + hb_shape_func_t *shaper_func; + const char *shaper_name; + hb_ot_shape_plan_t ot; }; commit 1db672a5e903de39f955e70b8814c275ccbe1b5c Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 12 16:05:09 2018 -0500 [shaper] Rename diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 0d51165f..4bd50abd 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -58,7 +58,7 @@ hb_shape_plan_choose_shaper (hb_shape_plan_t *shape_plan, num_coords, shaper_list); - const hb_shaper_pair_t *shapers = _hb_shapers_get (); + const hb_shaper_pair_static_t *shapers = _hb_shapers_get (); #define HB_SHAPER_PLAN(shaper) \ HB_STMT_START { \ diff --git a/src/hb-shape.cc b/src/hb-shape.cc index f98bc6e5..325be0f1 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -63,7 +63,7 @@ static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, if (unlikely (!shaper_list)) return nullptr; - const hb_shaper_pair_t *shapers = _hb_shapers_get (); + const hb_shaper_pair_static_t *shapers = _hb_shapers_get (); unsigned int i; for (i = 0; i < HB_SHAPERS_COUNT; i++) shaper_list[i] = shapers[i].name; diff --git a/src/hb-shaper.cc b/src/hb-shaper.cc index 52418c08..58a5e497 100644 --- a/src/hb-shaper.cc +++ b/src/hb-shaper.cc @@ -29,7 +29,7 @@ #include "hb-machinery.hh" -static const hb_shaper_pair_t all_shapers[] = { +static const hb_shaper_pair_static_t all_shapers[] = { #define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape}, #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT @@ -39,16 +39,16 @@ static const hb_shaper_pair_t all_shapers[] = { static void free_static_shapers (void); #endif -static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_t, +static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_static_t, hb_shapers_lazy_loader_t> { - static inline hb_shaper_pair_t *create (void) + static inline hb_shaper_pair_static_t *create (void) { char *env = getenv ("HB_SHAPER_LIST"); if (!env || !*env) return nullptr; - hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers)); + hb_shaper_pair_static_t *shapers = (hb_shaper_pair_static_t *) calloc (1, sizeof (all_shapers)); if (unlikely (!shapers)) return nullptr; @@ -68,7 +68,7 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_t 0 == strncmp (shapers[j].name, p, end - p)) { /* Reorder this shaper to position i */ - struct hb_shaper_pair_t t = shapers[j]; + struct hb_shaper_pair_static_t t = shapers[j]; memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i)); shapers[i] = t; i++; @@ -86,11 +86,11 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_t return shapers; } - static inline void destroy (const hb_shaper_pair_t *p) + static inline void destroy (const hb_shaper_pair_static_t *p) { free ((void *) p); } - static inline const hb_shaper_pair_t *get_null (void) + static inline const hb_shaper_pair_static_t *get_null (void) { return all_shapers; } @@ -104,7 +104,7 @@ void free_static_shapers (void) } #endif -const hb_shaper_pair_t * +const hb_shaper_pair_static_t * _hb_shapers_get (void) { return static_shapers.get_unconst (); diff --git a/src/hb-shaper.hh b/src/hb-shaper.hh index e3be4119..f29b29f9 100644 --- a/src/hb-shaper.hh +++ b/src/hb-shaper.hh @@ -40,12 +40,12 @@ typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan, #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT -struct hb_shaper_pair_t { +struct hb_shaper_pair_static_t { char name[16]; hb_shape_func_t *func; }; -HB_INTERNAL const hb_shaper_pair_t * +HB_INTERNAL const hb_shaper_pair_static_t * _hb_shapers_get (void); _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
