[OT] Streamline complex shaper enumeration

Add a shaper class struct.
This commit is contained in:
Behdad Esfahbod 2012-07-30 21:08:51 -04:00
parent c2e42c3db6
commit 693918ef85
7 changed files with 143 additions and 209 deletions

View 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,
};

View 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,
};

View 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,
};

View 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) \
@ -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;
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
}
}
/*
* 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 */

View 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,

View 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;
};

View 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);