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

Behdad Esfahbod behdad at kemper.freedesktop.org
Thu Aug 9 19:34:39 PDT 2012


 src/hb-ot-layout-common-private.hh       |    1 
 src/hb-ot-layout-gsubgpos-private.hh     |    2 
 src/hb-ot-layout-private.hh              |    6 
 src/hb-ot-shape-complex-arabic.cc        |    2 
 src/hb-ot-shape-complex-indic-private.hh |    4 
 src/hb-ot-shape-complex-private.hh       |    5 
 src/hb-ot-shape-fallback.cc              |   38 +++++
 src/hb-ot-shape-normalize-private.hh     |    2 
 src/hb-ot-shape-normalize.cc             |   88 ++++++++++---
 src/hb-ot-shape-private.hh               |    4 
 src/hb-ot-shape.cc                       |  198 +++++++++++++++----------------
 src/hb-unicode-private.hh                |    7 -
 src/hb-unicode.cc                        |    2 
 13 files changed, 219 insertions(+), 140 deletions(-)

New commits:
commit b00321ea78793d9b3592b5173a9800e6322424fe
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 9 22:33:32 2012 -0400

    [OT] Avoid calling get_glyph() twice
    
    Essentially move the glyph mapping to normalization process.
    The effect on Devanagari is small (but observable).  Should be more
    observable in simple text, like ASCII.

diff --git a/src/hb-ot-shape-normalize-private.hh b/src/hb-ot-shape-normalize-private.hh
index f222c07..462b87d 100644
--- a/src/hb-ot-shape-normalize-private.hh
+++ b/src/hb-ot-shape-normalize-private.hh
@@ -32,6 +32,8 @@
 #include "hb-font.h"
 #include "hb-buffer.h"
 
+/* buffer var allocations, used during the normalization process */
+#define glyph_index()	var1.u32
 
 enum hb_ot_shape_normalization_mode_t {
   HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc
index ccaf1d7..e6092d6 100644
--- a/src/hb-ot-shape-normalize.cc
+++ b/src/hb-ot-shape-normalize.cc
@@ -258,16 +258,25 @@ compose_func (hb_unicode_funcs_t *unicode,
   return found;
 }
 
+
+static inline void
+set_glyph (hb_glyph_info_t &info, hb_font_t *font)
+{
+  hb_font_get_glyph (font, info.codepoint, 0, &info.glyph_index());
+}
+
 static inline void
-output_char (hb_buffer_t *buffer, hb_codepoint_t unichar)
+output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
 {
+  buffer->cur().glyph_index() = glyph;
   buffer->output_glyph (unichar);
   _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer->unicode);
 }
 
 static inline void
-next_char (hb_buffer_t *buffer)
+next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
 {
+  buffer->cur().glyph_index() = glyph;
   buffer->next_glyph ();
 }
 
@@ -282,31 +291,31 @@ decompose (hb_font_t *font, hb_buffer_t *buffer,
 	   bool shortest,
 	   hb_codepoint_t ab)
 {
-  hb_codepoint_t a, b, glyph;
+  hb_codepoint_t a, b, a_glyph, b_glyph;
 
   if (!decompose_func (buffer->unicode, ab, &a, &b) ||
-      (b && !font->get_glyph (b, 0, &glyph)))
+      (b && !font->get_glyph (b, 0, &b_glyph)))
     return false;
 
-  bool has_a = font->get_glyph (a, 0, &glyph);
+  bool has_a = font->get_glyph (a, 0, &a_glyph);
   if (shortest && has_a) {
     /* Output a and b */
-    output_char (buffer, a);
+    output_char (buffer, a, a_glyph);
     if (b)
-      output_char (buffer, b);
+      output_char (buffer, b, b_glyph);
     return true;
   }
 
   if (decompose (font, buffer, shortest, a)) {
     if (b)
-      output_char (buffer, b);
+      output_char (buffer, b, b_glyph);
     return true;
   }
 
   if (has_a) {
-    output_char (buffer, a);
+    output_char (buffer, a, a_glyph);
     if (b)
-      output_char (buffer, b);
+      output_char (buffer, b, b_glyph);
     return true;
   }
 
@@ -319,18 +328,18 @@ decompose_compatibility (hb_font_t *font, hb_buffer_t *buffer,
 {
   unsigned int len, i;
   hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN];
+  hb_codepoint_t glyphs[HB_UNICODE_MAX_DECOMPOSITION_LEN];
 
   len = buffer->unicode->decompose_compatibility (u, decomposed);
   if (!len)
     return false;
 
-  hb_codepoint_t glyph;
   for (i = 0; i < len; i++)
-    if (!font->get_glyph (decomposed[i], 0, &glyph))
+    if (!font->get_glyph (decomposed[i], 0, &glyphs[i]))
       return false;
 
   for (i = 0; i < len; i++)
-    output_char (buffer, decomposed[i]);
+    output_char (buffer, decomposed[i], glyphs[i]);
 
   return true;
 }
@@ -343,15 +352,38 @@ decompose_current_character (hb_font_t *font, hb_buffer_t *buffer,
 
   /* Kind of a cute waterfall here... */
   if (shortest && font->get_glyph (buffer->cur().codepoint, 0, &glyph))
-    next_char (buffer);
+    next_char (buffer, glyph);
   else if (decompose (font, buffer, shortest, buffer->cur().codepoint))
     skip_char (buffer);
   else if (!shortest && font->get_glyph (buffer->cur().codepoint, 0, &glyph))
-    next_char (buffer);
+    next_char (buffer, glyph);
   else if (decompose_compatibility (font, buffer, buffer->cur().codepoint))
     skip_char (buffer);
-  else
-    next_char (buffer);
+  else {
+    /* A glyph-not-found case... */
+    font->get_glyph (buffer->cur().codepoint, 0, &glyph);
+    next_char (buffer, glyph);
+  }
+}
+
+static inline void
+handle_variation_selector_cluster (hb_font_t *font, hb_buffer_t *buffer,
+				   unsigned int end)
+{
+  for (; buffer->idx < end - 1;) {
+    if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
+      /* The next two lines are some ugly lines... But work. */
+      font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index());
+      buffer->replace_glyphs (2, 1, &buffer->cur().codepoint);
+    } else {
+      set_glyph (buffer->cur(), font);
+      buffer->next_glyph ();
+    }
+  }
+  if (likely (buffer->idx < end)) {
+    set_glyph (buffer->cur(), font);
+    buffer->next_glyph ();
+  }
 }
 
 static void
@@ -361,8 +393,7 @@ decompose_multi_char_cluster (hb_font_t *font, hb_buffer_t *buffer,
   /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
   for (unsigned int i = buffer->idx; i < end; i++)
     if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
-      while (buffer->idx < end)
-	next_char (buffer);
+      handle_variation_selector_cluster (font, buffer, end);
       return;
     }
 
@@ -457,7 +488,7 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
   buffer->clear_output ();
   count = buffer->len;
   unsigned int starter = 0;
-  next_char (buffer);
+  buffer->next_glyph ();
   while (buffer->idx < count)
   {
     hb_codepoint_t composed, glyph;
@@ -478,19 +509,20 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
 	font->get_glyph (composed, 0, &glyph))
     {
       /* Composes. */
-      next_char (buffer); /* Copy to out-buffer. */
+      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 composable. */
       buffer->out_info[starter].codepoint = composed; /* Modify starter and carry on. */
+      set_glyph (buffer->out_info[starter], font);
       _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode);
 
       continue;
     }
 
     /* Blocked, or doesn't compose. */
-    next_char (buffer);
+    buffer->next_glyph ();
 
     if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
       starter = buffer->out_len - 1;
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index b4745c5..2062102 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -308,28 +308,12 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
 }
 
 static inline void
-hb_ot_map_glyphs (hb_font_t    *font,
-		  hb_buffer_t  *buffer)
+hb_ot_map_glyphs_fast (hb_buffer_t  *buffer)
 {
-  hb_codepoint_t glyph;
-
-  buffer->clear_output ();
-
-  unsigned int count = buffer->len - 1;
-  for (buffer->idx = 0; buffer->idx < count;) {
-    if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
-      font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &glyph);
-      buffer->replace_glyphs (2, 1, &glyph);
-    } else {
-      font->get_glyph (buffer->cur().codepoint, 0, &glyph);
-      buffer->replace_glyph (glyph);
-    }
-  }
-  if (likely (buffer->idx < buffer->len)) {
-    font->get_glyph (buffer->cur().codepoint, 0, &glyph);
-    buffer->replace_glyph (glyph);
-  }
-  buffer->swap_buffers ();
+  /* Normalization process sets up glyph_index(), we just copy it. */
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    buffer->info[i].codepoint = buffer->info[i].glyph_index();
 }
 
 static inline void
@@ -337,6 +321,8 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
 {
   hb_ot_mirror_chars (c);
 
+  HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index);
+
   _hb_ot_shape_normalize (c->font, c->buffer,
 			  c->plan->shaper->normalization_preference ?
 			  c->plan->shaper->normalization_preference (c->plan) :
@@ -344,7 +330,9 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
 
   hb_ot_shape_setup_masks (c);
 
-  hb_ot_map_glyphs (c->font, c->buffer);
+  hb_ot_map_glyphs_fast (c->buffer);
+
+  HB_BUFFER_DEALLOCATE_VAR (c->buffer, glyph_index);
 }
 
 static inline void
@@ -558,6 +546,16 @@ _hb_ot_shape (hb_shape_plan_t    *shape_plan,
 }
 
 
+
+static inline void
+hb_ot_map_glyphs_dumb (hb_font_t    *font,
+		       hb_buffer_t  *buffer)
+{
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    font->get_glyph (buffer->cur().codepoint, 0, &buffer->cur().codepoint);
+}
+
 void
 hb_ot_shape_glyphs_closure (hb_font_t          *font,
 			    hb_buffer_t        *buffer,
@@ -574,7 +572,7 @@ hb_ot_shape_glyphs_closure (hb_font_t          *font,
 
   /* TODO: normalization? have shapers do closure()? */
   /* TODO: Deal with mirrored chars? */
-  hb_ot_map_glyphs (font, buffer);
+  hb_ot_map_glyphs_dumb (font, buffer);
 
   /* Seed it.  It's user's responsibility to have cleard glyphs
    * if that's what they desire. */
commit 12c0875eafa4bd92db650e5acca046d99594d1e6
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 9 22:00:53 2012 -0400

    [OT] Remove redundant check

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 0fab82b..b4745c5 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -279,7 +279,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
   for (unsigned int i = 0; i < count; i++) {
     hb_codepoint_t codepoint = unicode->mirroring (c->buffer->info[i].codepoint);
     if (likely (codepoint == c->buffer->info[i].codepoint))
-      c->buffer->info[i].mask |= rtlm_mask; /* TODO this should be moved to before setting user-feature masks */
+      c->buffer->info[i].mask |= rtlm_mask;
     else
       c->buffer->info[i].codepoint = codepoint;
   }
@@ -313,9 +313,6 @@ hb_ot_map_glyphs (hb_font_t    *font,
 {
   hb_codepoint_t glyph;
 
-  if (unlikely (!buffer->len))
-    return;
-
   buffer->clear_output ();
 
   unsigned int count = buffer->len - 1;
commit 5c60b70c89b4e0a6512d9fd1ab5394dd76feb742
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 9 21:58:07 2012 -0400

    [OT] More code shuffling around
    
    Preparing for merging map_glyphs() and normalize().

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index d1e1d6c..0fab82b 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -217,34 +217,13 @@ struct hb_ot_shape_context_t
 
   /* Transient stuff */
   hb_direction_t target_direction;
-  hb_bool_t applied_position_complex;
 };
 
-static void
-hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
-{
-  hb_ot_map_t *map = &c->plan->map;
-
-  hb_mask_t global_mask = map->get_global_mask ();
-  c->buffer->reset_masks (global_mask);
-
-  if (c->plan->shaper->setup_masks)
-    c->plan->shaper->setup_masks (c->plan, c->buffer, c->font);
-
-  for (unsigned int i = 0; i < c->num_user_features; i++)
-  {
-    const hb_feature_t *feature = &c->user_features[i];
-    if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
-      unsigned int shift;
-      hb_mask_t mask = map->get_mask (feature->tag, &shift);
-      c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
-    }
-  }
-}
 
 
 /* Main shaper */
 
+
 /* Prepare */
 
 static void
@@ -287,14 +266,13 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
 
 /* Substitute */
 
-static void
-hb_mirror_chars (hb_ot_shape_context_t *c)
+static inline void
+hb_ot_mirror_chars (hb_ot_shape_context_t *c)
 {
-  hb_unicode_funcs_t *unicode = c->buffer->unicode;
-
   if (HB_DIRECTION_IS_FORWARD (c->target_direction))
     return;
 
+  hb_unicode_funcs_t *unicode = c->buffer->unicode;
   hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m'));
 
   unsigned int count = c->buffer->len;
@@ -307,9 +285,31 @@ hb_mirror_chars (hb_ot_shape_context_t *c)
   }
 }
 
-static void
-hb_map_glyphs (hb_font_t    *font,
-	       hb_buffer_t  *buffer)
+static inline void
+hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
+{
+  hb_ot_map_t *map = &c->plan->map;
+
+  hb_mask_t global_mask = map->get_global_mask ();
+  c->buffer->reset_masks (global_mask);
+
+  if (c->plan->shaper->setup_masks)
+    c->plan->shaper->setup_masks (c->plan, c->buffer, c->font);
+
+  for (unsigned int i = 0; i < c->num_user_features; i++)
+  {
+    const hb_feature_t *feature = &c->user_features[i];
+    if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
+      unsigned int shift;
+      hb_mask_t mask = map->get_mask (feature->tag, &shift);
+      c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
+    }
+  }
+}
+
+static inline void
+hb_ot_map_glyphs (hb_font_t    *font,
+		  hb_buffer_t  *buffer)
 {
   hb_codepoint_t glyph;
 
@@ -335,15 +335,22 @@ hb_map_glyphs (hb_font_t    *font,
   buffer->swap_buffers ();
 }
 
-static void
-hb_substitute_default (hb_ot_shape_context_t *c)
+static inline void
+hb_ot_substitute_default (hb_ot_shape_context_t *c)
 {
-  hb_mirror_chars (c);
+  hb_ot_mirror_chars (c);
+
+  _hb_ot_shape_normalize (c->font, c->buffer,
+			  c->plan->shaper->normalization_preference ?
+			  c->plan->shaper->normalization_preference (c->plan) :
+			  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT);
+
+  hb_ot_shape_setup_masks (c);
 
-  hb_map_glyphs (c->font, c->buffer);
+  hb_ot_map_glyphs (c->font, c->buffer);
 }
 
-static void
+static inline void
 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
 {
   unsigned int count = c->buffer->len;
@@ -354,7 +361,7 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
 }
 
 
-static void
+static inline void
 hb_ot_substitute_complex (hb_ot_shape_context_t *c)
 {
   hb_ot_layout_substitute_start (c->font, c->buffer);
@@ -370,11 +377,17 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
   return;
 }
 
+static inline void
+hb_ot_substitute (hb_ot_shape_context_t *c)
+{
+  hb_ot_substitute_default (c);
+  hb_ot_substitute_complex (c);
+}
 
 /* Position */
 
-static void
-hb_position_default (hb_ot_shape_context_t *c)
+static inline void
+hb_ot_position_default (hb_ot_shape_context_t *c)
 {
   hb_ot_layout_position_start (c->font, c->buffer);
 
@@ -391,9 +404,10 @@ hb_position_default (hb_ot_shape_context_t *c)
   }
 }
 
-static void
+static inline bool
 hb_ot_position_complex (hb_ot_shape_context_t *c)
 {
+  bool ret = false;
 
   if (hb_ot_layout_has_positioning (c->face))
   {
@@ -416,22 +430,22 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
 						    &c->buffer->pos[i].y_offset);
     }
 
-    c->applied_position_complex = true;
+    ret = true;
   }
 
   hb_ot_layout_position_finish (c->font, c->buffer, c->plan->shaper->zero_width_attached_marks);
 
-  return;
+  return ret;
 }
 
-static void
-hb_position_complex_fallback (hb_ot_shape_context_t *c)
+static inline void
+hb_ot_position_complex_fallback (hb_ot_shape_context_t *c)
 {
   _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
 }
 
-static void
-hb_truetype_kern (hb_ot_shape_context_t *c)
+static inline void
+hb_ot_truetype_kern (hb_ot_shape_context_t *c)
 {
   /* TODO Check for kern=0 */
   unsigned int count = c->buffer->len;
@@ -455,14 +469,34 @@ hb_truetype_kern (hb_ot_shape_context_t *c)
   }
 }
 
-static void
+static inline void
 hb_position_complex_fallback_visual (hb_ot_shape_context_t *c)
 {
-  hb_truetype_kern (c);
+  hb_ot_truetype_kern (c);
+}
+
+static inline void
+hb_ot_position (hb_ot_shape_context_t *c)
+{
+  hb_ot_position_default (c);
+
+  hb_bool_t fallback = !hb_ot_position_complex (c);
+
+  if (fallback)
+    hb_ot_position_complex_fallback (c);
+
+  if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
+    hb_buffer_reverse (c->buffer);
+
+  if (fallback)
+    hb_position_complex_fallback_visual (c);
 }
 
+
+/* Post-process */
+
 static void
-hb_hide_zerowidth (hb_ot_shape_context_t *c)
+hb_ot_hide_zerowidth (hb_ot_shape_context_t *c)
 {
   hb_codepoint_t space;
   if (!c->font->get_glyph (' ', 0, &space))
@@ -479,7 +513,7 @@ hb_hide_zerowidth (hb_ot_shape_context_t *c)
 }
 
 
-/* Do it! */
+/* Pull it all together! */
 
 static void
 hb_ot_shape_internal (hb_ot_shape_context_t *c)
@@ -495,43 +529,14 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
   c->buffer->clear_output ();
 
   hb_set_unicode_props (c->buffer);
-
   hb_form_clusters (c->buffer);
 
   hb_ensure_native_direction (c->buffer);
 
-  _hb_ot_shape_normalize (c->font, c->buffer,
-			  c->plan->shaper->normalization_preference ?
-			  c->plan->shaper->normalization_preference (c->plan) :
-			  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT);
-
-  hb_ot_shape_setup_masks (c);
-
-  /* SUBSTITUTE */
-  {
-    hb_substitute_default (c);
-
-    hb_ot_substitute_complex (c);
-  }
-
-  /* POSITION */
-  {
-    hb_position_default (c);
-
-    hb_ot_position_complex (c);
-
-    hb_bool_t position_fallback = !c->applied_position_complex;
-    if (position_fallback)
-      hb_position_complex_fallback (c);
-
-    if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
-      hb_buffer_reverse (c->buffer);
-
-    if (position_fallback)
-      hb_position_complex_fallback_visual (c);
-  }
+  hb_ot_substitute (c);
+  hb_ot_position (c);
 
-  hb_hide_zerowidth (c);
+  hb_ot_hide_zerowidth (c);
 
   HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
   HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);
@@ -572,7 +577,7 @@ hb_ot_shape_glyphs_closure (hb_font_t          *font,
 
   /* TODO: normalization? have shapers do closure()? */
   /* TODO: Deal with mirrored chars? */
-  hb_map_glyphs (font, buffer);
+  hb_ot_map_glyphs (font, buffer);
 
   /* Seed it.  It's user's responsibility to have cleard glyphs
    * if that's what they desire. */
commit cd0c6e148f6d078b364370cb2f808b793b921be2
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 9 21:48:55 2012 -0400

    Shuffle buffer variable allocations around
    
    To room for more allocations, coming.

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 510aec9..e101782 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -39,9 +39,9 @@
 
 
 /* buffer var allocations, used during the GSUB/GPOS processing */
-#define glyph_props()		var1.u16[1] /* GDEF glyph properties */
-#define syllable()		var2.u8[0] /* GSUB/GPOS shaping boundaries */
-#define lig_props()		var2.u8[1] /* GSUB/GPOS ligature tracking */
+#define glyph_props()		var1.u16[0] /* GDEF glyph properties */
+#define syllable()		var1.u8[2] /* GSUB/GPOS shaping boundaries */
+#define lig_props()		var1.u8[3] /* GSUB/GPOS ligature tracking */
 
 #define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
 
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index b014c74..2a96b7d 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -30,7 +30,7 @@
 
 
 /* buffer var allocations */
-#define arabic_shaping_action() complex_var_temporary_u8() /* arabic shaping action */
+#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
 
 
 /*
diff --git a/src/hb-ot-shape-complex-indic-private.hh b/src/hb-ot-shape-complex-indic-private.hh
index 719d287..79daba5 100644
--- a/src/hb-ot-shape-complex-indic-private.hh
+++ b/src/hb-ot-shape-complex-indic-private.hh
@@ -35,8 +35,8 @@
 
 
 /* buffer var allocations */
-#define indic_category() complex_var_persistent_u8_0() /* indic_category_t */
-#define indic_position() complex_var_persistent_u8_1() /* indic_matra_category_t */
+#define indic_category() complex_var_u8_0() /* indic_category_t */
+#define indic_position() complex_var_u8_1() /* indic_matra_category_t */
 
 
 #define INDIC_TABLE_ELEMENT_TYPE uint8_t
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index baece32..efff325 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -35,9 +35,8 @@
 
 
 /* buffer var allocations, used by complex shapers */
-#define complex_var_persistent_u8_0()	var2.u8[2]
-#define complex_var_persistent_u8_1()	var2.u8[3]
-#define complex_var_temporary_u8()	var2.u8[0]
+#define complex_var_u8_0()	var2.u8[2]
+#define complex_var_u8_1()	var2.u8[3]
 
 
 
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 975665e..f856045 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -34,8 +34,8 @@
 
 
 /* buffer var allocations, used during the entire shaping process */
-#define unicode_props0()	var1.u8[0]
-#define unicode_props1()	var1.u8[1]
+#define unicode_props0()	var2.u8[0]
+#define unicode_props1()	var2.u8[1]
 
 
 
commit 8d1eef3f32fb539de2a72804fa3834acc18daab5
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 9 21:31:52 2012 -0400

    Minor

diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc
index b5e0b4d..ccaf1d7 100644
--- a/src/hb-ot-shape-normalize.cc
+++ b/src/hb-ot-shape-normalize.cc
@@ -258,13 +258,25 @@ compose_func (hb_unicode_funcs_t *unicode,
   return found;
 }
 
-static void
-output_glyph (hb_buffer_t *buffer, hb_codepoint_t glyph)
+static inline void
+output_char (hb_buffer_t *buffer, hb_codepoint_t unichar)
 {
-  buffer->output_glyph (glyph);
+  buffer->output_glyph (unichar);
   _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer->unicode);
 }
 
+static inline void
+next_char (hb_buffer_t *buffer)
+{
+  buffer->next_glyph ();
+}
+
+static inline void
+skip_char (hb_buffer_t *buffer)
+{
+  buffer->skip_glyph ();
+}
+
 static bool
 decompose (hb_font_t *font, hb_buffer_t *buffer,
 	   bool shortest,
@@ -279,22 +291,22 @@ decompose (hb_font_t *font, hb_buffer_t *buffer,
   bool has_a = font->get_glyph (a, 0, &glyph);
   if (shortest && has_a) {
     /* Output a and b */
-    output_glyph (buffer, a);
+    output_char (buffer, a);
     if (b)
-      output_glyph (buffer, b);
+      output_char (buffer, b);
     return true;
   }
 
   if (decompose (font, buffer, shortest, a)) {
     if (b)
-      output_glyph (buffer, b);
+      output_char (buffer, b);
     return true;
   }
 
   if (has_a) {
-    output_glyph (buffer, a);
+    output_char (buffer, a);
     if (b)
-      output_glyph (buffer, b);
+      output_char (buffer, b);
     return true;
   }
 
@@ -318,7 +330,7 @@ decompose_compatibility (hb_font_t *font, hb_buffer_t *buffer,
       return false;
 
   for (i = 0; i < len; i++)
-    output_glyph (buffer, decomposed[i]);
+    output_char (buffer, decomposed[i]);
 
   return true;
 }
@@ -331,15 +343,15 @@ decompose_current_character (hb_font_t *font, hb_buffer_t *buffer,
 
   /* Kind of a cute waterfall here... */
   if (shortest && font->get_glyph (buffer->cur().codepoint, 0, &glyph))
-    buffer->next_glyph ();
+    next_char (buffer);
   else if (decompose (font, buffer, shortest, buffer->cur().codepoint))
-    buffer->skip_glyph ();
+    skip_char (buffer);
   else if (!shortest && font->get_glyph (buffer->cur().codepoint, 0, &glyph))
-    buffer->next_glyph ();
+    next_char (buffer);
   else if (decompose_compatibility (font, buffer, buffer->cur().codepoint))
-    buffer->skip_glyph ();
+    skip_char (buffer);
   else
-    buffer->next_glyph ();
+    next_char (buffer);
 }
 
 static void
@@ -350,7 +362,7 @@ decompose_multi_char_cluster (hb_font_t *font, hb_buffer_t *buffer,
   for (unsigned int i = buffer->idx; i < end; i++)
     if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
       while (buffer->idx < end)
-	buffer->next_glyph ();
+	next_char (buffer);
       return;
     }
 
@@ -445,7 +457,7 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
   buffer->clear_output ();
   count = buffer->len;
   unsigned int starter = 0;
-  buffer->next_glyph ();
+  next_char (buffer);
   while (buffer->idx < count)
   {
     hb_codepoint_t composed, glyph;
@@ -466,11 +478,11 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
 	font->get_glyph (composed, 0, &glyph))
     {
       /* Composes. */
-      buffer->next_glyph (); /* Copy to out-buffer. */
+      next_char (buffer); /* 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_len--; /* Remove the second composable. */
       buffer->out_info[starter].codepoint = composed; /* Modify starter and carry on. */
       _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode);
 
@@ -478,7 +490,7 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
     }
 
     /* Blocked, or doesn't compose. */
-    buffer->next_glyph ();
+    next_char (buffer);
 
     if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
       starter = buffer->out_len - 1;
commit 56c9e7c004e802ddcb8c704346026f1d7a812f9f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 9 21:12:30 2012 -0400

    Fill out combining class resetting for fallback shaping Thai/Lao/Tibetan

diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index 71aed89..abc7e2b 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -49,7 +49,9 @@ recategorize_combining_class (unsigned int modified_combining_class)
    * from hb-unicode.cc. */
   switch (modified_combining_class)
   {
+
     /* Hebrew */
+
     case HB_MODIFIED_COMBINING_CLASS_CCC10: /* sheva */
     case HB_MODIFIED_COMBINING_CLASS_CCC11: /* hataf segol */
     case HB_MODIFIED_COMBINING_CLASS_CCC12: /* hataf patah */
@@ -79,7 +81,9 @@ recategorize_combining_class (unsigned int modified_combining_class)
     case HB_MODIFIED_COMBINING_CLASS_CCC21: /* dagesh */
       break;
 
+
     /* Arabic and Syriac */
+
     case HB_MODIFIED_COMBINING_CLASS_CCC27: /* fathatan */
     case HB_MODIFIED_COMBINING_CLASS_CCC28: /* dammatan */
     case HB_MODIFIED_COMBINING_CLASS_CCC30: /* fatha */
@@ -94,7 +98,39 @@ recategorize_combining_class (unsigned int modified_combining_class)
     case HB_MODIFIED_COMBINING_CLASS_CCC32: /* kasra */
       return HB_UNICODE_COMBINING_CLASS_BELOW;
 
-    /* TODO Thai, Lao, and Tibetan */
+
+    /* Thai */
+
+    /* Note: to be useful we also need to position U+0E3A that has ccc=9 (virama).
+     * But viramas can be both above and below based on the codepoint / script. */
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC103: /* sara u / sara uu */
+      return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC107: /* mai */
+      return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+
+    /* Lao */
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC118: /* sign u / sign uu */
+      return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC122: /* mai */
+      return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+
+    /* Tibetan */
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC129: /* sign aa */
+      return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC130: /* sign i*/
+      return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC132: /* sign u */
+      return HB_UNICODE_COMBINING_CLASS_BELOW;
+
   }
 
   return modified_combining_class;
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index b2af7c8..53214b9 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -260,8 +260,9 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
 
 /* Thai
  *
- * Modify U+0E38 and U+0E39 (ccc=104) to be reordered before U+0E3A (ccc=9).
- * Uniscribe does this too.
+ * Modify U+0E38 and U+0E39 (ccc=103) to be reordered before U+0E3A (ccc=9).
+ * Assign 3, which is unassigned otherwise.
+ * Uniscribe does this reordering too.
  */
 #define HB_MODIFIED_COMBINING_CLASS_CCC103 3 /* sara u / sara uu */
 #define HB_MODIFIED_COMBINING_CLASS_CCC107 107 /* mai * */
@@ -273,7 +274,7 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
 /* Tibetan */
 #define HB_MODIFIED_COMBINING_CLASS_CCC129 129 /* sign aa */
 #define HB_MODIFIED_COMBINING_CLASS_CCC130 130 /* sign i */
-#define HB_MODIFIED_COMBINING_CLASS_CCC133 132 /* sign u */
+#define HB_MODIFIED_COMBINING_CLASS_CCC132 132 /* sign u */
 
 
 #endif /* HB_UNICODE_PRIVATE_HH */
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index 30dc7de..8979eaa 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -358,7 +358,7 @@ _hb_modified_combining_class[256] =
   HB_MODIFIED_COMBINING_CLASS_CCC129,
   HB_MODIFIED_COMBINING_CLASS_CCC130,
   131,
-  HB_MODIFIED_COMBINING_CLASS_CCC133,
+  HB_MODIFIED_COMBINING_CLASS_CCC132,
   133, 134, 135, 136, 137, 138, 139,
 
 
commit a321e1d51e0e7fa02738410e8d6e77c841bc6b13
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 9 18:30:34 2012 -0400

    Revert "Reject lookups with no subTable"
    
    This reverts commit 30ec9002d84e8b49290e782e6192069821ffa942.
    
    See previous commit.

diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index fad813f..cea5b75 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -314,7 +314,6 @@ struct Lookup
     TRACE_SANITIZE ();
     /* Real sanitize of the subtables is done by GSUB/GPOS/... */
     if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false);
-    if (!subTable.len) TRACE_RETURN (false);
     if (unlikely (lookupFlag & LookupFlag::UseMarkFilteringSet))
     {
       USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
commit 2eaf482b371034ce6ebfaedee98049b036fd3493
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Aug 9 18:30:05 2012 -0400

    Revert "[GSUB/GPOS] Reject Context/ChainContext lookups with zero input"
    
    This reverts commit 0981068b75710397f08e0d2d776a0a2ea68d7117.
    
    I was confused.  Even if we access coverage[0] unconditionally, we don't
    need bound checks since the array machinary already handles that.

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index fd5fb19..ba2a7e0 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -928,7 +928,6 @@ struct ContextFormat3
     TRACE_SANITIZE ();
     if (!c->check_struct (this)) return TRACE_RETURN (false);
     unsigned int count = glyphCount;
-    if (unlikely (!glyphCount)) return TRACE_RETURN (false);
     if (!c->check_array (coverage, coverage[0].static_size, count)) return TRACE_RETURN (false);
     for (unsigned int i = 0; i < count; i++)
       if (!coverage[i].sanitize (c, this)) return TRACE_RETURN (false);
@@ -1467,7 +1466,6 @@ struct ChainContextFormat3
     if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false);
     OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
     if (!input.sanitize (c, this)) return TRACE_RETURN (false);
-    if (unlikely (!input.len)) return TRACE_RETURN (false);
     OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
     if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false);
     ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);



More information about the HarfBuzz mailing list