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

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Jun 8 19:14:37 PDT 2012


 TODO                                 |    7 ---
 src/Makefile.am                      |    3 -
 src/check-internal-symbols.sh        |    2 
 src/check-static-inits.sh            |   33 ++++++++++++++
 src/hb-buffer-private.hh             |    3 -
 src/hb-buffer.cc                     |   81 ++++++++++++++++++-----------------
 src/hb-object-private.hh             |    2 
 src/hb-ot-layout-gpos-table.hh       |    7 ++-
 src/hb-ot-layout-gsub-table.hh       |   13 ++++-
 src/hb-ot-layout-gsubgpos-private.hh |   25 ++++++++--
 src/hb-ot-map.cc                     |    3 +
 src/hb-ot-shape-complex-misc.cc      |   11 ----
 src/hb-ot-shape-normalize.cc         |   11 +++-
 src/hb-ot-shape.cc                   |    5 +-
 14 files changed, 129 insertions(+), 77 deletions(-)

New commits:
commit 7b84c536c10ab90ed96a033d88e9ad232d46c5b8
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 22:04:23 2012 -0400

    In MarkBase attachment, only attach to first of a MultipleSubst sequence
    
    This is apparently what Uniscribe does.  Test case is:
    
      SEEN FATHA TEH ALEF
    
    with Arabic Typesetting.  Originally reported by Khaled Hosny.

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 49986ea..c9e10bd 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -955,7 +955,12 @@ struct MarkBasePosFormat1
     /* now we search backwards for a non-mark glyph */
     unsigned int property;
     hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
-    if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
+    do {
+      if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
+      /* We only want to attach to the first of a MultipleSubst sequence.  Reject others. */
+      if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break;
+      skippy_iter.reject ();
+    } while (1);
 
     /* The following assertion is too strong, so we've disabled it. */
     if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index d73bb29..4cf6150 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -144,6 +144,10 @@ struct hb_apply_context_t
     {
       return unlikely (num_items && idx + num_items >= end);
     }
+    inline bool reject (void)
+    {
+      num_items++;
+    }
     inline bool next (unsigned int *property_out,
 		      unsigned int lookup_props)
     {
@@ -189,6 +193,10 @@ struct hb_apply_context_t
     {
       return unlikely (idx < num_items);
     }
+    inline bool reject (void)
+    {
+      num_items++;
+    }
     inline bool prev (unsigned int *property_out,
 		      unsigned int lookup_props)
     {
commit ec57e0c5655ced5109c4638bf802772d336448fd
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 21:47:23 2012 -0400

    Set lig_comp for MultipleSubst components
    
    To be used for correct mark attachment to first component of a
    MultipleSubst output.  That's what Uniscribe does.

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 47c000d..ced6f32 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -214,8 +214,10 @@ struct Sequence
 
     unsigned int klass = c->property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE ? HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH : 0;
     unsigned int count = substitute.len;
-    for (unsigned int i = 0; i < count; i++)
+    for (unsigned int i = 0; i < count; i++) {
+      set_lig_props (c->buffer->cur(), 0, i);
       c->output_glyph (substitute.array[i], klass);
+    }
     c->buffer->skip_glyph ();
 
     return TRACE_RETURN (true);
commit e085fcf7ca302eb7802a032197c022819e7e7074
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 21:45:00 2012 -0400

    Remove unused buffer->replace_glyphs_be16

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index 4077bb3..39b6e5c 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -110,9 +110,6 @@ struct _hb_buffer_t {
   HB_INTERNAL void swap_buffers (void);
   HB_INTERNAL void clear_output (void);
   HB_INTERNAL void clear_positions (void);
-  HB_INTERNAL void replace_glyphs_be16 (unsigned int num_in,
-					unsigned int num_out,
-					const char *glyph_data_be);
   HB_INTERNAL void replace_glyphs (unsigned int num_in,
 				   unsigned int num_out,
 				   const hb_codepoint_t *glyph_data);
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 5c8b9e8..44571da 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -231,29 +231,6 @@ hb_buffer_t::swap_buffers (void)
 }
 
 void
-hb_buffer_t::replace_glyphs_be16 (unsigned int num_in,
-				  unsigned int num_out,
-				  const char *glyph_data_be)
-{
-  if (!make_room_for (num_in, num_out)) return;
-
-  merge_clusters (idx, idx + num_in);
-
-  hb_glyph_info_t orig_info = info[idx];
-  hb_glyph_info_t *pinfo = &out_info[out_len];
-  const unsigned char *data = (const unsigned char *) glyph_data_be;
-  for (unsigned int i = 0; i < num_out; i++)
-  {
-    *pinfo = orig_info;
-    pinfo->codepoint = (data[2*i] << 8) | data[2*i+1];
-    pinfo++;
-  }
-
-  idx  += num_in;
-  out_len += num_out;
-}
-
-void
 hb_buffer_t::replace_glyphs (unsigned int num_in,
 			     unsigned int num_out,
 			     const uint32_t *glyph_data)
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index bc8d9bc..d73bb29 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -233,14 +233,6 @@ struct hb_apply_context_t
     buffer->cur().props_cache() = klass; /*XXX if has gdef? */
     buffer->replace_glyph (glyph_index);
   }
-  inline void replace_glyphs_be16 (unsigned int num_in,
-				   unsigned int num_out,
-				   const char *glyph_data_be,
-				   unsigned int klass = 0) const
-  {
-    buffer->cur().props_cache() = klass; /* XXX if has gdef? */
-    buffer->replace_glyphs_be16 (num_in, num_out, glyph_data_be);
-  }
   inline void replace_glyphs (unsigned int num_in,
 			      unsigned int num_out,
 			      hb_codepoint_t *glyph_data,
commit 3ec77d6ae0510dc2c0ec64382c4948bc6e109844
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 21:44:06 2012 -0400

    Don't use replace_glyphs_be for MultipleSubst

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 41b88b7..47c000d 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -213,7 +213,10 @@ struct Sequence
     if (unlikely (!substitute.len)) return TRACE_RETURN (false);
 
     unsigned int klass = c->property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE ? HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH : 0;
-    c->replace_glyphs_be16 (1, substitute.len, (const char *) substitute.array, klass);
+    unsigned int count = substitute.len;
+    for (unsigned int i = 0; i < count; i++)
+      c->output_glyph (substitute.array[i], klass);
+    c->buffer->skip_glyph ();
 
     return TRACE_RETURN (true);
   }
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index a33bce6..bc8d9bc 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -221,7 +221,12 @@ struct hb_apply_context_t
   }
 
 
-
+  inline void output_glyph (hb_codepoint_t glyph_index,
+			    unsigned int klass = 0) const
+  {
+    buffer->cur().props_cache() = klass; /*XXX if has gdef? */
+    buffer->output_glyph (glyph_index);
+  }
   inline void replace_glyph (hb_codepoint_t glyph_index,
 			     unsigned int klass = 0) const
   {
commit 4b7192125ffd295091d6b3a0bdfca7011947c2ca
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 21:41:46 2012 -0400

    Minor

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 49ada88..41b88b7 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -502,7 +502,8 @@ struct Ligature
 
     if (skippy_iter.idx < c->buffer->idx + count) /* No input glyphs skipped */
     {
-      c->replace_glyphs_be16 (count, 1, (const char *) &ligGlyph, klass);
+      hb_codepoint_t lig_glyph = ligGlyph;
+      c->replace_glyphs (count, 1, &lig_glyph, klass);
     }
     else
     {
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 2554f42..a33bce6 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -236,6 +236,14 @@ struct hb_apply_context_t
     buffer->cur().props_cache() = klass; /* XXX if has gdef? */
     buffer->replace_glyphs_be16 (num_in, num_out, glyph_data_be);
   }
+  inline void replace_glyphs (unsigned int num_in,
+			      unsigned int num_out,
+			      hb_codepoint_t *glyph_data,
+			      unsigned int klass = 0) const
+  {
+    buffer->cur().props_cache() = klass; /* XXX if has gdef? */
+    buffer->replace_glyphs (num_in, num_out, glyph_data);
+  }
 };
 
 
commit 4508789f4b5e0ece5620d35598aeeb7ecbe3e3aa
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 21:32:43 2012 -0400

    Add test for static initializers and other C++ stuff

diff --git a/src/Makefile.am b/src/Makefile.am
index 344cc57..98c6cd5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -190,8 +190,9 @@ indic_LDADD = libharfbuzz.la $(HBLIBS)
 dist_check_SCRIPTS = \
 	check-c-linkage-decls.sh \
 	check-header-guards.sh \
-	check-internal-symbols.sh \
 	check-includes.sh \
+	check-internal-symbols.sh \
+	check-static-inits.sh \
 	$(NULL)
 
 if HAVE_ICU
diff --git a/src/check-static-inits.sh b/src/check-static-inits.sh
new file mode 100755
index 0000000..eb04a55
--- /dev/null
+++ b/src/check-static-inits.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+LC_ALL=C
+export LC_ALL
+
+test -z "$srcdir" && srcdir=.
+stat=0
+
+
+if which objdump 2>/dev/null >/dev/null; then
+	:
+else
+	echo "check-static-inits.sh: 'objdump' not found; skipping test"
+	exit 77
+fi
+
+echo "Checking that no object file has static initializers"
+for obj in .libs/*.o; do
+	if objdump -t "$obj" | grep '[.]ctors'; then
+		echo "Ouch, $obj has static initializers"
+		stat=1
+	fi
+done
+
+echo "Checking that no object file has lazy static C++ constructors/destructors"
+for obj in .libs/*.o; do
+	if objdump -t "$obj" | grep '__c'; then
+		echo "Ouch, $obj has lazy static C++ constructors/destructors"
+		stat=1
+	fi
+done
+
+exit $stat
commit 56bd259b9ac22dd98913c8ca2e2cf7b30b632373
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 21:29:18 2012 -0400

    Minor

diff --git a/src/check-internal-symbols.sh b/src/check-internal-symbols.sh
index a24a693..ba6a45d 100755
--- a/src/check-internal-symbols.sh
+++ b/src/check-internal-symbols.sh
@@ -18,7 +18,7 @@ tested=false
 for suffix in so; do
 	so=.libs/libharfbuzz.$suffix
 	if test -f "$so"; then
-		echo "Checking that we are exposing internal symbols"
+		echo "Checking that we are not exposing internal symbols"
 		if nm $so | grep ' T ' | grep -v ' T _fini\>\| T _init\>\| T hb_'; then
 			echo "Ouch, internal symbols exposed"
 			stat=1
commit 4538b47bf08e73e7f5cce6337df5fe154233c168
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 21:01:45 2012 -0400

    Remove done TODO items

diff --git a/TODO b/TODO
index 4a1ad19..c171c94 100644
--- a/TODO
+++ b/TODO
@@ -15,12 +15,7 @@ General fixes:
   * vkna,hkna etc for kana, etc
 
 - Move non-native direction and normalization handling to the generic non-OT
-  layer, such that uniscribe and other backends can use.
-
-- Uniscribe backend needs to enforce one direction only, otherwise cluster
-  values can confuse the user.
-
-- GSUB ligation should call merge_clusters().  Also other places.
+  layer, such that other backends can use (Uniscribe doesn't need this).
 
 - Convert NBSP into space glyph.
 
commit bc8357ea7b4c0d7c715aae353176434fb9460205
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 21:01:20 2012 -0400

    Merge clusters during normalization

diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc
index 562ba88..d4b0b27 100644
--- a/src/hb-ot-shape-normalize.cc
+++ b/src/hb-ot-shape-normalize.cc
@@ -259,12 +259,15 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
 	/* And the font has glyph for the composite. */
 	hb_font_get_glyph (font, composed, 0, &glyph))
     {
-      /* Composes. Modify starter and carry on. */
-      buffer->out_info[starter].codepoint = composed;
-      /* XXX update cluster */
+      /* Composes. */
+      buffer->next_glyph (); /* Copy to out-buffer. */
+      if (unlikely (buffer->in_error))
+        return;
+      buffer->merge_out_clusters (starter, buffer->out_len);
+      buffer->out_len--; /* Remove the second composble. */
+      buffer->out_info[starter].codepoint = composed; /* Modify starter and carry on. */
       _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode);
 
-      buffer->skip_glyph ();
       continue;
     }
 
commit fe3dabc08df7501010564f8844bd4d11771cc6a4
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:56:05 2012 -0400

    Minor

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 34d2300..5c8b9e8 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -416,7 +416,7 @@ void
 hb_buffer_t::merge_clusters (unsigned int start,
 			     unsigned int end)
 {
-  if (unlikely (start >= end))
+  if (unlikely (end - start < 2))
     return;
 
   unsigned int cluster = info[start].cluster;
@@ -444,7 +444,7 @@ void
 hb_buffer_t::merge_out_clusters (unsigned int start,
 				 unsigned int end)
 {
-  if (unlikely (start >= end))
+  if (unlikely (end - start < 2))
     return;
 
   unsigned int cluster = out_info[start].cluster;
commit e88e14421a33ca5bdfd76bc0b2f801fcb6e78911
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:55:21 2012 -0400

    Use merge_clusters instead of open-coding

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 8ccfea5..34d2300 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -237,13 +237,9 @@ hb_buffer_t::replace_glyphs_be16 (unsigned int num_in,
 {
   if (!make_room_for (num_in, num_out)) return;
 
-  hb_glyph_info_t orig_info = info[idx];
-  for (unsigned int i = 1; i < num_in; i++)
-  {
-    hb_glyph_info_t *inf = &info[idx + i];
-    orig_info.cluster = MIN (orig_info.cluster, inf->cluster);
-  }
+  merge_clusters (idx, idx + num_in);
 
+  hb_glyph_info_t orig_info = info[idx];
   hb_glyph_info_t *pinfo = &out_info[out_len];
   const unsigned char *data = (const unsigned char *) glyph_data_be;
   for (unsigned int i = 0; i < num_out; i++)
@@ -264,13 +260,9 @@ hb_buffer_t::replace_glyphs (unsigned int num_in,
 {
   if (!make_room_for (num_in, num_out)) return;
 
-  hb_glyph_info_t orig_info = info[idx];
-  for (unsigned int i = 1; i < num_in; i++)
-  {
-    hb_glyph_info_t *inf = &info[idx + i];
-    orig_info.cluster = MIN (orig_info.cluster, inf->cluster);
-  }
+  merge_clusters (idx, idx + num_in);
 
+  hb_glyph_info_t orig_info = info[idx];
   hb_glyph_info_t *pinfo = &out_info[out_len];
   for (unsigned int i = 0; i < num_out; i++)
   {
commit 330a2af3ff0e12c01b3b451357b8bdc83b2e9b47
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:40:02 2012 -0400

    Use merge_clusters when forming Unicode clusters

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 3a13bb5..60b028d 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -188,7 +188,7 @@ hb_form_clusters (hb_buffer_t *buffer)
 	(FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) |
 	 FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) |
 	 FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
-      buffer->info[i].cluster = buffer->info[i - 1].cluster; /* XXX do the min() here */
+      buffer->merge_clusters (i - 1, i + 1);
 }
 
 static void
@@ -405,6 +405,8 @@ hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
   HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0);
   HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1);
 
+  c->buffer->clear_output ();
+
   hb_set_unicode_props (c->buffer);
 
   hb_form_clusters (c->buffer);
commit bd300df9adf955c1e69b3783c1c061876940fb8b
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:35:18 2012 -0400

    Minor

diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 96d1bd3..e7f6eda 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -165,7 +165,7 @@ struct hb_object_header_t
 
   inline void trace (const char *function) const {
     if (unlikely (!this)) return;
-    /* XXX We cannot use DEBUG_MSG_FUNC here since that one currecntly only
+    /* TODO We cannot use DEBUG_MSG_FUNC here since that one currently only
      * prints the class name and throws away the template info. */
     DEBUG_MSG (OBJECT, (void *) this,
 	       "%s refcount=%d",
commit e51d2b6ed1c794ac28c5610bfd01dbc9fb383633
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:33:27 2012 -0400

    Extend into main buffer if extension hit end of out-buffer merging clusters

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 2a98497..8ccfea5 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -468,6 +468,11 @@ hb_buffer_t::merge_out_clusters (unsigned int start,
   while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster)
     end++;
 
+  /* If we hit the end of out-buffer, continue in buffer. */
+  if (end == out_len)
+    for (unsigned i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
+      info[i].cluster = cluster;
+
   for (unsigned int i = start; i < end; i++)
     out_info[i].cluster = cluster;
 }
diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc
index 748d4b3..52fbd6d 100644
--- a/src/hb-ot-shape-complex-misc.cc
+++ b/src/hb-ot-shape-complex-misc.cc
@@ -176,15 +176,6 @@ _hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map HB_UNUSED,
 	     sizeof (buffer->out_info[0]) * (end - start - 2));
     buffer->out_info[start] = t;
 
-    /* XXX Make this easier! */
-    /* Make cluster */
-    for (; buffer->idx < count;)
-      if (buffer->cur().cluster == buffer->prev().cluster)
-        buffer->next_glyph ();
-      else
-        break;
-    end = buffer->out_len;
-
     buffer->merge_out_clusters (start, end);
   }
   buffer->swap_buffers ();
commit 5ced012d9f58c51d557a835593c3277e35fe3b35
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:31:32 2012 -0400

    Extend end when merging clusters in out-buffer

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 38eb95f..2a98497 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -464,6 +464,10 @@ hb_buffer_t::merge_out_clusters (unsigned int start,
   while (start && out_info[start - 1].cluster == out_info[start].cluster)
     start--;
 
+  /* Extend end */
+  while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster)
+    end++;
+
   for (unsigned int i = start; i < end; i++)
     out_info[i].cluster = cluster;
 }
commit 72c0a1878313e7232d554bc226f4c6dc01418a95
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:30:03 2012 -0400

    Extend clusters backward in out-buffer

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index c3cf561..38eb95f 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -452,10 +452,18 @@ void
 hb_buffer_t::merge_out_clusters (unsigned int start,
 				 unsigned int end)
 {
+  if (unlikely (start >= end))
+    return;
+
   unsigned int cluster = out_info[start].cluster;
 
   for (unsigned int i = start + 1; i < end; i++)
     cluster = MIN (cluster, out_info[i].cluster);
+
+  /* Extend start */
+  while (start && out_info[start - 1].cluster == out_info[start].cluster)
+    start--;
+
   for (unsigned int i = start; i < end; i++)
     out_info[i].cluster = cluster;
 }
diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc
index d93d4c6..748d4b3 100644
--- a/src/hb-ot-shape-complex-misc.cc
+++ b/src/hb-ot-shape-complex-misc.cc
@@ -178,8 +178,6 @@ _hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map HB_UNUSED,
 
     /* XXX Make this easier! */
     /* Make cluster */
-    for (; start > 0 && buffer->out_info[start - 1].cluster == buffer->out_info[start].cluster; start--)
-      ;
     for (; buffer->idx < count;)
       if (buffer->cur().cluster == buffer->prev().cluster)
         buffer->next_glyph ();
commit cd5891493df06fdb92e1ae526d29dee8df250235
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:27:53 2012 -0400

    Extend clusters backwards, into the out-buffer too

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 8c7edd6..c3cf561 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -436,6 +436,15 @@ hb_buffer_t::merge_clusters (unsigned int start,
   while (end < len && info[end - 1].cluster == info[end].cluster)
     end++;
 
+  /* Extend start */
+  while (idx < start && info[start - 1].cluster == info[start].cluster)
+    start--;
+
+  /* If we hit the start of buffer, continue in out-buffer. */
+  if (idx == start)
+    for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
+      out_info[i - 1].cluster = cluster;
+
   for (unsigned int i = start; i < end; i++)
     info[i].cluster = cluster;
 }
commit 77471e037122548bfc08cacea6fbb472831c34f3
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:21:02 2012 -0400

    Clear output buffer before calling GSUB pause functions

diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index bebf3ed..d34160c 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -88,6 +88,9 @@ void hb_ot_map_t::apply (unsigned int table_index,
     for (; i < pause->num_lookups; i++)
       apply_lookup_func (face_or_font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
 
+    if (table_index == 0)
+      buffer->clear_output ();
+
     pause->callback.func (this, face_or_font, buffer, pause->callback.user_data);
   }
 
commit cafa6f372721fd6b0a7c0da68b9421d3e94931bc
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:17:10 2012 -0400

    When merging clusters, extend the end

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 9c9b32e..8c7edd6 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -424,23 +424,31 @@ void
 hb_buffer_t::merge_clusters (unsigned int start,
 			     unsigned int end)
 {
-  unsigned int cluster = this->info[start].cluster;
+  if (unlikely (start >= end))
+    return;
+
+  unsigned int cluster = info[start].cluster;
 
   for (unsigned int i = start + 1; i < end; i++)
-    cluster = MIN (cluster, this->info[i].cluster);
+    cluster = MIN (cluster, info[i].cluster);
+
+  /* Extend end */
+  while (end < len && info[end - 1].cluster == info[end].cluster)
+    end++;
+
   for (unsigned int i = start; i < end; i++)
-    this->info[i].cluster = cluster;
+    info[i].cluster = cluster;
 }
 void
 hb_buffer_t::merge_out_clusters (unsigned int start,
 				 unsigned int end)
 {
-  unsigned int cluster = this->out_info[start].cluster;
+  unsigned int cluster = out_info[start].cluster;
 
   for (unsigned int i = start + 1; i < end; i++)
-    cluster = MIN (cluster, this->out_info[i].cluster);
+    cluster = MIN (cluster, out_info[i].cluster);
   for (unsigned int i = start; i < end; i++)
-    this->out_info[i].cluster = cluster;
+    out_info[i].cluster = cluster;
 }
 
 void
commit 28ce5fa454b54f728044ee12a9dbe7d016783d4a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 20:13:56 2012 -0400

    Merge clusters when ligating

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index b10f9b6..49ada88 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -506,6 +506,7 @@ struct Ligature
     }
     else
     {
+      c->buffer->merge_clusters (c->buffer->idx, skippy_iter.idx + 1);
       c->replace_glyph (ligGlyph);
 
       /* Now we must do a second loop to copy the skipped glyphs to
commit 2bb1761ccb7d300744ced6427165f4ea75ddf96c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 19:29:44 2012 -0400

    Minor, use next_glyph()

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 4229f32..b10f9b6 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -520,7 +520,7 @@ struct Ligature
 	while (c->should_mark_skip_current_glyph ())
 	{
 	  set_lig_props (c->buffer->cur(),  lig_id, i);
-	  c->replace_glyph (c->buffer->cur().codepoint);
+	  c->buffer->next_glyph ();
 	}
 
 	/* Skip the base glyph */
commit 5f68f8675e5ccaee91f5a90d86bc3b022b9a54e4
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 8 19:23:43 2012 -0400

    Minor

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 19cf680..3a13bb5 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -383,6 +383,7 @@ hb_hide_zerowidth (hb_ot_shape_context_t *c)
 
   unsigned int count = c->buffer->len;
   for (unsigned int i = 0; i < count; i++)
+    /* TODO Do this if no ligature was formed? */
     if (unlikely (_hb_glyph_info_is_zero_width (&c->buffer->info[i]))) {
       c->buffer->info[i].codepoint = space;
       c->buffer->pos[i].x_advance = 0;



More information about the HarfBuzz mailing list