[Indic] Reorder left matras to be closer to base

This commit is contained in:
Behdad Esfahbod 2012-05-10 12:53:53 +02:00
parent 1a1fa8c655
commit 4ac9e98d9d
2 changed files with 46 additions and 8 deletions

View File

@ -67,10 +67,6 @@ enum indic_position_t {
POS_LEFT_MATRA,
POS_PRE_C,
POS_BEFORE_HALFS,
POS_HALFS,
POS_BASE_C,
POS_ABOVE_C,
POS_BELOW_C,

View File

@ -462,14 +462,32 @@ static void
final_reordering_syllable (hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
hb_glyph_info_t *info = buffer->info;
/* 4. Final reordering:
*
* After the localized forms and basic shaping forms GSUB features have been
* applied (see below), the shaping engine performs some final glyph
* reordering before applying all the remaining font features to the entire
* cluster.
*
* o Reorder matras:
*/
/* Find base again */
unsigned int base = end;
for (unsigned int i = start; i < end; i++)
if (info[i].indic_position() == POS_BASE_C) {
base = i;
break;
}
if (base == start) {
/* There's no Reph, and no left Matra to reposition. Just merge the cluster
* and go home. */
buffer->merge_clusters (start, end);
return;
}
/* o Reorder matras:
*
* If a pre-base matra character had been reordered before applying basic
* features, the glyph can be moved closer to the main consonant based on
@ -477,8 +495,32 @@ final_reordering_syllable (hb_buffer_t *buffer,
* defined as after last standalone halant glyph, after initial matra
* position and before the main consonant. If ZWJ or ZWNJ follow this
* halant, position is moved after it.
*
* o Reorder reph:
*/
unsigned int new_matra_pos = base - 1;
while (new_matra_pos > start &&
!(FLAG (info[new_matra_pos].indic_category()) & (FLAG (OT_M) | FLAG (OT_H))))
new_matra_pos--;
/* If we found no Halant we are done. Otherwise... */
if (info[new_matra_pos].indic_category() == OT_H) {
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
if (new_matra_pos + 1 < end && is_joiner (info[new_matra_pos + 1]))
new_matra_pos++;
/* Now go see if there's actually any matras... */
for (unsigned int i = new_matra_pos; i > start; i--)
if (info[i - 1].indic_category () == OT_M)
{
unsigned int old_matra_pos = i - 1;
hb_glyph_info_t matra = info[old_matra_pos];
memmove (&info[old_matra_pos], &info[old_matra_pos + 1], (new_matra_pos - old_matra_pos) * sizeof (info[0]));
info[new_matra_pos] = matra;
new_matra_pos--;
}
}
/* o Reorder reph:
*
* Rephs original position is always at the beginning of the syllable,
* (i.e. it is not reordered at the character reordering stage). However,