From 693918ef8541014a5ef7dfb91c6ea0ae36d9c368 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 30 Jul 2012 21:08:51 -0400 Subject: [PATCH] [OT] Streamline complex shaper enumeration Add a shaper class struct. --- src/hb-ot-shape-complex-arabic.cc | 37 ++++---- src/hb-ot-shape-complex-indic.cc | 47 ++++++--- src/hb-ot-shape-complex-misc.cc | 67 ++++++------- src/hb-ot-shape-complex-private.hh | 179 ++++++++++------------------------- src/hb-ot-shape-normalize-private.hh | 4 +- src/hb-ot-shape-private.hh | 2 +- src/hb-ot-shape.cc | 16 ++-- 7 files changed, 143 insertions(+), 209 deletions(-) diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index 1f63c12..0f73d6d 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -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, +}; diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index c7025ff..b384e0e 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -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, +}; diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc index 4b9e6a6..1815366 100644 --- a/src/hb-ot-shape-complex-misc.cc +++ b/src/hb-ot-shape-complex-misc.cc @@ -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, +}; diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index 689ca61..c0864fe 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -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) \ @@ -51,21 +53,60 @@ 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 */ diff --git a/src/hb-ot-shape-normalize-private.hh b/src/hb-ot-shape-normalize-private.hh index bb81f00..4c89a8f 100644 --- a/src/hb-ot-shape-normalize-private.hh +++ b/src/hb-ot-shape-normalize-private.hh @@ -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, diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh index e1f6a69..30c7808 100644 --- a/src/hb-ot-shape-private.hh +++ b/src/hb-ot-shape-private.hh @@ -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; }; diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 0cd548f..8df8251 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -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); -- 2.7.4