[HarfBuzz] harfbuzz: Branch 'master' - 7 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Mon Nov 12 22:55:34 UTC 2018
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 <behdad at behdad.org>
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 <behdad at behdad.org>
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 <behdad at behdad.org>
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 <behdad at behdad.org>
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 <behdad at behdad.org>
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 <behdad at behdad.org>
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 <behdad at behdad.org>
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);
More information about the HarfBuzz
mailing list