From 4ac9e98d9d2ea973dd612dc4063cf78496c643a0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 10 May 2012 12:53:53 +0200 Subject: [PATCH] [Indic] Reorder left matras to be closer to base --- src/hb-ot-shape-complex-indic-private.hh | 4 -- src/hb-ot-shape-complex-indic.cc | 50 ++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/hb-ot-shape-complex-indic-private.hh b/src/hb-ot-shape-complex-indic-private.hh index 681391ea0..8f5144e38 100644 --- a/src/hb-ot-shape-complex-indic-private.hh +++ b/src/hb-ot-shape-complex-indic-private.hh @@ -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, diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 67628ae3d..ad8b967b2 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -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: * * Reph’s original position is always at the beginning of the syllable, * (i.e. it is not reordered at the character reordering stage). However,