From d1d69ec52e75a78575b620a1c456d528b6078170 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 30 Jul 2012 00:51:47 -0400 Subject: [PATCH] [GSUB] Don't ligate glyphs attached to different components of ligatures This concludes the mark-attachment vs ligating interaction fixes (for now). --- src/hb-ot-layout-gsub-table.hh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 0a3e9dae4..b5520edb3 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -518,6 +518,11 @@ struct Ligature * * This in fact happened to a font... See: * https://bugzilla.gnome.org/show_bug.cgi?id=437633 + * + * - Ligatures cannot be formed across glyphs attached to different components + * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and + * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. + * However, it would be wrong to ligate that SHADDA,FATHA sequence. */ bool is_mark_ligature = !!(c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK); @@ -525,6 +530,9 @@ struct Ligature unsigned int total_component_count = 0; total_component_count += get_lig_num_comps (c->buffer->cur()); + unsigned int first_lig_id = get_lig_id (c->buffer->cur()); + unsigned int first_lig_comp = get_lig_comp (c->buffer->cur()); + for (unsigned int i = 1; i < count; i++) { unsigned int property; @@ -533,6 +541,22 @@ struct Ligature if (likely (c->buffer->info[skippy_iter.idx].codepoint != component[i])) return TRACE_RETURN (false); + unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]); + unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]); + if (first_lig_id && first_lig_comp) { + /* If first component was attached to a previous ligature component, + * all subsequent components should be attached to the same ligature + * component, otherwise we shouldn't ligate them. */ + if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) + return TRACE_RETURN (false); + } else { + /* If first component was NOT attached to a previous ligature component, + * all subsequent components should also NOT be attached to any ligature + * component, otherwise we shouldn't ligate them. */ + if (this_lig_id && this_lig_comp) + return TRACE_RETURN (false); + } + is_mark_ligature = is_mark_ligature && (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK); total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]); }