[OT] Add per-complex-shaper shape_plan data
Hookup some Indic data to it. More to come.
This commit is contained in:
parent
8bb5deba96
commit
a8c6da90f4
|
@ -296,6 +296,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
|
||||||
"arabic",
|
"arabic",
|
||||||
collect_features_arabic,
|
collect_features_arabic,
|
||||||
NULL, /* override_features */
|
NULL, /* override_features */
|
||||||
|
NULL, /* data_create */
|
||||||
|
NULL, /* data_destroy */
|
||||||
NULL, /* normalization_preference */
|
NULL, /* normalization_preference */
|
||||||
setup_masks_arabic,
|
setup_masks_arabic,
|
||||||
true, /* zero_width_attached_marks */
|
true, /* zero_width_attached_marks */
|
||||||
|
|
|
@ -82,56 +82,6 @@ indic_options (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct indic_shape_plan_t
|
|
||||||
{
|
|
||||||
struct would_apply_feature_t
|
|
||||||
{
|
|
||||||
would_apply_feature_t (const hb_ot_map_t *map, hb_tag_t feature_tag)
|
|
||||||
{
|
|
||||||
map->get_stage_lookups (0/*GSUB*/,
|
|
||||||
map->get_feature_stage (0/*GSUB*/, feature_tag),
|
|
||||||
&lookups, &count);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool would_substitute (hb_codepoint_t *glyphs,
|
|
||||||
unsigned int glyphs_count,
|
|
||||||
hb_face_t *face) const
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < count; i++)
|
|
||||||
if (hb_ot_layout_would_substitute_lookup_fast (face, glyphs, glyphs_count, lookups[i].index))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const hb_ot_map_t::lookup_map_t *lookups;
|
|
||||||
unsigned int count;
|
|
||||||
};
|
|
||||||
|
|
||||||
indic_shape_plan_t (const hb_ot_shape_plan_t *plan) :
|
|
||||||
pref (&plan->map, HB_TAG('p','r','e','f')),
|
|
||||||
blwf (&plan->map, HB_TAG('b','l','w','f')),
|
|
||||||
pstf (&plan->map, HB_TAG('p','s','t','f')),
|
|
||||||
is_old_spec (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))) {}
|
|
||||||
|
|
||||||
would_apply_feature_t pref;
|
|
||||||
would_apply_feature_t blwf;
|
|
||||||
would_apply_feature_t pstf;
|
|
||||||
bool is_old_spec;
|
|
||||||
};
|
|
||||||
|
|
||||||
static indic_position_t
|
|
||||||
consonant_position_from_font (const indic_shape_plan_t *indic_plan,
|
|
||||||
hb_codepoint_t *glyphs, unsigned int glyphs_len,
|
|
||||||
hb_face_t *face)
|
|
||||||
{
|
|
||||||
if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_BELOW_C;
|
|
||||||
if (indic_plan->blwf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_BELOW_C;
|
|
||||||
if (indic_plan->pstf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_POST_C;
|
|
||||||
return POS_BASE_C;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct feature_list_t {
|
struct feature_list_t {
|
||||||
hb_tag_t tag;
|
hb_tag_t tag;
|
||||||
|
@ -230,6 +180,76 @@ override_features_indic (hb_ot_shape_planner_t *plan)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct would_apply_feature_t
|
||||||
|
{
|
||||||
|
would_apply_feature_t (const hb_ot_map_t *map, hb_tag_t feature_tag)
|
||||||
|
{
|
||||||
|
map->get_stage_lookups (0/*GSUB*/,
|
||||||
|
map->get_feature_stage (0/*GSUB*/, feature_tag),
|
||||||
|
&lookups, &count);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool would_substitute (hb_codepoint_t *glyphs,
|
||||||
|
unsigned int glyphs_count,
|
||||||
|
hb_face_t *face) const
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (hb_ot_layout_would_substitute_lookup_fast (face, glyphs, glyphs_count, lookups[i].index))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const hb_ot_map_t::lookup_map_t *lookups;
|
||||||
|
unsigned int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct indic_shape_plan_t
|
||||||
|
{
|
||||||
|
indic_shape_plan_t (const hb_ot_shape_plan_t *plan) :
|
||||||
|
pref (&plan->map, HB_TAG('p','r','e','f')),
|
||||||
|
blwf (&plan->map, HB_TAG('b','l','w','f')),
|
||||||
|
pstf (&plan->map, HB_TAG('p','s','t','f')),
|
||||||
|
is_old_spec (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))) {}
|
||||||
|
|
||||||
|
would_apply_feature_t pref;
|
||||||
|
would_apply_feature_t blwf;
|
||||||
|
would_apply_feature_t pstf;
|
||||||
|
bool is_old_spec;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *
|
||||||
|
data_create_indic (const hb_ot_shape_plan_t *plan)
|
||||||
|
{
|
||||||
|
indic_shape_plan_t *data = (indic_shape_plan_t *) calloc (1, sizeof (indic_shape_plan_t));
|
||||||
|
if (unlikely (!data))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Mixing C++ and C, oh well... */
|
||||||
|
indic_shape_plan_t indic_plan (plan);
|
||||||
|
|
||||||
|
*data = indic_plan;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_destroy_indic (void *data)
|
||||||
|
{
|
||||||
|
free (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static indic_position_t
|
||||||
|
consonant_position_from_face (const indic_shape_plan_t *indic_plan,
|
||||||
|
hb_codepoint_t *glyphs, unsigned int glyphs_len,
|
||||||
|
hb_face_t *face)
|
||||||
|
{
|
||||||
|
if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_BELOW_C;
|
||||||
|
if (indic_plan->blwf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_BELOW_C;
|
||||||
|
if (indic_plan->pstf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_POST_C;
|
||||||
|
return POS_BASE_C;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
|
@ -278,9 +298,9 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
|
||||||
default: virama = 0; break;
|
default: virama = 0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
indic_shape_plan_t indic_plan (plan);
|
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
|
||||||
|
|
||||||
unsigned int consonant_pos = indic_plan.is_old_spec ? 0 : 1;
|
unsigned int consonant_pos = indic_plan->is_old_spec ? 0 : 1;
|
||||||
hb_codepoint_t glyphs[2];
|
hb_codepoint_t glyphs[2];
|
||||||
if (virama && font->get_glyph (virama, 0, &glyphs[1 - consonant_pos]))
|
if (virama && font->get_glyph (virama, 0, &glyphs[1 - consonant_pos]))
|
||||||
{
|
{
|
||||||
|
@ -291,7 +311,7 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (buffer->info[i].indic_position() == POS_BASE_C) {
|
if (buffer->info[i].indic_position() == POS_BASE_C) {
|
||||||
glyphs[consonant_pos] = buffer->info[i].codepoint;
|
glyphs[consonant_pos] = buffer->info[i].codepoint;
|
||||||
buffer->info[i].indic_position() = consonant_position_from_font (&indic_plan, glyphs, 2, face);
|
buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, glyphs, 2, face);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1086,6 +1106,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
|
||||||
"indic",
|
"indic",
|
||||||
collect_features_indic,
|
collect_features_indic,
|
||||||
override_features_indic,
|
override_features_indic,
|
||||||
|
data_create_indic,
|
||||||
|
data_destroy_indic,
|
||||||
NULL, /* normalization_preference */
|
NULL, /* normalization_preference */
|
||||||
setup_masks_indic,
|
setup_masks_indic,
|
||||||
false, /* zero_width_attached_marks */
|
false, /* zero_width_attached_marks */
|
||||||
|
|
|
@ -88,6 +88,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
|
||||||
"default",
|
"default",
|
||||||
collect_features_default,
|
collect_features_default,
|
||||||
NULL, /* override_features */
|
NULL, /* override_features */
|
||||||
|
NULL, /* data_create */
|
||||||
|
NULL, /* data_destroy */
|
||||||
normalization_preference_default,
|
normalization_preference_default,
|
||||||
NULL, /* setup_masks */
|
NULL, /* setup_masks */
|
||||||
true, /* zero_width_attached_marks */
|
true, /* zero_width_attached_marks */
|
||||||
|
@ -196,6 +198,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
|
||||||
"thai",
|
"thai",
|
||||||
NULL, /* collect_features */
|
NULL, /* collect_features */
|
||||||
NULL, /* override_features */
|
NULL, /* override_features */
|
||||||
|
NULL, /* data_create */
|
||||||
|
NULL, /* data_destroy */
|
||||||
NULL, /* normalization_preference */
|
NULL, /* normalization_preference */
|
||||||
setup_masks_thai,
|
setup_masks_thai,
|
||||||
true, /* zero_width_attached_marks */
|
true, /* zero_width_attached_marks */
|
||||||
|
|
|
@ -69,13 +69,27 @@ struct hb_ot_complex_shaper_t
|
||||||
*/
|
*/
|
||||||
void (*override_features) (hb_ot_shape_planner_t *plan);
|
void (*override_features) (hb_ot_shape_planner_t *plan);
|
||||||
|
|
||||||
|
|
||||||
|
/* data_create()
|
||||||
|
* Called at the end of shape_plan().
|
||||||
|
* Whatever shapers return will be accessible through plan->data later.
|
||||||
|
* If NULL is returned, means a plan failure.
|
||||||
|
* May be NULL. */
|
||||||
|
void *(*data_create) (const hb_ot_shape_plan_t *plan);
|
||||||
|
|
||||||
|
/* data_destroy()
|
||||||
|
* Called when the shape_plan is being destroyed.
|
||||||
|
* plan->data is passed here for destruction.
|
||||||
|
* If NULL is returned, means a plan failure.
|
||||||
|
* May be NULL. */
|
||||||
|
void (*data_destroy) (void *data);
|
||||||
|
|
||||||
/* normalization_preference()
|
/* normalization_preference()
|
||||||
* Called during shape().
|
* Called during shape().
|
||||||
*/
|
*/
|
||||||
hb_ot_shape_normalization_mode_t
|
hb_ot_shape_normalization_mode_t
|
||||||
(*normalization_preference) (const hb_ot_shape_plan_t *plan);
|
(*normalization_preference) (const hb_ot_shape_plan_t *plan);
|
||||||
|
|
||||||
|
|
||||||
/* setup_masks()
|
/* setup_masks()
|
||||||
* Called during shape().
|
* Called during shape().
|
||||||
* Shapers should use map to get feature masks and set on buffer.
|
* Shapers should use map to get feature masks and set on buffer.
|
||||||
|
|
|
@ -44,6 +44,7 @@ struct hb_ot_shape_plan_t
|
||||||
hb_segment_properties_t props;
|
hb_segment_properties_t props;
|
||||||
const struct hb_ot_complex_shaper_t *shaper;
|
const struct hb_ot_complex_shaper_t *shaper;
|
||||||
hb_ot_map_t map;
|
hb_ot_map_t map;
|
||||||
|
const void *data;
|
||||||
|
|
||||||
inline void substitute_closure (hb_face_t *face, hb_set_t *glyphs) const { map.substitute_closure (this, face, glyphs); }
|
inline void substitute_closure (hb_face_t *face, hb_set_t *glyphs) const { map.substitute_closure (this, face, glyphs); }
|
||||||
inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
|
inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
|
||||||
|
|
|
@ -167,8 +167,8 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
||||||
const hb_feature_t *user_features,
|
const hb_feature_t *user_features,
|
||||||
unsigned int num_user_features)
|
unsigned int num_user_features)
|
||||||
{
|
{
|
||||||
hb_ot_shape_plan_t *data = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
|
hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
|
||||||
if (unlikely (!data))
|
if (unlikely (!plan))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
hb_ot_shape_planner_t planner (shape_plan);
|
hb_ot_shape_planner_t planner (shape_plan);
|
||||||
|
@ -177,17 +177,26 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
||||||
|
|
||||||
hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
|
hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
|
||||||
|
|
||||||
planner.compile (*data);
|
planner.compile (*plan);
|
||||||
|
|
||||||
return data;
|
if (plan->shaper->data_create) {
|
||||||
|
plan->data = plan->shaper->data_create (plan);
|
||||||
|
if (unlikely (!plan->data))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *data)
|
_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
|
||||||
{
|
{
|
||||||
data->finish ();
|
if (plan->shaper->data_destroy)
|
||||||
|
plan->shaper->data_destroy (const_cast<void *> (plan->data));
|
||||||
|
|
||||||
free (data);
|
plan->finish ();
|
||||||
|
|
||||||
|
free (plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue