[indic] Adjust left-matra repositioning and Halant,ZWJ sequence

From the new code (first paragraph is from the OT Devanagari spec.):

  /*   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
   *     whether half-forms had been formed. Actual position for the matra is
   *     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.
   *
   * IMPLEMENTATION NOTES:
   *
   * It looks like the last sentence is wrong.  Testing, with Windows 7 Uniscribe
   * and Devanagari shows that the behavior is best described as:
   *
   * "If ZWJ follows this halant, matra is NOT repositioned after this halant.
   *  If ZWNJ follows this halant, position is moved after it."
   *
   * Test case, with Adobe Devanagari or Nirmala UI:
   *
   *   U+091F,U+094D,U+200C,U+092F,U+093F
   *   (Matra moves to the middle, after ZWNJ.)
   *
   *   U+091F,U+094D,U+200D,U+092F,U+093F
   *   (Matra does NOT move, stays to the left.)

Fixes https://github.com/harfbuzz/harfbuzz/issues/1070

Test case added with Adobe Devanagari.
This commit is contained in:
Behdad Esfahbod 2018-07-03 14:29:25 +04:30
parent 2cb075fe26
commit 9940504e93
3 changed files with 41 additions and 0 deletions

View File

@ -1127,6 +1127,24 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* defined as after last standalone halant glyph, after initial matra * defined as after last standalone halant glyph, after initial matra
* position and before the main consonant. If ZWJ or ZWNJ follow this * position and before the main consonant. If ZWJ or ZWNJ follow this
* halant, position is moved after it. * halant, position is moved after it.
*
* IMPLEMENTATION NOTES:
*
* It looks like the last sentence is wrong. Testing, with Windows 7 Uniscribe
* and Devanagari shows that the behavior is best described as:
*
* "If ZWJ follows this halant, matra is NOT repositioned after this halant.
* If ZWNJ follows this halant, position is moved after it."
*
* Test case, with Adobe Devanagari or Nirmala UI:
*
* U+091F,U+094D,U+200C,U+092F,U+093F
* (Matra moves to the middle, after ZWNJ.)
*
* U+091F,U+094D,U+200D,U+092F,U+093F
* (Matra does NOT move, stays to the left.)
*
* https://github.com/harfbuzz/harfbuzz/issues/1070
*/ */
if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */ if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */
@ -1140,6 +1158,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
*/ */
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL) if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
{ {
search:
while (new_pos > start && while (new_pos > start &&
!(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H))))) !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H)))))
new_pos--; new_pos--;
@ -1150,9 +1169,27 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (is_halant (info[new_pos]) && if (is_halant (info[new_pos]) &&
info[new_pos].indic_position() != POS_PRE_M) info[new_pos].indic_position() != POS_PRE_M)
{ {
#if 0 // See comment above
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
if (new_pos + 1 < end && is_joiner (info[new_pos + 1])) if (new_pos + 1 < end && is_joiner (info[new_pos + 1]))
new_pos++; new_pos++;
#endif
if (new_pos + 1 < end)
{
/* -> If ZWJ follows this halant, matra is NOT repositioned after this halant. */
if (info[new_pos + 1].indic_category() == OT_ZWJ)
{
/* Keep searching. */
if (new_pos > start)
{
new_pos--;
goto search;
}
}
/* -> If ZWNJ follows this halant, position is moved after it. */
if (info[new_pos + 1].indic_category() == OT_ZWNJ)
new_pos++;
}
} }
else else
new_pos = start; /* No move. */ new_pos = start; /* No move. */

View File

@ -1,2 +1,6 @@
../fonts/f443753e8ffe8e8aae606cfba158e00334b6efb1.ttf::U+179A,U+1784,U+17D2,U+179F,U+200C,U+17CA,U+17B8,U+0020:[uni179a=0+775|uni1784=1+1550|uni179f.sub=1+775|space=1+0|uni17ca=1+0|uni17b8=1@0,300+0|space=7+600] ../fonts/f443753e8ffe8e8aae606cfba158e00334b6efb1.ttf::U+179A,U+1784,U+17D2,U+179F,U+200C,U+17CA,U+17B8,U+0020:[uni179a=0+775|uni1784=1+1550|uni179f.sub=1+775|space=1+0|uni17ca=1+0|uni17b8=1@0,300+0|space=7+600]
../fonts/f443753e8ffe8e8aae606cfba158e00334b6efb1.ttf::U+179A,U+1784,U+17D2,U+179F,U+17CA,U+17B8:[uni179a=0+775|uni1784=1+1550|uni179f.sub=1+775|uni17bb=1@-75,-700+0|uni17b8=1+0] ../fonts/f443753e8ffe8e8aae606cfba158e00334b6efb1.ttf::U+179A,U+1784,U+17D2,U+179F,U+17CA,U+17B8:[uni179a=0+775|uni1784=1+1550|uni179f.sub=1+775|uni17bb=1@-75,-700+0|uni17b8=1+0]
../fonts/8116e5d8fedfbec74e45dc350d2416d810bed8c4.ttf:--font-funcs=ft:U+091F,U+094D,U+200C,U+092F,U+093F:[uni091F=0+876|uni094D=0@4,0+0|space=0+0|uni093F.750=3+397|uni092F=3+924]
../fonts/8116e5d8fedfbec74e45dc350d2416d810bed8c4.ttf:--font-funcs=ft:U+091F,U+094D,U+200D,U+092F,U+093F:[uni093F=0+398|uni091F=0+876|uni094D=0@4,0+0|space=0+0|uni092F=0+924]
../fonts/8116e5d8fedfbec74e45dc350d2416d810bed8c4.ttf:--font-funcs=ft:U+091F,U+094D,U+200D,U+091F,U+094D,U+200C,U+091F,U+094D,U+200D,U+092F,U+093F:[uni091F=0+876|uni094D=0@4,0+0|space=0+0|uni091F=3+876|uni094D=3@4,0+0|space=3+0|uni093F=6+398|uni091F=6+876|uni094D=6@4,0+0|space=6+0|uni092F=6+924]
../fonts/8116e5d8fedfbec74e45dc350d2416d810bed8c4.ttf:--font-funcs=ft:U+091F,U+094D,U+200D,U+091F,U+094D,U+200D,U+091F,U+094D,U+200D,U+092F,U+093F:[uni093F=0+398|uni091F=0+876|uni094D=0@4,0+0|space=0+0|uni091F=0+876|uni094D=0@4,0+0|space=0+0|uni091F=0+876|uni094D=0@4,0+0|space=0+0|uni092F=0+924]