src/hb-ot-layout-gpos-table.hh | 15 ++++++--------- src/hb-ot-layout-gsub-table.hh | 26 +++++++++++++++++++++++++- src/hb-ot-layout-private.hh | 20 ++++++++++---------- 3 files changed, 41 insertions(+), 20 deletions(-)
New commits: commit 0aef425e25e2c58445157057f17ef18f695c5240 Author: Behdad Esfahbod <[email protected]> Date: Mon Jul 30 00:55:15 2012 -0400 [GSUB] Minor diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 83252c1..5945b0f 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1147,19 +1147,16 @@ struct MarkLigPosFormat1 unsigned int comp_count = lig_attach.rows; if (unlikely (!comp_count)) return TRACE_RETURN (false); - unsigned int comp_index; /* We must now check whether the ligature ID of the current mark glyph * is identical to the ligature ID of the found ligature. If yes, we * can directly use the component index. If not, we attach the mark * glyph to the last component of the ligature. */ - if (get_lig_id (c->buffer->info[j]) && - get_lig_id (c->buffer->info[j]) == get_lig_id (c->buffer->cur()) && - get_lig_comp (c->buffer->cur()) > 0) - { - comp_index = get_lig_comp (c->buffer->cur()) - 1; - if (comp_index >= comp_count) - comp_index = comp_count - 1; - } + unsigned int comp_index; + unsigned int lig_id = get_lig_id (c->buffer->info[j]); + unsigned int mark_id = get_lig_id (c->buffer->cur()); + unsigned int mark_comp = get_lig_comp (c->buffer->cur()); + if (lig_id && lig_id == mark_id && mark_comp > 0) + comp_index = MIN (comp_count, get_lig_comp (c->buffer->cur())) - 1; else comp_index = comp_count - 1; commit d1d69ec52e75a78575b620a1c456d528b6078170 Author: Behdad Esfahbod <[email protected]> Date: Mon Jul 30 00:51:47 2012 -0400 [GSUB] Don't ligate glyphs attached to different components of ligatures This concludes the mark-attachment vs ligating interaction fixes (for now). diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 0a3e9da..b5520ed 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]); } commit 4751dec8be05883483fd5f6b474ebd22583ae566 Author: Behdad Esfahbod <[email protected]> Date: Mon Jul 30 00:42:07 2012 -0400 Minor diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index b44737e..3138a1d 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -75,7 +75,7 @@ _hb_ot_layout_skip_mark (hb_face_t *face, * * - The ligature glyph and any marks in between all the same newly allocated * lig_id, - * - The ligature glyph will get lig_comp = 0 + * - The ligature glyph will get lig_num_comps set to the number of components * - The marks get lig_comp > 0, reflecting which component of the ligature * they were applied to. * - This is used in GPOS to attach marks to the right component of a ligature @@ -91,10 +91,11 @@ _hb_ot_layout_skip_mark (hb_face_t *face, * The numbers are also used in GPOS to do mark-to-mark positioning only * to marks that belong to the same component of a ligature in MarkMarPos. */ +#define IS_LIG_BASE 0x10 static inline void set_lig_props_for_ligature (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_num_comps) { - info.lig_props() = (lig_id << 5) | 0x10 | (lig_num_comps & 0x0F); + info.lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F); } static inline void set_lig_props_for_mark (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_comp) @@ -112,10 +113,15 @@ get_lig_id (const hb_glyph_info_t &info) { return info.lig_props() >> 5; } +static inline bool +is_a_ligature (const hb_glyph_info_t &info) +{ + return !!(info.lig_props() & IS_LIG_BASE); +} static inline unsigned int get_lig_comp (const hb_glyph_info_t &info) { - if (info.lig_props() & 0x10) + if (is_a_ligature (info)) return 0; else return info.lig_props() & 0x0F; @@ -123,17 +129,11 @@ get_lig_comp (const hb_glyph_info_t &info) static inline unsigned int get_lig_num_comps (const hb_glyph_info_t &info) { - if ((info.props_cache() & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE) && - info.lig_props() & 0x10) + if ((info.props_cache() & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE) && is_a_ligature (info)) return info.lig_props() & 0x0F; else return 1; } -static inline bool -is_a_ligature (const hb_glyph_info_t &info) -{ - return unlikely (get_lig_id (info) && ~get_lig_comp (info)); -} static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) { uint8_t lig_id = buffer->next_serial () & 0x07; commit f24bcfbed1f3b4f4f6311246bd870f73ad6ba750 Author: Behdad Esfahbod <[email protected]> Date: Mon Jul 30 00:39:00 2012 -0400 Minor diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 7c3c54c..0a3e9da 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -511,7 +511,7 @@ struct Ligature * for them and update them. * * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a - * 'clig' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature + * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligature * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to * the new ligature with a component value of 2. _______________________________________________ HarfBuzz mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/harfbuzz
