[Indic] Port reph handling logic to look into font features

...instead of using a hardcoded list of Ra characters.
This commit is contained in:
Behdad Esfahbod 2012-11-12 14:02:02 -08:00
parent 43149afbc0
commit f2c0f59043
1 changed files with 30 additions and 18 deletions

View File

@ -305,6 +305,7 @@ struct indic_shape_plan_t
bool is_old_spec; bool is_old_spec;
hb_codepoint_t virama_glyph; hb_codepoint_t virama_glyph;
would_substitute_feature_t rphf;
would_substitute_feature_t pref; would_substitute_feature_t pref;
would_substitute_feature_t blwf; would_substitute_feature_t blwf;
would_substitute_feature_t pstf; would_substitute_feature_t pstf;
@ -329,6 +330,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.get_chosen_script (0) & 0x000000FF) != '2'); indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.get_chosen_script (0) & 0x000000FF) != '2');
indic_plan->virama_glyph = (hb_codepoint_t) -1; indic_plan->virama_glyph = (hb_codepoint_t) -1;
indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'));
indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f')); indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'));
indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f')); indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'));
indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f')); indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'));
@ -430,7 +432,9 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */ * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
static void static void
initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end) unsigned int start, unsigned int end)
{ {
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
@ -461,18 +465,21 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
unsigned int limit = start; unsigned int limit = start;
if (indic_plan->mask_array[RPHF] && if (indic_plan->mask_array[RPHF] &&
start + 3 <= end && start + 3 <= end &&
info[start].indic_category() == OT_Ra &&
info[start + 1].indic_category() == OT_H &&
(/* TODO Handle other Reph modes. */ (/* TODO Handle other Reph modes. */
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) || (indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
(indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ) (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ)
)) ))
{
/* See if it matches the 'rphf' feature. */
hb_codepoint_t glyphs[2] = {info[start].codepoint, info[start + 1].codepoint};
if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face))
{ {
limit += 2; limit += 2;
while (limit < end && is_joiner (info[limit])) while (limit < end && is_joiner (info[limit]))
limit++; limit++;
base = start; base = start;
has_reph = true; has_reph = true;
}
}; };
switch (indic_plan->config->base_pos) switch (indic_plan->config->base_pos)
@ -770,15 +777,17 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
static void static void
initial_reordering_vowel_syllable (const hb_ot_shape_plan_t *plan, initial_reordering_vowel_syllable (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer, hb_buffer_t *buffer,
unsigned int start, unsigned int end) unsigned int start, unsigned int end)
{ {
/* We made the vowels look like consonants. So let's call the consonant logic! */ /* We made the vowels look like consonants. So let's call the consonant logic! */
initial_reordering_consonant_syllable (plan, buffer, start, end); initial_reordering_consonant_syllable (plan, face, buffer, start, end);
} }
static void static void
initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer, hb_buffer_t *buffer,
unsigned int start, unsigned int end) unsigned int start, unsigned int end)
{ {
@ -794,20 +803,22 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
return; return;
} }
initial_reordering_consonant_syllable (plan, buffer, start, end); initial_reordering_consonant_syllable (plan, face, buffer, start, end);
} }
static void static void
initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer, hb_buffer_t *buffer,
unsigned int start, unsigned int end) unsigned int start, unsigned int end)
{ {
/* We already inserted dotted-circles, so just call the standalone_cluster. */ /* We already inserted dotted-circles, so just call the standalone_cluster. */
initial_reordering_standalone_cluster (plan, buffer, start, end); initial_reordering_standalone_cluster (plan, face, buffer, start, end);
} }
static void static void
initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_face_t *face HB_UNUSED,
hb_buffer_t *buffer HB_UNUSED, hb_buffer_t *buffer HB_UNUSED,
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED) unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
{ {
@ -818,16 +829,17 @@ initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
static void static void
initial_reordering_syllable (const hb_ot_shape_plan_t *plan, initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer, hb_buffer_t *buffer,
unsigned int start, unsigned int end) unsigned int start, unsigned int end)
{ {
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type) { switch (syllable_type) {
case consonant_syllable: initial_reordering_consonant_syllable (plan, buffer, start, end); return; case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
case vowel_syllable: initial_reordering_vowel_syllable (plan, buffer, start, end); return; case vowel_syllable: initial_reordering_vowel_syllable (plan, face, buffer, start, end); return;
case standalone_cluster: initial_reordering_standalone_cluster (plan, buffer, start, end); return; case standalone_cluster: initial_reordering_standalone_cluster (plan, face, buffer, start, end); return;
case broken_cluster: initial_reordering_broken_cluster (plan, buffer, start, end); return; case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
case non_indic_cluster: initial_reordering_non_indic_cluster (plan, buffer, start, end); return; case non_indic_cluster: initial_reordering_non_indic_cluster (plan, face, buffer, start, end); return;
} }
} }
@ -895,11 +907,11 @@ initial_reordering (const hb_ot_shape_plan_t *plan,
unsigned int last_syllable = info[0].syllable(); unsigned int last_syllable = info[0].syllable();
for (unsigned int i = 1; i < count; i++) for (unsigned int i = 1; i < count; i++)
if (last_syllable != info[i].syllable()) { if (last_syllable != info[i].syllable()) {
initial_reordering_syllable (plan, buffer, last, i); initial_reordering_syllable (plan, font->face, buffer, last, i);
last = i; last = i;
last_syllable = info[last].syllable(); last_syllable = info[last].syllable();
} }
initial_reordering_syllable (plan, buffer, last, count); initial_reordering_syllable (plan, font->face, buffer, last, count);
} }
static void static void