[GX] Hook up feature variations Shape-plan caching is not implemented.
diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 507581b..e857dfa 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc
@@ -288,7 +288,9 @@ hb_coretext_shaper_shape_plan_data_t * _hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED) + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) { return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; } @@ -1280,7 +1282,9 @@ hb_coretext_aat_shaper_shape_plan_data_t * _hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED) + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) { return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; }
diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index 76482ac..d26b298 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc
@@ -258,8 +258,10 @@ hb_directwrite_shaper_shape_plan_data_t * _hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, - const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED) + const hb_feature_t *user_features HB_UNUSED, + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) { return (hb_directwrite_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; }
diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc index e2ad240..ac6d4b0 100644 --- a/src/hb-fallback-shape.cc +++ b/src/hb-fallback-shape.cc
@@ -73,7 +73,9 @@ hb_fallback_shaper_shape_plan_data_t * _hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED) + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) { return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; }
diff --git a/src/hb-font.cc b/src/hb-font.cc index f12dfb5..2935c4b 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc
@@ -1253,8 +1253,7 @@ hb_face_destroy (font->face); hb_font_funcs_destroy (font->klass); - if (font->coords) - free (font->coords); + free (font->coords); free (font); } @@ -1561,8 +1560,7 @@ if (unlikely (coords_length && !copy)) return; - if (font->coords) - free (font->coords); + free (font->coords); if (coords_length) memcpy (copy, coords, coords_length * sizeof (coords[0]));
diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index c32318d..a2d90db 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc
@@ -195,7 +195,9 @@ hb_graphite2_shaper_shape_plan_data_t * _hb_graphite2_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED) + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) { return (hb_graphite2_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; }
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index fc5ce66..0395c9c 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh
@@ -176,7 +176,9 @@ inline void add_gpos_pause (hb_ot_map_t::pause_func_t 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, + unsigned int num_coords); inline void finish (void) { feature_infos.finish (); @@ -188,12 +190,13 @@ private: - HB_INTERNAL void add_lookups (hb_ot_map_t &m, - hb_face_t *face, - unsigned int table_index, - unsigned int feature_index, - hb_mask_t mask, - bool auto_zwj); + HB_INTERNAL void add_lookups (hb_ot_map_t &m, + hb_face_t *face, + unsigned int table_index, + unsigned int feature_index, + unsigned int variations_index, + hb_mask_t mask, + bool auto_zwj); struct feature_info_t { hb_tag_t tag;
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 9cd3a44..9b331d5 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc
@@ -83,6 +83,7 @@ hb_face_t *face, unsigned int table_index, unsigned int feature_index, + unsigned int variations_index, hb_mask_t mask, bool auto_zwj) { @@ -95,11 +96,12 @@ offset = 0; do { len = ARRAY_LENGTH (lookup_indices); - hb_ot_layout_feature_get_lookups (face, - table_tags[table_index], - feature_index, - offset, &len, - lookup_indices); + hb_ot_layout_feature_with_variations_get_lookups (face, + table_tags[table_index], + feature_index, + variations_index, + offset, &len, + lookup_indices); for (unsigned int i = 0; i < len; i++) { @@ -130,7 +132,9 @@ } 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, + unsigned int num_coords) { m.global_mask = 1; @@ -264,6 +268,13 @@ { /* 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 last_num_lookups = 0; for (unsigned stage = 0; stage < current_stage[table_index]; stage++) @@ -272,6 +283,7 @@ required_feature_stage[table_index] == stage) add_lookups (m, face, table_index, required_feature_index[table_index], + variations_index, 1 /* mask */, true /* auto_zwj */); @@ -279,6 +291,7 @@ if (m.features[i].stage[table_index] == stage) add_lookups (m, face, table_index, m.features[i].index[table_index], + variations_index, m.features[i].mask, m.features[i].auto_zwj);
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh index 54ac2c3..594e54c 100644 --- a/src/hb-ot-shape-private.hh +++ b/src/hb-ot-shape-private.hh
@@ -77,11 +77,13 @@ map (face, &props) {} ~hb_ot_shape_planner_t (void) { map.finish (); } - inline void compile (hb_ot_shape_plan_t &plan) + inline void compile (hb_ot_shape_plan_t &plan, + const int *coords, + unsigned int num_coords) { plan.props = props; plan.shaper = shaper; - map.compile (plan.map); + map.compile (plan.map, coords, num_coords); plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m')); plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 7811cb7..6c78b47 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc
@@ -163,7 +163,9 @@ hb_ot_shaper_shape_plan_data_t * _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, const hb_feature_t *user_features, - unsigned int num_user_features) + unsigned int num_user_features, + const int *coords, + unsigned int num_coords) { hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t)); if (unlikely (!plan)) @@ -173,9 +175,10 @@ planner.shaper = hb_ot_shape_complex_categorize (&planner); - hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features); + hb_ot_shape_collect_features (&planner, &shape_plan->props, + user_features, num_user_features); - planner.compile (*plan); + planner.compile (*plan, coords, num_coords); if (plan->shaper->data_create) { plan->data = plan->shaper->data_create (plan);
diff --git a/src/hb-shape-plan-private.hh b/src/hb-shape-plan-private.hh index 607da5e..aa0413a 100644 --- a/src/hb-shape-plan-private.hh +++ b/src/hb-shape-plan-private.hh
@@ -47,12 +47,17 @@ hb_feature_t *user_features; unsigned int num_user_features; + int *coords; + unsigned int num_coords; + struct hb_shaper_data_t shaper_data; }; #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \ - , const hb_feature_t *user_features \ - , unsigned int num_user_features + , const hb_feature_t *user_features \ + , unsigned int num_user_features \ + , const int *coords \ + , unsigned int num_coords #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan); #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 87231fb..600faae 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc
@@ -46,11 +46,14 @@ hb_shape_plan_plan (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) { DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, - "num_features=%d shaper_list=%p", + "num_features=%d num_coords=%d shaper_list=%p", num_user_features, + num_coords, shaper_list); const hb_shaper_pair_t *shapers = _hb_shapers_get (); @@ -59,7 +62,9 @@ HB_STMT_START { \ if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \ HB_SHAPER_DATA (shaper, shape_plan) = \ - HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \ + HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, \ + user_features, num_user_features, \ + coords, num_coords); \ shape_plan->shaper_func = _hb_##shaper##_shape; \ shape_plan->shaper_name = #shaper; \ return; \ @@ -115,14 +120,31 @@ unsigned int num_user_features, const char * const *shaper_list) { + return hb_shape_plan_create2 (face, props, + user_features, num_user_features, + NULL, 0, + shaper_list); +} + +hb_shape_plan_t * +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, + unsigned int num_coords, + const char * const *shaper_list) +{ DEBUG_MSG_FUNC (SHAPE_PLAN, NULL, - "face=%p num_features=%d shaper_list=%p", + "face=%p num_features=%d num_coords=%d shaper_list=%p", face, num_user_features, + num_coords, shaper_list); hb_shape_plan_t *shape_plan; hb_feature_t *features = NULL; + int *coords = NULL; if (unlikely (!face)) face = hb_face_get_empty (); @@ -130,7 +152,14 @@ return hb_shape_plan_get_empty (); if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t)))) return hb_shape_plan_get_empty (); - if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) { + if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int)))) + { + free (features); + return hb_shape_plan_get_empty (); + } + if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) + { + free (coords); free (features); return hb_shape_plan_get_empty (); } @@ -145,8 +174,15 @@ 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)); - hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list); + hb_shape_plan_plan (shape_plan, + user_features, num_user_features, + coords, num_coords, + shaper_list); return shape_plan; } @@ -176,6 +212,9 @@ NULL, /* user_features */ 0, /* num_user_featurs */ + NULL, /* coords */ + 0, /* num_coords */ + { #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, #include "hb-shaper-list.hh" @@ -220,6 +259,7 @@ #undef HB_SHAPER_IMPLEMENT free (shape_plan->user_features); + free (shape_plan->coords); free (shape_plan); } @@ -351,6 +391,8 @@ const char * const *shaper_list; const hb_feature_t *user_features; unsigned int num_user_features; + const int *coords; + unsigned int num_coords; hb_shape_func_t *shaper_func; }; @@ -358,12 +400,26 @@ hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan, const hb_shape_plan_proposal_t *proposal) { - if (proposal->num_user_features != shape_plan->num_user_features) return false; + if (proposal->num_user_features != shape_plan->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; + proposal->user_features[i].end != shape_plan->user_features[i].end) + return false; + return true; +} + +static inline hb_bool_t +hb_shape_plan_coords_match (const hb_shape_plan_t *shape_plan, + const hb_shape_plan_proposal_t *proposal) +{ + if (proposal->num_coords != shape_plan->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; } @@ -373,6 +429,7 @@ { 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->default_shaper_list && proposal->shaper_list == NULL) || (shape_plan->shaper_func == proposal->shaper_func)); } @@ -389,6 +446,13 @@ return false; } +static inline hb_bool_t +hb_coords_present (const int *coords, + unsigned int num_coords) +{ + return num_coords != 0; +} + /** * hb_shape_plan_create_cached: * @face: @@ -410,6 +474,21 @@ unsigned int num_user_features, const char * const *shaper_list) { + return hb_shape_plan_create_cached2 (face, props, + user_features, num_user_features, + NULL, 0, + shaper_list); +} + +hb_shape_plan_t * +hb_shape_plan_create_cached2 (hb_face_t *face, + const hb_segment_properties_t *props, + 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, NULL, "face=%p num_features=%d shaper_list=%p", face, @@ -456,16 +535,21 @@ /* Not found. */ - hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list); + 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)) + 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)); if (unlikely (!node))
diff --git a/src/hb-shape-plan.h b/src/hb-shape-plan.h index aa5e0c7..b62ae7c 100644 --- a/src/hb-shape-plan.h +++ b/src/hb-shape-plan.h
@@ -53,6 +53,25 @@ const char * const *shaper_list); HB_EXTERN hb_shape_plan_t * +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 *coords, + unsigned int num_coords, + const char * const *shaper_list); + +HB_EXTERN hb_shape_plan_t * +hb_shape_plan_create_cached2 (hb_face_t *face, + const hb_segment_properties_t *props, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *coords, + unsigned int num_coords, + const char * const *shaper_list); + + +HB_EXTERN hb_shape_plan_t * hb_shape_plan_get_empty (void); HB_EXTERN hb_shape_plan_t *
diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 41a4fc5..706f144 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc
@@ -373,7 +373,10 @@ unsigned int num_features, const char * const *shaper_list) { - hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list); + hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached2 (font->face, &buffer->props, + features, num_features, + font->coords, font->num_coords, + shaper_list); hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); hb_shape_plan_destroy (shape_plan);
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index 07007a6..6e4db01 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc
@@ -587,7 +587,9 @@ hb_uniscribe_shaper_shape_plan_data_t * _hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED) + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) { return (hb_uniscribe_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; }