[shape-plan] Cache shape plans with variations based on variation indices
This commit is contained in:
parent
8284cb9fb3
commit
cc8428756a
|
@ -51,9 +51,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_aat_map_builder_t::compile (hb_aat_map_t &m,
|
hb_aat_map_builder_t::compile (hb_aat_map_t &m)
|
||||||
const int *coords HB_UNUSED,
|
|
||||||
unsigned int num_coords HB_UNUSED)
|
|
||||||
{
|
{
|
||||||
/* Sort features and merge duplicates */
|
/* Sort features and merge duplicates */
|
||||||
if (features.len)
|
if (features.len)
|
||||||
|
|
|
@ -60,9 +60,7 @@ struct hb_aat_map_builder_t
|
||||||
|
|
||||||
HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1);
|
HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1);
|
||||||
|
|
||||||
HB_INTERNAL void compile (hb_aat_map_t &m,
|
HB_INTERNAL void compile (hb_aat_map_t &m);
|
||||||
const int *coords,
|
|
||||||
unsigned int num_coords);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct feature_info_t
|
struct feature_info_t
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hb-ot-map.hh"
|
#include "hb-ot-map.hh"
|
||||||
|
#include "hb-ot-shape.hh"
|
||||||
#include "hb-ot-layout.hh"
|
#include "hb-ot-layout.hh"
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,8 +144,7 @@ void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::paus
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
||||||
const int *coords,
|
const hb_ot_shape_plan_key_t &key)
|
||||||
unsigned int num_coords)
|
|
||||||
{
|
{
|
||||||
static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
|
static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
|
||||||
unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1;
|
unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1;
|
||||||
|
@ -282,13 +281,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
||||||
{
|
{
|
||||||
/* Collect lookup indices for features */
|
/* Collect lookup indices for features */
|
||||||
|
|
||||||
unsigned int variations_index;
|
|
||||||
hb_ot_layout_table_find_feature_variations (face,
|
|
||||||
table_tags[table_index],
|
|
||||||
coords,
|
|
||||||
num_coords,
|
|
||||||
&variations_index);
|
|
||||||
|
|
||||||
unsigned int stage_index = 0;
|
unsigned int stage_index = 0;
|
||||||
unsigned int last_num_lookups = 0;
|
unsigned int last_num_lookups = 0;
|
||||||
for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
|
for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
|
||||||
|
@ -297,14 +289,14 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
||||||
required_feature_stage[table_index] == stage)
|
required_feature_stage[table_index] == stage)
|
||||||
add_lookups (m, table_index,
|
add_lookups (m, table_index,
|
||||||
required_feature_index[table_index],
|
required_feature_index[table_index],
|
||||||
variations_index,
|
key.variations_index[table_index],
|
||||||
global_bit_mask);
|
global_bit_mask);
|
||||||
|
|
||||||
for (unsigned i = 0; i < m.features.len; i++)
|
for (unsigned i = 0; i < m.features.len; i++)
|
||||||
if (m.features[i].stage[table_index] == stage)
|
if (m.features[i].stage[table_index] == stage)
|
||||||
add_lookups (m, table_index,
|
add_lookups (m, table_index,
|
||||||
m.features[i].index[table_index],
|
m.features[i].index[table_index],
|
||||||
variations_index,
|
key.variations_index[table_index],
|
||||||
m.features[i].mask,
|
m.features[i].mask,
|
||||||
m.features[i].auto_zwnj,
|
m.features[i].auto_zwnj,
|
||||||
m.features[i].auto_zwj,
|
m.features[i].auto_zwj,
|
||||||
|
|
|
@ -188,6 +188,7 @@ struct hb_ot_map_feature_t
|
||||||
hb_ot_map_feature_flags_t flags;
|
hb_ot_map_feature_flags_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hb_ot_shape_plan_key_t;
|
||||||
|
|
||||||
struct hb_ot_map_builder_t
|
struct hb_ot_map_builder_t
|
||||||
{
|
{
|
||||||
|
@ -219,8 +220,7 @@ struct hb_ot_map_builder_t
|
||||||
{ add_pause (1, pause_func); }
|
{ add_pause (1, pause_func); }
|
||||||
|
|
||||||
HB_INTERNAL void compile (hb_ot_map_t &m,
|
HB_INTERNAL void compile (hb_ot_map_t &m,
|
||||||
const int *coords,
|
const hb_ot_shape_plan_key_t &key);
|
||||||
unsigned int num_coords);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -80,14 +80,13 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
|
hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
|
||||||
const int *coords,
|
const hb_ot_shape_plan_key_t &key)
|
||||||
unsigned int num_coords)
|
|
||||||
{
|
{
|
||||||
plan.props = props;
|
plan.props = props;
|
||||||
plan.shaper = shaper;
|
plan.shaper = shaper;
|
||||||
map.compile (plan.map, coords, num_coords);
|
map.compile (plan.map, key);
|
||||||
if (apply_morx)
|
if (apply_morx)
|
||||||
aat_map.compile (plan.aat_map, coords, num_coords);
|
aat_map.compile (plan.aat_map);
|
||||||
|
|
||||||
plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
|
plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
|
||||||
plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
|
plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
|
||||||
|
@ -160,9 +159,7 @@ hb_ot_shape_plan_t::init0 (hb_face_t *face,
|
||||||
key->user_features,
|
key->user_features,
|
||||||
key->num_user_features);
|
key->num_user_features);
|
||||||
|
|
||||||
planner.compile (*this,
|
planner.compile (*this, key->ot);
|
||||||
key->coords,
|
|
||||||
key->num_coords);
|
|
||||||
|
|
||||||
if (shaper->data_create)
|
if (shaper->data_create)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,29 @@
|
||||||
#include "hb-aat-map.hh"
|
#include "hb-aat-map.hh"
|
||||||
|
|
||||||
|
|
||||||
|
struct hb_ot_shape_plan_key_t
|
||||||
|
{
|
||||||
|
unsigned int variations_index[2];
|
||||||
|
|
||||||
|
inline void init (hb_face_t *face,
|
||||||
|
const int *coords,
|
||||||
|
unsigned int num_coords)
|
||||||
|
{
|
||||||
|
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||||
|
hb_ot_layout_table_find_feature_variations (face,
|
||||||
|
table_tags[table_index],
|
||||||
|
coords,
|
||||||
|
num_coords,
|
||||||
|
&variations_index[table_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool equal (const hb_ot_shape_plan_key_t *other)
|
||||||
|
{
|
||||||
|
return 0 == memcmp (this, other, sizeof (*this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct hb_shape_plan_key_t;
|
struct hb_shape_plan_key_t;
|
||||||
|
|
||||||
struct hb_ot_shape_plan_t
|
struct hb_ot_shape_plan_t
|
||||||
|
@ -96,8 +119,7 @@ struct hb_ot_shape_planner_t
|
||||||
const hb_segment_properties_t *props);
|
const hb_segment_properties_t *props);
|
||||||
|
|
||||||
HB_INTERNAL void compile (hb_ot_shape_plan_t &plan,
|
HB_INTERNAL void compile (hb_ot_shape_plan_t &plan,
|
||||||
const int *coords,
|
const hb_ot_shape_plan_key_t &key);
|
||||||
unsigned int num_coords);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,28 +54,22 @@ hb_shape_plan_key_t::init (bool copy,
|
||||||
const hb_segment_properties_t *props,
|
const hb_segment_properties_t *props,
|
||||||
const hb_feature_t *user_features,
|
const hb_feature_t *user_features,
|
||||||
unsigned int num_user_features,
|
unsigned int num_user_features,
|
||||||
const int *orig_coords,
|
const int *coords,
|
||||||
unsigned int num_coords,
|
unsigned int num_coords,
|
||||||
const char * const *shaper_list)
|
const char * const *shaper_list)
|
||||||
{
|
{
|
||||||
hb_feature_t *features = nullptr;
|
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))))
|
if (copy && num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t))))
|
||||||
goto bail;
|
goto bail;
|
||||||
if (copy && num_coords && !(coords = (int *) calloc (num_coords, sizeof (int))))
|
|
||||||
goto bail;
|
|
||||||
|
|
||||||
this->props = *props;
|
this->props = *props;
|
||||||
this->num_user_features = num_user_features;
|
this->num_user_features = num_user_features;
|
||||||
this->user_features = copy ? features : user_features;
|
this->user_features = copy ? features : user_features;
|
||||||
if (copy && num_user_features)
|
if (copy && num_user_features)
|
||||||
memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
|
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_func = nullptr;
|
||||||
this->shaper_name = nullptr;
|
this->shaper_name = nullptr;
|
||||||
|
this->ot.init (face, coords, num_coords);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Choose shaper.
|
* Choose shaper.
|
||||||
|
@ -117,7 +111,6 @@ hb_shape_plan_key_t::init (bool copy,
|
||||||
#undef HB_SHAPER_PLAN
|
#undef HB_SHAPER_PLAN
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
::free (coords);
|
|
||||||
::free (features);
|
::free (features);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -378,38 +371,6 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
|
||||||
* Caching
|
* Caching
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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 (key1->num_user_features != key2->num_user_features)
|
|
||||||
return false;
|
|
||||||
return 0 == hb_memcmp(key1->user_features,
|
|
||||||
key2->user_features,
|
|
||||||
key1->num_user_features * sizeof (key1->user_features[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hb_shape_plan_key_coords_equal (const hb_shape_plan_key_t *key2,
|
|
||||||
const hb_shape_plan_key_t *key1)
|
|
||||||
{
|
|
||||||
if (key1->num_coords != key2->num_coords)
|
|
||||||
return false;
|
|
||||||
return 0 == hb_memcmp(key1->coords,
|
|
||||||
key2->coords,
|
|
||||||
key1->num_coords * sizeof (key1->coords[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (&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 bool
|
static inline bool
|
||||||
_has_non_global_user_features (const hb_feature_t *user_features,
|
_has_non_global_user_features (const hb_feature_t *user_features,
|
||||||
unsigned int num_user_features)
|
unsigned int num_user_features)
|
||||||
|
@ -425,21 +386,13 @@ _has_non_global_user_features (const hb_feature_t *user_features,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
|
||||||
_has_coords (const int *coords,
|
|
||||||
unsigned int num_coords)
|
|
||||||
{
|
|
||||||
return num_coords;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
_dont_cache (const hb_feature_t *user_features,
|
_dont_cache (const hb_feature_t *user_features,
|
||||||
unsigned int num_user_features,
|
unsigned int num_user_features,
|
||||||
const int *coords,
|
const int *coords,
|
||||||
unsigned int num_coords)
|
unsigned int num_coords)
|
||||||
{
|
{
|
||||||
return _has_non_global_user_features (user_features, num_user_features) ||
|
return _has_non_global_user_features (user_features, num_user_features);
|
||||||
_has_coords (coords, num_coords);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -505,7 +458,7 @@ retry:
|
||||||
return hb_shape_plan_get_empty ();
|
return hb_shape_plan_get_empty ();
|
||||||
|
|
||||||
for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
|
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))
|
if (node->shape_plan->key.equal (&key))
|
||||||
{
|
{
|
||||||
DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
|
DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
|
||||||
return hb_shape_plan_reference (node->shape_plan);
|
return hb_shape_plan_reference (node->shape_plan);
|
||||||
|
|
|
@ -39,8 +39,7 @@ struct hb_shape_plan_key_t
|
||||||
const hb_feature_t *user_features;
|
const hb_feature_t *user_features;
|
||||||
unsigned int num_user_features;
|
unsigned int num_user_features;
|
||||||
|
|
||||||
const int *coords;
|
hb_ot_shape_plan_key_t ot;
|
||||||
unsigned int num_coords;
|
|
||||||
|
|
||||||
hb_shape_func_t *shaper_func;
|
hb_shape_func_t *shaper_func;
|
||||||
const char *shaper_name;
|
const char *shaper_name;
|
||||||
|
@ -50,14 +49,30 @@ struct hb_shape_plan_key_t
|
||||||
const hb_segment_properties_t *props,
|
const hb_segment_properties_t *props,
|
||||||
const hb_feature_t *user_features,
|
const hb_feature_t *user_features,
|
||||||
unsigned int num_user_features,
|
unsigned int num_user_features,
|
||||||
const int *orig_coords,
|
const int *coords,
|
||||||
unsigned int num_coords,
|
unsigned int num_coords,
|
||||||
const char * const *shaper_list);
|
const char * const *shaper_list);
|
||||||
|
|
||||||
HB_INTERNAL inline void free (void)
|
HB_INTERNAL inline void free (void)
|
||||||
{
|
{
|
||||||
::free ((void *) user_features);
|
::free ((void *) user_features);
|
||||||
::free ((void *) coords);
|
}
|
||||||
|
|
||||||
|
inline bool user_features_match (const hb_shape_plan_key_t *other)
|
||||||
|
{
|
||||||
|
/* TODO Implement non-exact matching. */
|
||||||
|
if (this->num_user_features != other->num_user_features)
|
||||||
|
return false;
|
||||||
|
return 0 == hb_memcmp(this->user_features, other->user_features,
|
||||||
|
this->num_user_features * sizeof (this->user_features[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool equal (const hb_shape_plan_key_t *other)
|
||||||
|
{
|
||||||
|
return hb_segment_properties_equal (&this->props, &other->props) &&
|
||||||
|
this->user_features_match (other) &&
|
||||||
|
this->ot.equal (&other->ot) &&
|
||||||
|
this->shaper_func == other->shaper_func;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue