[HarfBuzz] harfbuzz-ng: Branch 'master' - 4 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Sun Jul 29 21:55:19 PDT 2012


 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 <behdad at behdad.org>
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 <behdad at behdad.org>
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 <behdad at behdad.org>
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 <behdad at behdad.org>
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.



More information about the HarfBuzz mailing list