[OT] Streamline complex shaper enumeration
authorBehdad Esfahbod <behdad@behdad.org>
Tue, 31 Jul 2012 01:08:51 +0000 (21:08 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Tue, 31 Jul 2012 01:08:51 +0000 (21:08 -0400)
Add a shaper class struct.

src/hb-ot-shape-complex-arabic.cc
src/hb-ot-shape-complex-indic.cc
src/hb-ot-shape-complex-misc.cc
src/hb-ot-shape-complex-private.hh
src/hb-ot-shape-normalize-private.hh
src/hb-ot-shape-private.hh
src/hb-ot-shape.cc

index 1f63c12..0f73d6d 100644 (file)
@@ -164,9 +164,10 @@ static const struct arabic_state_table_entry {
 
 
 
-void
-_hb_ot_shape_complex_collect_features_arabic (hb_ot_map_builder_t *map,
-                                             const hb_segment_properties_t *props)
+static void
+collect_features_arabic (const hb_ot_complex_shaper_t  *shaper,
+                        hb_ot_map_builder_t           *map,
+                        const hb_segment_properties_t *props)
 {
   /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together,
    * then rlig and calt each in their own stage.  This makes IranNastaliq's ALLAH
@@ -199,18 +200,6 @@ _hb_ot_shape_complex_collect_features_arabic (hb_ot_map_builder_t *map,
   map->add_bool_feature (HB_TAG('c','s','w','h'));
 }
 
-void
-_hb_ot_shape_complex_override_features_arabic (hb_ot_map_builder_t *map,
-                                              const hb_segment_properties_t *props)
-{
-}
-
-hb_ot_shape_normalization_mode_t
-_hb_ot_shape_complex_normalization_preference_arabic (const hb_segment_properties_t *props)
-{
-  return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
-}
-
 
 static void
 arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer)
@@ -246,10 +235,11 @@ arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer)
   buffer->swap_buffers ();
 }
 
-void
-_hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map,
-                                        hb_buffer_t *buffer,
-                                        hb_font_t *font)
+static void
+setup_masks_arabic (const hb_ot_complex_shaper_t *shaper,
+                   const hb_ot_map_t            *map,
+                   hb_buffer_t                  *buffer,
+                   hb_font_t                    *font)
 {
   unsigned int count = buffer->len;
   unsigned int prev = 0, state = 0;
@@ -302,4 +292,11 @@ _hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map,
   HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
 }
 
-
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
+{
+  "arabic",
+  collect_features_arabic,
+  NULL, /* override_features */
+  NULL, /* normalization_preference */
+  setup_masks_arabic,
+};
index c7025ff..b384e0e 100644 (file)
@@ -89,8 +89,11 @@ compare_codepoint (const void *pa, const void *pb)
 }
 
 static bool
-would_substitute (hb_codepoint_t *glyphs, unsigned int glyphs_count,
-                 hb_tag_t feature_tag, hb_ot_map_t *map, hb_face_t *face)
+would_substitute (hb_codepoint_t    *glyphs,
+                 unsigned int       glyphs_count,
+                 hb_tag_t           feature_tag,
+                 const hb_ot_map_t *map,
+                 hb_face_t         *face)
 {
   unsigned int lookup_indices[32];
   unsigned int offset, len;
@@ -115,7 +118,9 @@ would_substitute (hb_codepoint_t *glyphs, unsigned int glyphs_count,
 }
 
 static indic_position_t
-consonant_position (hb_codepoint_t u, hb_ot_map_t *map, hb_font_t *font)
+consonant_position (hb_codepoint_t     u,
+                   const hb_ot_map_t *map,
+                   hb_font_t         *font)
 {
   if ((u & ~0x007F) == 0x1780)
     return POS_BELOW_C; /* In Khmer coeng model, all are subjoining. */
@@ -232,7 +237,9 @@ is_halant_or_coeng (const hb_glyph_info_t &info)
 }
 
 static inline void
-set_indic_properties (hb_glyph_info_t &info, hb_ot_map_t *map, hb_font_t *font)
+set_indic_properties (hb_glyph_info_t   &info,
+                     const hb_ot_map_t *map,
+                     hb_font_t         *font)
 {
   hb_codepoint_t u = info.codepoint;
   unsigned int type = get_indic_categories (u);
@@ -387,9 +394,10 @@ final_reordering (const hb_ot_map_t *map,
                  hb_buffer_t *buffer,
                  void *user_data HB_UNUSED);
 
-void
-_hb_ot_shape_complex_collect_features_indic (hb_ot_map_builder_t *map,
-                                            const hb_segment_properties_t *props HB_UNUSED)
+static void
+collect_features_indic (const hb_ot_complex_shaper_t  *shaper,
+                       hb_ot_map_builder_t           *map,
+                       const hb_segment_properties_t *props)
 {
   map->add_bool_feature (HB_TAG('l','o','c','l'));
   /* The Indic specs do not require ccmp, but we apply it here since if
@@ -409,9 +417,10 @@ _hb_ot_shape_complex_collect_features_indic (hb_ot_map_builder_t *map,
     map->add_bool_feature (indic_other_features[i].tag, indic_other_features[i].is_global);
 }
 
-void
-_hb_ot_shape_complex_override_features_indic (hb_ot_map_builder_t *map,
-                                             const hb_segment_properties_t *props HB_UNUSED)
+static void
+override_features_indic (const hb_ot_complex_shaper_t  *shaper,
+                        hb_ot_map_builder_t           *map,
+                        const hb_segment_properties_t *props)
 {
   /* Uniscribe does not apply 'kern'. */
   if (indic_options ().uniscribe_bug_compatible)
@@ -426,10 +435,11 @@ _hb_ot_shape_complex_normalization_preference_indic (const hb_segment_properties
 }
 
 
-void
-_hb_ot_shape_complex_setup_masks_indic (hb_ot_map_t *map,
-                                       hb_buffer_t *buffer,
-                                       hb_font_t *font)
+static void
+setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
+                  const hb_ot_map_t            *map,
+                  hb_buffer_t                  *buffer,
+                  hb_font_t                    *font)
 {
   HB_BUFFER_ALLOCATE_VAR (buffer, indic_category);
   HB_BUFFER_ALLOCATE_VAR (buffer, indic_position);
@@ -1235,4 +1245,11 @@ final_reordering (const hb_ot_map_t *map,
 }
 
 
-
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
+{
+  "indic",
+  collect_features_indic,
+  override_features_indic,
+  NULL, /* normalization_preference */
+  setup_masks_indic,
+};
index 4b9e6a6..1815366 100644 (file)
@@ -49,9 +49,10 @@ static const hb_tag_t tibetan_features[] =
   HB_TAG_NONE
 };
 
-void
-_hb_ot_shape_complex_collect_features_default (hb_ot_map_builder_t *map HB_UNUSED,
-                                              const hb_segment_properties_t *props)
+static void
+collect_features_default (const hb_ot_complex_shaper_t  *shaper,
+                         hb_ot_map_builder_t           *map,
+                         const hb_segment_properties_t *props)
 {
   const hb_tag_t *script_features = NULL;
 
@@ -72,14 +73,9 @@ _hb_ot_shape_complex_collect_features_default (hb_ot_map_builder_t *map HB_UNUSE
     map->add_bool_feature (*script_features);
 }
 
-void
-_hb_ot_shape_complex_override_features_default (hb_ot_map_builder_t *map HB_UNUSED,
-                                               const hb_segment_properties_t *props HB_UNUSED)
-{
-}
-
-hb_ot_shape_normalization_mode_t
-_hb_ot_shape_complex_normalization_preference_default (const hb_segment_properties_t *props)
+static hb_ot_shape_normalization_mode_t
+normalization_preference_default (const hb_ot_complex_shaper_t  *shaper,
+                                 const hb_segment_properties_t *props)
 {
   switch ((hb_tag_t) props->script)
   {
@@ -90,39 +86,23 @@ _hb_ot_shape_complex_normalization_preference_default (const hb_segment_properti
   return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
 }
 
-void
-_hb_ot_shape_complex_setup_masks_default (hb_ot_map_t *map HB_UNUSED,
-                                         hb_buffer_t *buffer HB_UNUSED,
-                                         hb_font_t *font HB_UNUSED)
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
 {
-}
-
+  "default",
+  collect_features_default,
+  NULL, /* override_features */
+  normalization_preference_default,
+  NULL, /* setup_masks */
+};
 
 
 /* Thai / Lao shaper */
 
-void
-_hb_ot_shape_complex_collect_features_thai (hb_ot_map_builder_t *map HB_UNUSED,
-                                           const hb_segment_properties_t *props HB_UNUSED)
-{
-}
-
-void
-_hb_ot_shape_complex_override_features_thai (hb_ot_map_builder_t *map HB_UNUSED,
-                                            const hb_segment_properties_t *props HB_UNUSED)
-{
-}
-
-hb_ot_shape_normalization_mode_t
-_hb_ot_shape_complex_normalization_preference_thai (const hb_segment_properties_t *props HB_UNUSED)
-{
-  return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
-}
-
-void
-_hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map HB_UNUSED,
-                                      hb_buffer_t *buffer,
-                                      hb_font_t *font HB_UNUSED)
+static void
+setup_masks_thai (const hb_ot_complex_shaper_t *shaper,
+                 const hb_ot_map_t            *map,
+                 hb_buffer_t                  *buffer,
+                 hb_font_t                    *font)
 {
   /* The following is NOT specified in the MS OT Thai spec, however, it seems
    * to be what Uniscribe and other engines implement.  According to Eric Muller:
@@ -213,3 +193,12 @@ _hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map HB_UNUSED,
   }
   buffer->swap_buffers ();
 }
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
+{
+  "thai",
+  NULL, /* collect_features */
+  NULL, /* override_features */
+  NULL, /* normalization_preference */
+  setup_masks_thai,
+};
index 689ca61..c0864fe 100644 (file)
@@ -44,6 +44,8 @@
 #define complex_var_temporary_u8()     var2.u8[0]
 
 
+
+/* Master OT shaper list */
 #define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
   HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
   HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
   HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
   /* ^--- Add new shapers here */
 
-enum hb_ot_complex_shaper_t {
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) hb_ot_complex_shaper_##name,
-  HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-  /* Just here to avoid enum trailing comma: */
-  hb_ot_complex_shaper_generic = hb_ot_complex_shaper_default
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
+
+struct hb_ot_complex_shaper_t
+{
+  char name[8];
+
+  /* collect_features()
+   * Called during shape_plan().
+   * Shapers should use map to add their features and callbacks.
+   * May be NULL.
+   */
+  void (*collect_features) (const hb_ot_complex_shaper_t  *shaper,
+                           hb_ot_map_builder_t           *map,
+                           const hb_segment_properties_t *props);
+
+  /* override_features()
+   * Called during shape_plan().
+   * Shapers should use map to override features and add callbacks after
+   * common features are added.
+   * May be NULL.
+   */
+  void (*override_features) (const hb_ot_complex_shaper_t  *shaper,
+                            hb_ot_map_builder_t           *map,
+                            const hb_segment_properties_t *props);
+
+  /* normalization_preference()
+   * Called during shape_execute().
+   */
+  hb_ot_shape_normalization_mode_t
+  (*normalization_preference) (const hb_ot_complex_shaper_t  *shaper,
+                              const hb_segment_properties_t *props);
+
+
+  /* setup_masks()
+   * Called during shape_execute().
+   * Shapers should use map to get feature masks and set on buffer.
+   */
+  void (*setup_masks) (const hb_ot_complex_shaper_t *shaper,
+                      const hb_ot_map_t            *map,
+                      hb_buffer_t                  *buffer,
+                      hb_font_t                    *font);
 };
 
-static inline hb_ot_complex_shaper_t
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
+HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
+
+
+static inline const hb_ot_complex_shaper_t *
 hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
 {
   switch ((hb_tag_t) props->script)
   {
     default:
-      return hb_ot_complex_shaper_default;
+      return &_hb_ot_complex_shaper_default;
 
 
     /* Unicode-1.1 additions */
@@ -79,14 +120,14 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
     /* Unicode-6.0 additions */
     case HB_SCRIPT_MANDAIC:
 
-      return hb_ot_complex_shaper_arabic;
+      return &_hb_ot_complex_shaper_arabic;
 
 
     /* Unicode-1.1 additions */
     case HB_SCRIPT_THAI:
     case HB_SCRIPT_LAO:
 
-      return hb_ot_complex_shaper_thai;
+      return &_hb_ot_complex_shaper_thai;
 
 
 
@@ -201,125 +242,9 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
     case HB_SCRIPT_SHARADA:
     case HB_SCRIPT_TAKRI:
 
-      return hb_ot_complex_shaper_indic;
-  }
-}
-
-
-
-/*
- * collect_features()
- *
- * Called during shape_plan().
- *
- * Shapers should use map to add their features and callbacks.
- */
-
-typedef void hb_ot_shape_complex_collect_features_func_t (hb_ot_map_builder_t *map, const hb_segment_properties_t  *props);
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
-  HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_##name;
-  HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-
-static inline void
-hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper,
-                                     hb_ot_map_builder_t *map,
-                                     const hb_segment_properties_t  *props)
-{
-  switch (shaper) {
-    default:
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
-    case hb_ot_complex_shaper_##name:  _hb_ot_shape_complex_collect_features_##name (map, props); return;
-    HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
+      return &_hb_ot_complex_shaper_indic;
   }
 }
 
 
-/*
- * override_features()
- *
- * Called during shape_plan().
- *
- * Shapers should use map to override features and add callbacks after
- * common features are added.
- */
-
-typedef void hb_ot_shape_complex_override_features_func_t (hb_ot_map_builder_t *map, const hb_segment_properties_t  *props);
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
-  HB_INTERNAL hb_ot_shape_complex_override_features_func_t _hb_ot_shape_complex_override_features_##name;
-  HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-
-static inline void
-hb_ot_shape_complex_override_features (hb_ot_complex_shaper_t shaper,
-                                      hb_ot_map_builder_t *map,
-                                      const hb_segment_properties_t  *props)
-{
-  switch (shaper) {
-    default:
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
-    case hb_ot_complex_shaper_##name:  _hb_ot_shape_complex_override_features_##name (map, props); return;
-    HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-  }
-}
-
-
-/*
- * normalization_preference()
- *
- * Called during shape_execute().
- */
-
-typedef hb_ot_shape_normalization_mode_t hb_ot_shape_complex_normalization_preference_func_t (const hb_segment_properties_t *props HB_UNUSED);
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
-  HB_INTERNAL hb_ot_shape_complex_normalization_preference_func_t _hb_ot_shape_complex_normalization_preference_##name;
-  HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-
-static inline hb_ot_shape_normalization_mode_t
-hb_ot_shape_complex_normalization_preference (hb_ot_complex_shaper_t shaper,
-                                             const hb_segment_properties_t *props)
-{
-  switch (shaper) {
-    default:
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
-    case hb_ot_complex_shaper_##name:  return _hb_ot_shape_complex_normalization_preference_##name (props);
-    HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-  }
-}
-
-
-/* setup_masks()
- *
- * Called during shape_execute().
- *
- * Shapers should use map to get feature masks and set on buffer.
- */
-
-typedef void hb_ot_shape_complex_setup_masks_func_t (hb_ot_map_t *map, hb_buffer_t *buffer, hb_font_t *font);
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
-  HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_##name;
-  HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-
-static inline void
-hb_ot_shape_complex_setup_masks (hb_ot_complex_shaper_t shaper,
-                                hb_ot_map_t *map,
-                                hb_buffer_t *buffer,
-                                hb_font_t *font)
-{
-  switch (shaper) {
-    default:
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
-    case hb_ot_complex_shaper_##name:  _hb_ot_shape_complex_setup_masks_##name (map, buffer, font); return;
-    HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
-  }
-}
-
-
-
 #endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */
index bb81f00..4c89a8f 100644 (file)
@@ -36,7 +36,9 @@
 enum hb_ot_shape_normalization_mode_t {
   HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
   HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
-  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL /* including base-to-base composition */
+  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL, /* including base-to-base composition */
+
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS,
 };
 
 HB_INTERNAL void _hb_ot_shape_normalize (hb_font_t *font,
index e1f6a69..30c7808 100644 (file)
@@ -36,7 +36,7 @@
 struct hb_ot_shape_plan_t
 {
   hb_ot_map_t map;
-  hb_ot_complex_shaper_t shaper;
+  const hb_ot_complex_shaper_t *shaper;
 };
 
 
index 0cd548f..8df8251 100644 (file)
@@ -73,7 +73,7 @@ hb_tag_t vertical_features[] = {
 struct hb_ot_shape_planner_t
 {
   hb_ot_map_builder_t map;
-  hb_ot_complex_shaper_t shaper;
+  const hb_ot_complex_shaper_t *shaper;
 
   hb_ot_shape_planner_t (void) : map () {}
   ~hb_ot_shape_planner_t (void) { map.finish (); }
@@ -118,7 +118,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
       planner->map.add_bool_feature (array[i]); \
   } HB_STMT_END
 
-  hb_ot_shape_complex_collect_features (planner->shaper, &planner->map, props);
+  if (planner->shaper->collect_features)
+    planner->shaper->collect_features (planner->shaper, &planner->map, props);
 
   ADD_FEATURES (common_features);
 
@@ -127,7 +128,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
   else
     ADD_FEATURES (vertical_features);
 
-  hb_ot_shape_complex_override_features (planner->shaper, &planner->map, props);
+  if (planner->shaper->override_features)
+    planner->shaper->override_features (planner->shaper, &planner->map, props);
 
 #undef ADD_FEATURES
 
@@ -233,7 +235,8 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
   hb_mask_t global_mask = c->plan->map.get_global_mask ();
   c->buffer->reset_masks (global_mask);
 
-  hb_ot_shape_complex_setup_masks (c->plan->shaper, &c->plan->map, c->buffer, c->font);
+  if (c->plan->shaper->setup_masks)
+    c->plan->shaper->setup_masks (c->plan->shaper, &c->plan->map, c->buffer, c->font);
 
   for (unsigned int i = 0; i < c->num_user_features; i++)
   {
@@ -493,8 +496,9 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
   hb_ensure_native_direction (c->buffer);
 
   _hb_ot_shape_normalize (c->font, c->buffer,
-                         hb_ot_shape_complex_normalization_preference (c->plan->shaper,
-                                                                       &c->buffer->props));
+                         c->plan->shaper->normalization_preference ?
+                         c->plan->shaper->normalization_preference (c->plan->shaper, &c->buffer->props) :
+                         HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT);
 
   hb_ot_shape_setup_masks (c);