Another issue for us to look at in Paris... writing it up now so we
don't forget.
It looks to me like we may need to constrain Indic GSUB features to
syllable boundaries more consistently (sadly). Failure to follow
Uniscribe on this is leading to some poor results with NotoSansTelugu.
Testcase:
U+0C38,U+0C42,U+0C15,U+0C4D,U+0C37,U+0C4D,U+0C2E
using NotoSansTelugu-Regular.ttf.
Expected:
[gid54=0+1437|gid61=0+1368|gid101=2+1065|gid536=2+827]
Current HB output:
[gid54=0+1437|gid61=0+1368|gid101=2+1065|gid494=2+530]
What seems to be happening:
Initially, the <0C4D, 0C2E> sequence is replaced with glyph 494, by
'blwf' (lookup 6).
Then glyph 494 is changed to glyph 536, by 'psts' contextual lookup 23,
which calls substitution lookup 24.
(So far so good.)
But then glyph 536 is changed back(!) to glyph 494, thanks to 'psts'
contextual lookup 25, which matches a backtrack context that extends
into the preceding syllable.
Note that if we remove the initial (two-character) syllable group, the
result is correct, as lookup 25 no longer applies:
U+0C15,U+0C4D,U+0C37,U+0C4D,U+0C2E
[gid101=0+1065|gid536=0+827]
So the problem arises because we don't allow the syllable boundary to
constrain the application of "presentation form" features such as 'psts'.
Possible patch is attached; this delays the clearing of the syllable
info until after all the GSUB indic features, not only the "basic" ones.
We do still need to clear syllables before GPOS, as it appears
positioning features like 'kern' do get applied across syllable
boundaries in Uniscribe.
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 68ed8f6..2dbcdd9 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -411,6 +411,10 @@ static void
final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
static void
collect_features_indic (hb_ot_shape_planner_t *plan)
@@ -436,6 +440,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
for (; i < INDIC_NUM_FEATURES; i++) {
map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
}
+ map->add_gsub_pause (clear_syllables);
}
static void
@@ -1543,15 +1548,25 @@ final_reordering (const hb_ot_shape_plan_t *plan,
}
final_reordering_syllable (plan, buffer, last, count);
- /* Zero syllables now... */
- for (unsigned int i = 0; i < count; i++)
- info[i].syllable() = 0;
-
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
}
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ if (unlikely (!count)) return;
+
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < count; i++)
+ info[i].syllable() = 0;
+}
+
+
static hb_ot_shape_normalization_mode_t
normalization_preference_indic (const hb_segment_properties_t *props HB_UNUSED)
{
_______________________________________________
HarfBuzz mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/harfbuzz