[OT] Separate map_builder from the actual map
authorBehdad Esfahbod <behdad@behdad.org>
Fri, 27 May 2011 22:13:31 +0000 (18:13 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Fri, 27 May 2011 22:13:31 +0000 (18:13 -0400)
Respectively, separate planner from the actual plan.

src/hb-ot-map-private.hh
src/hb-ot-map.cc
src/hb-ot-shape-complex-arabic.cc
src/hb-ot-shape-complex-private.hh
src/hb-ot-shape-private.hh
src/hb-ot-shape.cc

index 02f5a91..2c8b99f 100644 (file)
@@ -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_info_t,16> 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_info_t,8> feature_infos; /* used before compile() only */
-  hb_prealloced_array_t<feature_map_t, 8> 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_map_t, 32> 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<feature_map_t, 8> features;
+  hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
+};
 
 
 HB_END_DECLS
index 9006bf9..f178bed 100644 (file)
@@ -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);
     }
   }
 }
index f2d325f..1b5b231 100644 (file)
@@ -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
index b3afe2b..f58e5da 100644 (file)
@@ -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;
   }
 }
index 4ea73f5..60269ce 100644 (file)
@@ -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
 {
index 02be237..4b66dd1 100644 (file)
@@ -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