[Indic] Do Reph repositioning in final reordering like the spec says

This introduced a failure, which we tracked down to a test case like this:

  U+092E,U+094B,U+094D,U+0930

The final character is a Ra that should be put in a syllable of it's
own.  And we do.  But it will interact with the Halant before it.  So
now we finally are convinced that we have to limit features to syllable
boundaries.  That's coming after lunch!
This commit is contained in:
Behdad Esfahbod 2012-05-10 13:45:52 +02:00
parent 4705a70269
commit dbb105883c
2 changed files with 64 additions and 41 deletions

View File

@ -74,8 +74,6 @@ enum indic_position_t {
POS_MATRAS,
POS_REPH,
POS_SMVD
};

View File

@ -332,10 +332,8 @@ initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buff
info[base].indic_position() = POS_BASE_C;
/* Handle beginning Ra */
if (has_reph) {
info[start].indic_position() = POS_REPH;
info[start].mask = mask_array[RPHF];
}
if (has_reph)
info[start].indic_position() = POS_RA_TO_BECOME_REPH;
/* For old-style Indic script tags, move the first post-base Halant after
* last consonant. */
@ -382,6 +380,10 @@ initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buff
{
hb_mask_t mask;
/* Reph */
if (has_reph)
info[start].mask = mask_array[RPHF];
/* Pre-base */
mask = mask_array[HALF] | mask_array[AKHN] | mask_array[CJCT];
for (i = start; i < base; i++)
@ -530,8 +532,16 @@ final_reordering_syllable (hb_buffer_t *buffer,
* it will be reordered according to the basic-forms shaping results.
* Possible positions for reph, depending on the script, are; after main,
* before post-base consonant forms, and after post-base consonant forms.
*
* 1. If reph should be positioned after post-base consonant forms,
*/
/* If there's anything after the Ra that has the REPH pos, it ought to be halant.
* Which means that the font has failed to ligate the Reph. In which case, we
* shouldn't move. */
if (start + 1 < end &&
info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
info[start + 1].indic_position() != POS_RA_TO_BECOME_REPH)
{
/* 1. If reph should be positioned after post-base consonant forms,
* proceed to step 5.
*
* 2. If the reph repositioning class is not after post-base: target
@ -563,8 +573,23 @@ final_reordering_syllable (hb_buffer_t *buffer,
* post-main position.
*
* 6. Otherwise, reorder reph to the end of the syllable.
*
* o Reorder pre-base reordering consonants:
*/
start_of_last_cluster = start; /* Yay, one big cluster! */
/* Now let's go shopping for a position. */
unsigned int new_reph_pos = end - 1;
while (new_reph_pos > start && (FLAG (info[new_reph_pos].indic_position()) & (FLAG (POS_SMVD))))
new_reph_pos--;
/* Move */
hb_glyph_info_t reph = info[start];
memmove (&info[start], &info[start + 1], (new_reph_pos - start) * sizeof (info[0]));
info[new_reph_pos] = reph;
}
/* o Reorder pre-base reordering consonants:
*
* If a pre-base reordering consonant is found, reorder it according to
* the following rules: