From 90645fb24bcbb78183576d3641a99560d87e49f2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 27 May 2011 18:13:31 -0400 Subject: [PATCH] [OT] Separate map_builder from the actual map Respectively, separate planner from the actual plan. --- src/hb-ot-map-private.hh | 121 ++++++++++++++++++++----------------- src/hb-ot-map.cc | 33 +++++----- src/hb-ot-shape-complex-arabic.cc | 6 +- src/hb-ot-shape-complex-private.hh | 8 +-- src/hb-ot-shape-private.hh | 22 +++++++ src/hb-ot-shape.cc | 28 +++++---- 6 files changed, 127 insertions(+), 91 deletions(-) diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index 02f5a91..2c8b99f 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -38,7 +38,31 @@ HB_BEGIN_DECLS static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS}; -struct hb_ot_map_t { +struct hb_ot_map_builder_t +{ + public: + + inline void add_feature (hb_tag_t tag, unsigned int value, bool global) + { + feature_info_t *info = feature_infos.push(); + if (unlikely (!info)) return; + info->tag = tag; + info->seq = feature_infos.len; + info->max_value = value; + info->global = global; + info->default_value = global ? value : 0; + } + + inline void add_bool_feature (hb_tag_t tag, bool global = true) + { add_feature (tag, 1, global); } + + HB_INTERNAL void compile (hb_face_t *face, + const hb_segment_properties_t *props, + struct hb_ot_map_t &m); + + inline void finish (void) { + feature_infos.finish (); + } private: @@ -53,90 +77,77 @@ struct hb_ot_map_t { { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); } }; - struct feature_map_t { - hb_tag_t tag; /* should be first for our bsearch to work */ - unsigned int index[2]; /* GSUB, GPOS */ - unsigned int shift; - hb_mask_t mask; - hb_mask_t _1_mask; /* mask for value=1, for quick access */ - - static int cmp (const feature_map_t *a, const feature_map_t *b) - { return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; } - }; - - struct lookup_map_t { - unsigned int index; - hb_mask_t mask; - - static int cmp (const lookup_map_t *a, const lookup_map_t *b) - { return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; } - }; + hb_prealloced_array_t feature_infos; /* used before compile() only */ +}; - HB_INTERNAL void add_lookups (hb_face_t *face, - unsigned int table_index, - unsigned int feature_index, - hb_mask_t mask); +struct hb_ot_map_t +{ + friend struct hb_ot_map_builder_t; public: - void add_feature (hb_tag_t tag, unsigned int value, bool global) - { - feature_info_t *info = feature_infos.push(); - if (unlikely (!info)) return; - info->tag = tag; - info->seq = feature_infos.len; - info->max_value = value; - info->global = global; - info->default_value = global ? value : 0; - } - - inline void add_bool_feature (hb_tag_t tag, bool global = true) - { add_feature (tag, 1, global); } - - HB_INTERNAL void compile (hb_face_t *face, - const hb_segment_properties_t *props); - inline hb_mask_t get_global_mask (void) const { return global_mask; } inline hb_mask_t get_mask (hb_tag_t tag, unsigned int *shift = NULL) const { - const feature_map_t *map = feature_maps.bsearch (&tag); + const feature_map_t *map = features.bsearch (&tag); if (shift) *shift = map ? map->shift : 0; return map ? map->mask : 0; } inline hb_mask_t get_1_mask (hb_tag_t tag) const { - const feature_map_t *map = feature_maps.bsearch (&tag); + const feature_map_t *map = features.bsearch (&tag); return map ? map->_1_mask : 0; } inline void substitute (hb_face_t *face, hb_buffer_t *buffer) const { - for (unsigned int i = 0; i < lookup_maps[0].len; i++) - hb_ot_layout_substitute_lookup (face, buffer, lookup_maps[0][i].index, lookup_maps[0][i].mask); + for (unsigned int i = 0; i < lookups[0].len; i++) + hb_ot_layout_substitute_lookup (face, buffer, lookups[0][i].index, lookups[0][i].mask); } inline void position (hb_font_t *font, hb_face_t *face, hb_buffer_t *buffer) const { - for (unsigned int i = 0; i < lookup_maps[1].len; i++) - hb_ot_layout_position_lookup (font, buffer, lookup_maps[1][i].index, lookup_maps[1][i].mask); + for (unsigned int i = 0; i < lookups[1].len; i++) + hb_ot_layout_position_lookup (font, buffer, lookups[1][i].index, lookups[1][i].mask); } inline void finish (void) { - feature_infos.finish (); - feature_maps.finish (); - lookup_maps[0].finish (); - lookup_maps[1].finish (); + features.finish (); + lookups[0].finish (); + lookups[1].finish (); } private: - hb_mask_t global_mask; + struct feature_map_t { + hb_tag_t tag; /* should be first for our bsearch to work */ + unsigned int index[2]; /* GSUB, GPOS */ + unsigned int shift; + hb_mask_t mask; + hb_mask_t _1_mask; /* mask for value=1, for quick access */ - hb_prealloced_array_t feature_infos; /* used before compile() only */ - hb_prealloced_array_t feature_maps; + static int cmp (const feature_map_t *a, const feature_map_t *b) + { return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; } + }; - hb_prealloced_array_t lookup_maps[2]; /* GSUB/GPOS */ -}; + struct lookup_map_t { + unsigned int index; + hb_mask_t mask; + static int cmp (const lookup_map_t *a, const lookup_map_t *b) + { return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; } + }; + + HB_INTERNAL void add_lookups (hb_face_t *face, + unsigned int table_index, + unsigned int feature_index, + hb_mask_t mask); + + + hb_mask_t global_mask; + + hb_prealloced_array_t features; + hb_prealloced_array_t lookups[2]; /* GSUB/GPOS */ +}; HB_END_DECLS diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 9006bf9..f178bed 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -52,7 +52,7 @@ hb_ot_map_t::add_lookups (hb_face_t *face, lookup_indices); for (unsigned int i = 0; i < len; i++) { - lookup_map_t *lookup = lookup_maps[table_index].push (); + hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push (); if (unlikely (!lookup)) return; lookup->mask = mask; @@ -65,10 +65,11 @@ hb_ot_map_t::add_lookups (hb_face_t *face, void -hb_ot_map_t::compile (hb_face_t *face, - const hb_segment_properties_t *props) +hb_ot_map_builder_t::compile (hb_face_t *face, + const hb_segment_properties_t *props, + hb_ot_map_t &m) { - global_mask = 1; + m.global_mask = 1; if (!feature_infos.len) return; @@ -139,7 +140,7 @@ hb_ot_map_t::compile (hb_face_t *face, continue; - feature_map_t *map = feature_maps.push (); + hb_ot_map_t::feature_map_t *map = m.features.push (); if (unlikely (!map)) break; @@ -155,7 +156,7 @@ hb_ot_map_t::compile (hb_face_t *face, map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit); next_bit += bits_needed; if (info->global) - global_mask |= (info->default_value << map->shift) & map->mask; + m.global_mask |= (info->default_value << map->shift) & map->mask; } map->_1_mask = (1 << map->shift) & map->mask; @@ -174,22 +175,22 @@ hb_ot_map_t::compile (hb_face_t *face, script_index[table_index], language_index[table_index], &required_feature_index)) - add_lookups (face, table_index, required_feature_index, 1); + m.add_lookups (face, table_index, required_feature_index, 1); - for (unsigned i = 0; i < feature_maps.len; i++) - add_lookups (face, table_index, feature_maps[i].index[table_index], feature_maps[i].mask); + for (unsigned i = 0; i < m.features.len; i++) + m.add_lookups (face, table_index, m.features[i].index[table_index], m.features[i].mask); /* Sort lookups and merge duplicates */ - lookup_maps[table_index].sort (); - if (lookup_maps[table_index].len) + m.lookups[table_index].sort (); + if (m.lookups[table_index].len) { unsigned int j = 0; - for (unsigned int i = 1; i < lookup_maps[table_index].len; i++) - if (lookup_maps[table_index][i].index != lookup_maps[table_index][j].index) - lookup_maps[table_index][++j] = lookup_maps[table_index][i]; + for (unsigned int i = 1; i < m.lookups[table_index].len; i++) + if (m.lookups[table_index][i].index != m.lookups[table_index][j].index) + m.lookups[table_index][++j] = m.lookups[table_index][i]; else - lookup_maps[table_index][j].mask |= lookup_maps[table_index][i].mask; - lookup_maps[table_index].shrink (j + 1); + m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask; + m.lookups[table_index].shrink (j + 1); } } } diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index f2d325f..1b5b231 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -152,14 +152,14 @@ static const struct arabic_state_table_entry { void -_hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_plan_t *plan, const hb_segment_properties_t *props) +_hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_planner_t *planner, const hb_segment_properties_t *props) { /* ArabicOT spec enables 'cswh' for Arabic where as for basic shaper it's disabled by default. */ - plan->map.add_bool_feature (HB_TAG('c','s','w','h')); + planner->map.add_bool_feature (HB_TAG('c','s','w','h')); unsigned int num_features = props->script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES; for (unsigned int i = 0; i < num_features; i++) - plan->map.add_bool_feature (arabic_syriac_features[i], false); + planner->map.add_bool_feature (arabic_syriac_features[i], false); } void diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index b3afe2b..f58e5da 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -61,14 +61,14 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) * Shapers should use plan->map to add their features. */ -HB_INTERNAL void _hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_plan_t *plan, const hb_segment_properties_t *props); +HB_INTERNAL void _hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_planner_t *plan, const hb_segment_properties_t *props); static inline void -hb_ot_shape_complex_collect_features (hb_ot_shape_plan_t *plan, +hb_ot_shape_complex_collect_features (hb_ot_shape_planner_t *planner, const hb_segment_properties_t *props) { - switch (plan->shaper) { - case hb_ot_complex_shaper_arabic: _hb_ot_shape_complex_collect_features_arabic (plan, props); return; + switch (planner->shaper) { + case hb_ot_complex_shaper_arabic: _hb_ot_shape_complex_collect_features_arabic (planner, props); return; case hb_ot_complex_shaper_none: default: return; } } diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh index 4ea73f5..60269ce 100644 --- a/src/hb-ot-shape-private.hh +++ b/src/hb-ot-shape-private.hh @@ -49,6 +49,8 @@ enum hb_ot_complex_shaper_t { struct hb_ot_shape_plan_t { + friend struct hb_ot_shape_planner_t; + hb_ot_map_t map; hb_ot_complex_shaper_t shaper; @@ -59,6 +61,26 @@ struct hb_ot_shape_plan_t NO_COPY (hb_ot_shape_plan_t); }; +struct hb_ot_shape_planner_t +{ + hb_ot_map_builder_t map; + hb_ot_complex_shaper_t shaper; + + hb_ot_shape_planner_t (void) : map () {} + ~hb_ot_shape_planner_t (void) { map.finish (); } + + inline void compile (hb_face_t *face, + const hb_segment_properties_t *props, + struct hb_ot_shape_plan_t &plan) + { + plan.shaper = shaper; + map.compile (face, props, plan.map); + } + + private: + NO_COPY (hb_ot_shape_planner_t); +}; + struct hb_ot_shape_context_t { diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 02be237..4b66dd1 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -49,19 +49,19 @@ hb_tag_t default_features[] = { }; static void -hb_ot_shape_collect_features (hb_ot_shape_plan_t *plan, +hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, const hb_segment_properties_t *props, - const hb_feature_t *user_features, - unsigned int num_user_features) + const hb_feature_t *user_features, + unsigned int num_user_features) { switch (props->direction) { case HB_DIRECTION_LTR: - plan->map.add_bool_feature (HB_TAG ('l','t','r','a')); - plan->map.add_bool_feature (HB_TAG ('l','t','r','m')); + planner->map.add_bool_feature (HB_TAG ('l','t','r','a')); + planner->map.add_bool_feature (HB_TAG ('l','t','r','m')); break; case HB_DIRECTION_RTL: - plan->map.add_bool_feature (HB_TAG ('r','t','l','a')); - plan->map.add_bool_feature (HB_TAG ('r','t','l','m'), false); + planner->map.add_bool_feature (HB_TAG ('r','t','l','a')); + planner->map.add_bool_feature (HB_TAG ('r','t','l','m'), false); break; case HB_DIRECTION_TTB: case HB_DIRECTION_BTT: @@ -71,13 +71,13 @@ hb_ot_shape_collect_features (hb_ot_shape_plan_t *plan, } for (unsigned int i = 0; i < ARRAY_LENGTH (default_features); i++) - plan->map.add_bool_feature (default_features[i]); + planner->map.add_bool_feature (default_features[i]); - hb_ot_shape_complex_collect_features (plan, props); + hb_ot_shape_complex_collect_features (planner, props); for (unsigned int i = 0; i < num_user_features; i++) { const hb_feature_t *feature = &user_features[i]; - plan->map.add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1)); + planner->map.add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1)); } } @@ -384,11 +384,13 @@ hb_ot_shape_plan_internal (hb_ot_shape_plan_t *plan, const hb_feature_t *user_features, unsigned int num_user_features) { - plan->shaper = hb_ot_shape_complex_categorize (props); + hb_ot_shape_planner_t planner; - hb_ot_shape_collect_features (plan, props, user_features, num_user_features); + planner.shaper = hb_ot_shape_complex_categorize (props); - plan->map.compile (face, props); + hb_ot_shape_collect_features (&planner, props, user_features, num_user_features); + + planner.compile (face, props, *plan); } static void -- 2.7.4