[HarfBuzz] harfbuzz: Branch 'master' - 25 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Oct 18 10:34:56 PDT 2013


 src/hb-buffer.h                          |   16 -
 src/hb-ft.cc                             |    8 
 src/hb-ot-layout-gdef-table.hh           |    8 
 src/hb-ot-layout-gpos-table.hh           |  128 +++++-----
 src/hb-ot-layout-gsub-table.hh           |   18 -
 src/hb-ot-layout-gsubgpos-private.hh     |   85 +++---
 src/hb-ot-layout-private.hh              |  382 ++++++++++++++++++++-----------
 src/hb-ot-layout.cc                      |   31 +-
 src/hb-ot-shape-complex-arabic.cc        |   13 -
 src/hb-ot-shape-complex-default.cc       |   17 +
 src/hb-ot-shape-complex-indic-machine.rl |   14 -
 src/hb-ot-shape-complex-indic-private.hh |   37 +--
 src/hb-ot-shape-complex-indic.cc         |   51 ++--
 src/hb-ot-shape-complex-myanmar.cc       |   17 -
 src/hb-ot-shape-complex-private.hh       |    8 
 src/hb-ot-shape-complex-sea.cc           |   14 -
 src/hb-ot-shape-complex-thai.cc          |    9 
 src/hb-ot-shape-fallback.cc              |   26 +-
 src/hb-ot-shape-normalize.cc             |   29 +-
 src/hb-ot-shape.cc                       |  100 ++++----
 20 files changed, 620 insertions(+), 391 deletions(-)

New commits:
commit ac8cd511911c7dca6222d14fa758bff75d601567
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 19:33:09 2013 +0200

    Refactor

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index b1f1a61..103676b 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -390,6 +390,7 @@ struct MarkArray : ArrayOf<MarkRecord>	/* Array of MarkRecords--in Coverage orde
 		     unsigned int glyph_pos) const
   {
     TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
     const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
     unsigned int mark_class = record.klass;
 
@@ -402,15 +403,15 @@ struct MarkArray : ArrayOf<MarkRecord>	/* Array of MarkRecords--in Coverage orde
 
     hb_position_t mark_x, mark_y, base_x, base_y;
 
-    mark_anchor.get_anchor (c->font, c->buffer->cur().codepoint, &mark_x, &mark_y);
-    glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &base_x, &base_y);
+    mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y);
+    glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
 
-    hb_glyph_position_t &o = c->buffer->cur_pos();
+    hb_glyph_position_t &o = buffer->cur_pos();
     o.x_offset = base_x - mark_x;
     o.y_offset = base_y - mark_y;
-    o.attach_lookback() = c->buffer->idx - glyph_pos;
+    o.attach_lookback() = buffer->idx - glyph_pos;
 
-    c->buffer->idx++;
+    buffer->idx++;
     return TRACE_RETURN (true);
   }
 
@@ -439,13 +440,14 @@ struct SinglePosFormat1
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    unsigned int index = (this+coverage).get_coverage  (c->buffer->cur().codepoint);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     valueFormat.apply_value (c->font, c->direction, this,
-			     values, c->buffer->cur_pos());
+			     values, buffer->cur_pos());
 
-    c->buffer->idx++;
+    buffer->idx++;
     return TRACE_RETURN (true);
   }
 
@@ -484,16 +486,17 @@ struct SinglePosFormat2
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    unsigned int index = (this+coverage).get_coverage  (c->buffer->cur().codepoint);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     if (likely (index >= valueCount)) return TRACE_RETURN (false);
 
     valueFormat.apply_value (c->font, c->direction, this,
 			     &values[index * valueFormat.get_len ()],
-			     c->buffer->cur_pos());
+			     buffer->cur_pos());
 
-    c->buffer->idx++;
+    buffer->idx++;
     return TRACE_RETURN (true);
   }
 
@@ -588,6 +591,7 @@ struct PairSet
 		     unsigned int pos) const
   {
     TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
     unsigned int len1 = valueFormats[0].get_len ();
     unsigned int len2 = valueFormats[1].get_len ();
     unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
@@ -597,15 +601,15 @@ struct PairSet
     for (unsigned int i = 0; i < count; i++)
     {
       /* TODO bsearch */
-      if (c->buffer->info[pos].codepoint == record->secondGlyph)
+      if (buffer->info[pos].codepoint == record->secondGlyph)
       {
 	valueFormats[0].apply_value (c->font, c->direction, this,
-				     &record->values[0], c->buffer->cur_pos());
+				     &record->values[0], buffer->cur_pos());
 	valueFormats[1].apply_value (c->font, c->direction, this,
-				     &record->values[len1], c->buffer->pos[pos]);
+				     &record->values[len1], buffer->pos[pos]);
 	if (len2)
 	  pos++;
-	c->buffer->idx = pos;
+	buffer->idx = pos;
 	return TRACE_RETURN (true);
       }
       record = &StructAtOffset<PairValueRecord> (record, record_size);
@@ -659,10 +663,11 @@ struct PairPosFormat1
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+    hb_buffer_t *buffer = c->buffer;
+    hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
     if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
 
-    unsigned int index = (this+coverage).get_coverage  (c->buffer->cur().codepoint);
+    unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     if (!skippy_iter.next ()) return TRACE_RETURN (false);
@@ -729,10 +734,11 @@ struct PairPosFormat2
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+    hb_buffer_t *buffer = c->buffer;
+    hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
     if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
 
-    unsigned int index = (this+coverage).get_coverage  (c->buffer->cur().codepoint);
+    unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     if (!skippy_iter.next ()) return TRACE_RETURN (false);
@@ -741,19 +747,19 @@ struct PairPosFormat2
     unsigned int len2 = valueFormat2.get_len ();
     unsigned int record_len = len1 + len2;
 
-    unsigned int klass1 = (this+classDef1).get_class (c->buffer->cur().codepoint);
-    unsigned int klass2 = (this+classDef2).get_class (c->buffer->info[skippy_iter.idx].codepoint);
+    unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
+    unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
     if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false);
 
     const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
     valueFormat1.apply_value (c->font, c->direction, this,
-			      v, c->buffer->cur_pos());
+			      v, buffer->cur_pos());
     valueFormat2.apply_value (c->font, c->direction, this,
-			      v + len1, c->buffer->pos[skippy_iter.idx]);
+			      v + len1, buffer->pos[skippy_iter.idx]);
 
-    c->buffer->idx = skippy_iter.idx;
+    buffer->idx = skippy_iter.idx;
     if (len2)
-      c->buffer->idx++;
+      buffer->idx++;
 
     return TRACE_RETURN (true);
   }
@@ -875,29 +881,30 @@ struct CursivePosFormat1
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
 
     /* We don't handle mark glyphs here. */
-    if (unlikely (_hb_glyph_info_is_mark (&c->buffer->cur()))) return TRACE_RETURN (false);
+    if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false);
 
-    hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+    hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
     if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
 
-    const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage  (c->buffer->cur().codepoint)];
+    const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage  (buffer->cur().codepoint)];
     if (!this_record.exitAnchor) return TRACE_RETURN (false);
 
     if (!skippy_iter.next ()) return TRACE_RETURN (false);
 
-    const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage  (c->buffer->info[skippy_iter.idx].codepoint)];
+    const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint)];
     if (!next_record.entryAnchor) return TRACE_RETURN (false);
 
-    unsigned int i = c->buffer->idx;
+    unsigned int i = buffer->idx;
     unsigned int j = skippy_iter.idx;
 
     hb_position_t entry_x, entry_y, exit_x, exit_y;
-    (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y);
-    (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, &entry_x, &entry_y);
+    (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint, &exit_x, &exit_y);
+    (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoint, &entry_x, &entry_y);
 
-    hb_glyph_position_t *pos = c->buffer->pos;
+    hb_glyph_position_t *pos = buffer->pos;
 
     hb_position_t d;
     /* Main-direction adjustment */
@@ -950,7 +957,7 @@ struct CursivePosFormat1
 	pos[j].x_offset = exit_x - entry_x;
     }
 
-    c->buffer->idx = j;
+    buffer->idx = j;
     return TRACE_RETURN (true);
   }
 
@@ -1022,23 +1029,24 @@ struct MarkBasePosFormat1
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    unsigned int mark_index = (this+markCoverage).get_coverage  (c->buffer->cur().codepoint);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int mark_index = (this+markCoverage).get_coverage  (buffer->cur().codepoint);
     if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
 
     /* now we search backwards for a non-mark glyph */
-    hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+    hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
     do {
       if (!skippy_iter.prev ()) return TRACE_RETURN (false);
       /* We only want to attach to the first of a MultipleSubst sequence.  Reject others. */
-      if (0 == _hb_glyph_info_get_lig_comp (&c->buffer->info[skippy_iter.idx])) break;
+      if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break;
       skippy_iter.reject ();
     } while (1);
 
     /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
-    if (!_hb_glyph_info_is_base_glyph (&c->buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
+    if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
 
-    unsigned int base_index = (this+baseCoverage).get_coverage  (c->buffer->info[skippy_iter.idx].codepoint);
+    unsigned int base_index = (this+baseCoverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint);
     if (base_index == NOT_COVERED) return TRACE_RETURN (false);
 
     return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
@@ -1125,19 +1133,20 @@ struct MarkLigPosFormat1
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    unsigned int mark_index = (this+markCoverage).get_coverage  (c->buffer->cur().codepoint);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int mark_index = (this+markCoverage).get_coverage  (buffer->cur().codepoint);
     if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
 
     /* now we search backwards for a non-mark glyph */
-    hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+    hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
     if (!skippy_iter.prev ()) return TRACE_RETURN (false);
 
     /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
-    if (!_hb_glyph_info_is_ligature (&c->buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
+    if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
 
     unsigned int j = skippy_iter.idx;
-    unsigned int lig_index = (this+ligatureCoverage).get_coverage  (c->buffer->info[j].codepoint);
+    unsigned int lig_index = (this+ligatureCoverage).get_coverage  (buffer->info[j].codepoint);
     if (lig_index == NOT_COVERED) return TRACE_RETURN (false);
 
     const LigatureArray& lig_array = this+ligatureArray;
@@ -1152,11 +1161,11 @@ struct MarkLigPosFormat1
      * can directly use the component index.  If not, we attach the mark
      * glyph to the last component of the ligature. */
     unsigned int comp_index;
-    unsigned int lig_id = _hb_glyph_info_get_lig_id (&c->buffer->info[j]);
-    unsigned int mark_id = _hb_glyph_info_get_lig_id (&c->buffer->cur());
-    unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&c->buffer->cur());
+    unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+    unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+    unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
     if (lig_id && lig_id == mark_id && mark_comp > 0)
-      comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&c->buffer->cur())) - 1;
+      comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
     else
       comp_index = comp_count - 1;
 
@@ -1240,22 +1249,23 @@ struct MarkMarkPosFormat1
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    unsigned int mark1_index = (this+mark1Coverage).get_coverage  (c->buffer->cur().codepoint);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int mark1_index = (this+mark1Coverage).get_coverage  (buffer->cur().codepoint);
     if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
 
     /* now we search backwards for a suitable mark glyph until a non-mark glyph */
-    hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+    hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
     skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
     if (!skippy_iter.prev ()) return TRACE_RETURN (false);
 
-    if (!_hb_glyph_info_is_mark (&c->buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); }
+    if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); }
 
     unsigned int j = skippy_iter.idx;
 
-    unsigned int id1 = _hb_glyph_info_get_lig_id (&c->buffer->cur());
-    unsigned int id2 = _hb_glyph_info_get_lig_id (&c->buffer->info[j]);
-    unsigned int comp1 = _hb_glyph_info_get_lig_comp (&c->buffer->cur());
-    unsigned int comp2 = _hb_glyph_info_get_lig_comp (&c->buffer->info[j]);
+    unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
+    unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+    unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
+    unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
 
     if (likely (id1 == id2)) {
       if (id1 == 0) /* Marks belonging to the same base. */
@@ -1273,7 +1283,7 @@ struct MarkMarkPosFormat1
     return TRACE_RETURN (false);
 
     good:
-    unsigned int mark2_index = (this+mark2Coverage).get_coverage  (c->buffer->info[j].codepoint);
+    unsigned int mark2_index = (this+mark2Coverage).get_coverage  (buffer->info[j].codepoint);
     if (mark2_index == NOT_COVERED) return TRACE_RETURN (false);
 
     return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 06c98d2..bd8ef08 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -825,8 +825,9 @@ apply_string (OT::hb_apply_context_t *c,
   bool ret = false;
   OT::hb_is_inplace_context_t inplace_c (c->face);
   bool inplace = lookup.is_inplace (&inplace_c);
+  hb_buffer_t *buffer = c->buffer;
 
-  if (unlikely (!c->buffer->len || !c->lookup_mask))
+  if (unlikely (!buffer->len || !c->lookup_mask))
     return false;
 
   c->set_lookup (lookup);
@@ -835,43 +836,43 @@ apply_string (OT::hb_apply_context_t *c,
   {
     /* in/out forward substitution/positioning */
     if (Proxy::table_index == 0)
-      c->buffer->clear_output ();
-    c->buffer->idx = 0;
+      buffer->clear_output ();
+    buffer->idx = 0;
 
-    while (c->buffer->idx < c->buffer->len)
+    while (buffer->idx < buffer->len)
     {
-      if (accel.digest.may_have (c->buffer->cur().codepoint) &&
-	  (c->buffer->cur().mask & c->lookup_mask) &&
+      if (accel.digest.may_have (buffer->cur().codepoint) &&
+	  (buffer->cur().mask & c->lookup_mask) &&
 	  apply_once (c, lookup))
 	ret = true;
       else
-	c->buffer->next_glyph ();
+	buffer->next_glyph ();
     }
     if (ret)
     {
       if (!inplace)
-	c->buffer->swap_buffers ();
+	buffer->swap_buffers ();
       else
-        assert (!c->buffer->has_separate_output ());
+        assert (!buffer->has_separate_output ());
     }
   }
   else
   {
     /* in-place backward substitution/positioning */
     if (Proxy::table_index == 0)
-      c->buffer->remove_output ();
-    c->buffer->idx = c->buffer->len - 1;
+      buffer->remove_output ();
+    buffer->idx = buffer->len - 1;
     do
     {
-      if (accel.digest.may_have (c->buffer->cur().codepoint) &&
-	  (c->buffer->cur().mask & c->lookup_mask) &&
+      if (accel.digest.may_have (buffer->cur().codepoint) &&
+	  (buffer->cur().mask & c->lookup_mask) &&
 	  apply_once (c, lookup))
 	ret = true;
       /* The reverse lookup doesn't "advance" cursor (for good reason). */
-      c->buffer->idx--;
+      buffer->idx--;
 
     }
-    while ((int) c->buffer->idx >= 0);
+    while ((int) buffer->idx >= 0);
   }
 
   return ret;
diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc
index 3fee809..6531e1b 100644
--- a/src/hb-ot-shape-normalize.cc
+++ b/src/hb-ot-shape-normalize.cc
@@ -132,17 +132,19 @@ static inline unsigned int
 decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab)
 {
   hb_codepoint_t a, b, a_glyph, b_glyph;
+  hb_buffer_t * const buffer = c->buffer;
+  hb_font_t * const font = c->font;
 
   if (!c->decompose (c, ab, &a, &b) ||
-      (b && !c->font->get_glyph (b, 0, &b_glyph)))
+      (b && !font->get_glyph (b, 0, &b_glyph)))
     return 0;
 
-  bool has_a = c->font->get_glyph (a, 0, &a_glyph);
+  bool has_a = font->get_glyph (a, 0, &a_glyph);
   if (shortest && has_a) {
     /* Output a and b */
-    output_char (c->buffer, a, a_glyph);
+    output_char (buffer, a, a_glyph);
     if (likely (b)) {
-      output_char (c->buffer, b, b_glyph);
+      output_char (buffer, b, b_glyph);
       return 2;
     }
     return 1;
@@ -151,16 +153,16 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint
   unsigned int ret;
   if ((ret = decompose (c, shortest, a))) {
     if (b) {
-      output_char (c->buffer, b, b_glyph);
+      output_char (buffer, b, b_glyph);
       return ret + 1;
     }
     return ret;
   }
 
   if (has_a) {
-    output_char (c->buffer, a, a_glyph);
+    output_char (buffer, a, a_glyph);
     if (likely (b)) {
-      output_char (c->buffer, b, b_glyph);
+      output_char (buffer, b, b_glyph);
       return 2;
     }
     return 1;
@@ -214,34 +216,35 @@ static inline void
 handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
 {
   hb_buffer_t * const buffer = c->buffer;
+  hb_font_t * const font = c->font;
   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. */
-      if (c->font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
+      if (font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
       {
 	buffer->replace_glyphs (2, 1, &buffer->cur().codepoint);
       }
       else
       {
         /* Just pass on the two characters separately, let GSUB do its magic. */
-	set_glyph (buffer->cur(), c->font);
+	set_glyph (buffer->cur(), font);
 	buffer->next_glyph ();
-	set_glyph (buffer->cur(), c->font);
+	set_glyph (buffer->cur(), font);
 	buffer->next_glyph ();
       }
       /* Skip any further variation selectors. */
       while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
       {
-	set_glyph (buffer->cur(), c->font);
+	set_glyph (buffer->cur(), font);
 	buffer->next_glyph ();
       }
     } else {
-      set_glyph (buffer->cur(), c->font);
+      set_glyph (buffer->cur(), font);
       buffer->next_glyph ();
     }
   }
   if (likely (buffer->idx < end)) {
-    set_glyph (buffer->cur(), c->font);
+    set_glyph (buffer->cur(), font);
     buffer->next_glyph ();
   }
 }
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 76c0fe3..d0737e2 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -290,16 +290,18 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
   if (HB_DIRECTION_IS_FORWARD (c->target_direction))
     return;
 
-  hb_unicode_funcs_t *unicode = c->buffer->unicode;
+  hb_buffer_t *buffer = c->buffer;
+  hb_unicode_funcs_t *unicode = 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;
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
   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;
+    hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint);
+    if (likely (codepoint == info[i].codepoint))
+      info[i].mask |= rtlm_mask;
     else
-      c->buffer->info[i].codepoint = codepoint;
+      info[i].codepoint = codepoint;
   }
 }
 
@@ -307,12 +309,13 @@ static inline void
 hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
 {
   hb_ot_map_t *map = &c->plan->map;
+  hb_buffer_t *buffer = c->buffer;
 
   hb_mask_t global_mask = map->get_global_mask ();
-  c->buffer->reset_masks (global_mask);
+  buffer->reset_masks (global_mask);
 
   if (c->plan->shaper->setup_masks)
-    c->plan->shaper->setup_masks (c->plan, c->buffer, c->font);
+    c->plan->shaper->setup_masks (c->plan, buffer, c->font);
 
   for (unsigned int i = 0; i < c->num_user_features; i++)
   {
@@ -320,7 +323,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
     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);
+      buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
     }
   }
 }
@@ -338,9 +341,10 @@ static inline void
 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
 {
   unsigned int count = c->buffer->len;
+  hb_glyph_info_t *info = c->buffer->info;
   for (unsigned int i = 0; i < count; i++)
-    _hb_glyph_info_set_glyph_props (&c->buffer->info[i],
-				    _hb_glyph_info_get_general_category (&c->buffer->info[i])
+    _hb_glyph_info_set_glyph_props (&info[i],
+				    _hb_glyph_info_get_general_category (&info[i])
 				    == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
 				    HB_OT_LAYOUT_GLYPH_PROPS_MARK :
 				    HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
@@ -349,37 +353,41 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
 static inline void
 hb_ot_substitute_default (hb_ot_shape_context_t *c)
 {
+  hb_buffer_t *buffer = c->buffer;
+
   if (c->plan->shaper->preprocess_text)
-    c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
+    c->plan->shaper->preprocess_text (c->plan, buffer, c->font);
 
   hb_ot_mirror_chars (c);
 
-  HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index);
+  HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
 
-  _hb_ot_shape_normalize (c->plan, c->buffer, c->font);
+  _hb_ot_shape_normalize (c->plan, buffer, c->font);
 
   hb_ot_shape_setup_masks (c);
 
   /* This is unfortunate to go here, but necessary... */
   if (!hb_ot_layout_has_positioning (c->face))
-    _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, c->buffer);
+    _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
 
-  hb_ot_map_glyphs_fast (c->buffer);
+  hb_ot_map_glyphs_fast (buffer);
 
-  HB_BUFFER_DEALLOCATE_VAR (c->buffer, glyph_index);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index);
 }
 
 static inline void
 hb_ot_substitute_complex (hb_ot_shape_context_t *c)
 {
-  hb_ot_layout_substitute_start (c->font, c->buffer);
+  hb_buffer_t *buffer = c->buffer;
+
+  hb_ot_layout_substitute_start (c->font, buffer);
 
   if (!hb_ot_layout_has_glyph_classes (c->face))
     hb_synthesize_glyph_classes (c);
 
-  c->plan->substitute (c->font, c->buffer);
+  c->plan->substitute (c->font, buffer);
 
-  hb_ot_layout_substitute_finish (c->font, c->buffer);
+  hb_ot_layout_substitute_finish (c->font, buffer);
 
   return;
 }
@@ -420,17 +428,20 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer)
 static inline void
 hb_ot_position_default (hb_ot_shape_context_t *c)
 {
+  hb_direction_t direction = c->buffer->props.direction;
   unsigned int count = c->buffer->len;
+  hb_glyph_info_t *info = c->buffer->info;
+  hb_glyph_position_t *pos = c->buffer->pos;
   for (unsigned int i = 0; i < count; i++)
   {
-    c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
-					      c->buffer->props.direction,
-					      &c->buffer->pos[i].x_advance,
-					      &c->buffer->pos[i].y_advance);
-    c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
-						  c->buffer->props.direction,
-						  &c->buffer->pos[i].x_offset,
-						  &c->buffer->pos[i].y_offset);
+    c->font->get_glyph_advance_for_direction (info[i].codepoint,
+					      direction,
+					      &pos[i].x_advance,
+					      &pos[i].y_advance);
+    c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
+						  direction,
+						  &pos[i].x_offset,
+						  &pos[i].y_offset);
 
   }
 }
@@ -462,22 +473,25 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
 
   if (hb_ot_layout_has_positioning (c->face))
   {
+    hb_glyph_info_t *info = c->buffer->info;
+    hb_glyph_position_t *pos = c->buffer->pos;
+
     /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
 
     for (unsigned int i = 0; i < count; i++) {
-      c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint,
+      c->font->add_glyph_origin_for_direction (info[i].codepoint,
 					       HB_DIRECTION_LTR,
-					       &c->buffer->pos[i].x_offset,
-					       &c->buffer->pos[i].y_offset);
+					       &pos[i].x_offset,
+					       &pos[i].y_offset);
     }
 
     c->plan->position (c->font, c->buffer);
 
     for (unsigned int i = 0; i < count; i++) {
-      c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
+      c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
 						    HB_DIRECTION_LTR,
-						    &c->buffer->pos[i].x_offset,
-						    &c->buffer->pos[i].y_offset);
+						    &pos[i].x_offset,
+						    &pos[i].y_offset);
     }
 
     ret = true;
commit 0f3fe37fccfb540437adf13dd580f2c5164a0b1f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 19:14:22 2013 +0200

    Comment

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 93d2d76..139e33f 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -187,6 +187,7 @@ enum {
 inline void
 _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
 {
+  /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */
   info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
 			   (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
 			   (info->codepoint == 0x200C ? MASK0_ZWNJ : 0) |
commit ddce2d8df6fed9c033f1f13e235666680c5beb67
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 18:07:11 2013 +0200

    [indic] Improve positioning of post-base bells and whistles
    
    Bug 58714 - Kannada u+0cb0 u+200d u+0ccd u+0c95 u+0cbe does not provide
    same results as Windows8
    https://bugs.freedesktop.org/show_bug.cgi?id=58714
    
    Test with U+0CB0,U+200D,U+0CCD,U+0C95,U+0CBF and tunga.ttf.
    
    Improves some scripts.  Improves Bengali too, but numbers
    are up because we produce better results than Uniscribe for some
    sequences now.
    
    New numbers:
    BENGALI: 353724 out of 354188 tests passed. 464 failed (0.131004%)
    DEVANAGARI: 707307 out of 707394 tests passed. 87 failed (0.0122987%)
    GUJARATI: 366349 out of 366457 tests passed. 108 failed (0.0294714%)
    GURMUKHI: 60732 out of 60747 tests passed. 15 failed (0.0246926%)
    KANNADA: 951190 out of 951913 tests passed. 723 failed (0.0759523%)
    KHMER: 299070 out of 299124 tests passed. 54 failed (0.0180527%)
    MALAYALAM: 1048140 out of 1048334 tests passed. 194 failed (0.0185056%)
    ORIYA: 42320 out of 42329 tests passed. 9 failed (0.021262%)
    SINHALA: 271662 out of 271847 tests passed. 185 failed (0.068053%)
    TAMIL: 1091753 out of 1091754 tests passed. 1 failed (9.15957e-05%)
    TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%)

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index f30e593..8265a58 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -962,18 +962,19 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
       }
     }
   }
-  /* Re-attach ZWJ, ZWNJ, and halant to next char, for after-base consonants. */
+  /* For post-base consonants let them own anything before them
+   * since the last consonant or matra. */
   {
-    unsigned int last_halant = end;
+    unsigned int last = base;
     for (unsigned int i = base + 1; i < end; i++)
-      if (is_halant_or_coeng (info[i]))
-        last_halant = i;
-      else if (is_consonant (info[i])) {
-	for (unsigned int j = last_halant; j < i; j++)
-	  if (info[j].indic_position() != POS_SMVD)
+      if (is_consonant (info[i]))
+      {
+	for (unsigned int j = last + 1; j < i; j++)
+	  if (info[j].indic_position() < POS_SMVD)
 	    info[j].indic_position() = info[i].indic_position();
-	last_halant = end;
-      }
+	last = i;
+      } else if (info[i].indic_category() == OT_M)
+        last = i;
   }
 
 
commit d5bd0590ae2fbc7b0dee86385a565aef00ffb835
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 16:44:54 2013 +0200

    Zero marks by GDEF for Tibetan
    
    See:
    http://lists.freedesktop.org/archives/harfbuzz/2013-April/003101.html

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 16c96fa..7fa3247 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -616,8 +616,8 @@ struct hb_apply_context_t
   }
 
   inline void _set_glyph_props (hb_codepoint_t glyph_index,
-			  unsigned int class_guess = 0,
-			  bool ligature = false) const
+				unsigned int class_guess = 0,
+				bool ligature = false) const
   {
     unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
 			  HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 4f6c86e..212b714 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -177,8 +177,6 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
    *
    * This also makes Arial Bold in Windows7 work.  See:
    * https://bugzilla.mozilla.org/show_bug.cgi?id=644184
-   *
-   * TODO: Add test cases for these two.
    */
 
   map->add_gsub_pause (nuke_joiners);
@@ -357,6 +355,12 @@ retry:
   arabic_fallback_plan_shape (fallback_plan, font, buffer);
 }
 
+static hb_ot_shape_zero_width_marks_t
+zero_width_marks_preference_arabic (const hb_segment_properties_t *props HB_UNUSED)
+{
+  return HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE;
+}
+
 
 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
 {
@@ -370,6 +374,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
   NULL, /* decompose */
   NULL, /* compose */
   setup_masks_arabic,
-  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
+  zero_width_marks_preference_arabic,
   true, /* fallback_position */
 };
diff --git a/src/hb-ot-shape-complex-default.cc b/src/hb-ot-shape-complex-default.cc
index d6afa0e..946825d 100644
--- a/src/hb-ot-shape-complex-default.cc
+++ b/src/hb-ot-shape-complex-default.cc
@@ -203,6 +203,21 @@ compose_default (const hb_ot_shape_normalize_context_t *c,
   return found;
 }
 
+static hb_ot_shape_zero_width_marks_t
+zero_width_marks_preference_default (const hb_segment_properties_t *props)
+{
+  switch ((hb_tag_t) props->script)
+  {
+    /* Unicode-2.0 additions */
+    case HB_SCRIPT_TIBETAN:
+      return HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE;
+
+    default:
+      return HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE;
+  }
+}
+
+
 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
 {
   "default",
@@ -215,6 +230,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
   NULL, /* decompose */
   compose_default,
   NULL, /* setup_masks */
-  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
+  zero_width_marks_preference_default,
   true, /* fallback_position */
 };
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 9a8b4e3..f30e593 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -1791,6 +1791,12 @@ compose_indic (const hb_ot_shape_normalize_context_t *c,
   return c->unicode->compose (a, b, ab);
 }
 
+static hb_ot_shape_zero_width_marks_t
+zero_width_marks_preference_indic (const hb_segment_properties_t *props HB_UNUSED)
+{
+  return HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE;
+}
+
 
 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
 {
@@ -1804,6 +1810,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
   decompose_indic,
   compose_indic,
   setup_masks_indic,
-  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+  zero_width_marks_preference_indic,
   false, /* fallback_position */
 };
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index a32405a..6cd7a2c 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -263,6 +263,12 @@ set_myanmar_properties (hb_glyph_info_t &info)
 
 
 
+static hb_ot_shape_normalization_mode_t
+normalization_preference_myanmar (const hb_segment_properties_t *props HB_UNUSED)
+{
+  return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
+}
+
 static void
 setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
 		   hb_buffer_t              *buffer,
@@ -519,11 +525,10 @@ final_reordering (const hb_ot_shape_plan_t *plan,
   HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
 }
 
-
-static hb_ot_shape_normalization_mode_t
-normalization_preference_myanmar (const hb_segment_properties_t *props HB_UNUSED)
+static hb_ot_shape_zero_width_marks_t
+zero_width_marks_preference_myanmar (const hb_segment_properties_t *props HB_UNUSED)
 {
-  return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
+  return HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY;
 }
 
 
@@ -539,6 +544,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
   NULL, /* decompose */
   NULL, /* compose */
   setup_masks_myanmar,
-  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
+  zero_width_marks_preference_myanmar,
   false, /* fallback_position */
 };
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index ac0072b..3109516 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -39,7 +39,7 @@
 #define complex_var_u8_1()	var2.u8[3]
 
 
-enum hb_ot_shape_zero_width_marks_type_t {
+enum hb_ot_shape_zero_width_marks_t {
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
 //  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY,
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
@@ -140,7 +140,11 @@ struct hb_ot_complex_shaper_t
 		       hb_buffer_t              *buffer,
 		       hb_font_t                *font);
 
-  hb_ot_shape_zero_width_marks_type_t zero_width_marks;
+  /* zero_width_marks_preference()
+   * Called during shape().
+   */
+  hb_ot_shape_zero_width_marks_t
+  (*zero_width_marks_preference) (const hb_segment_properties_t *props);
 
   bool fallback_position;
 };
diff --git a/src/hb-ot-shape-complex-sea.cc b/src/hb-ot-shape-complex-sea.cc
index da687ed..69d6678 100644
--- a/src/hb-ot-shape-complex-sea.cc
+++ b/src/hb-ot-shape-complex-sea.cc
@@ -162,6 +162,12 @@ set_sea_properties (hb_glyph_info_t &info)
 }
 
 
+static hb_ot_shape_normalization_mode_t
+normalization_preference_sea (const hb_segment_properties_t *props HB_UNUSED)
+{
+  return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
+}
+
 static void
 setup_masks_sea (const hb_ot_shape_plan_t *plan HB_UNUSED,
 		 hb_buffer_t              *buffer,
@@ -360,10 +366,10 @@ final_reordering (const hb_ot_shape_plan_t *plan,
 }
 
 
-static hb_ot_shape_normalization_mode_t
-normalization_preference_sea (const hb_segment_properties_t *props HB_UNUSED)
+static hb_ot_shape_zero_width_marks_t
+zero_width_marks_preference_sea (const hb_segment_properties_t *props HB_UNUSED)
 {
-  return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
+  return HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE;
 }
 
 
@@ -379,6 +385,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea =
   NULL, /* decompose */
   NULL, /* compose */
   setup_masks_sea,
-  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+  zero_width_marks_preference_sea,
   false, /* fallback_position */
 };
diff --git a/src/hb-ot-shape-complex-thai.cc b/src/hb-ot-shape-complex-thai.cc
index 4594533..955fc44 100644
--- a/src/hb-ot-shape-complex-thai.cc
+++ b/src/hb-ot-shape-complex-thai.cc
@@ -361,6 +361,13 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
     do_thai_pua_shaping (plan, buffer, font);
 }
 
+static hb_ot_shape_zero_width_marks_t
+zero_width_marks_preference_thai (const hb_segment_properties_t *props HB_UNUSED)
+{
+  return HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE;
+}
+
+
 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
 {
   "thai",
@@ -373,6 +380,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
   NULL, /* decompose */
   NULL, /* compose */
   NULL, /* setup_masks */
-  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
+  zero_width_marks_preference_thai,
   false,/* fallback_position */
 };
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 0296643..76c0fe3 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -441,7 +441,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
   bool ret = false;
   unsigned int count = c->buffer->len;
 
-  switch (c->plan->shaper->zero_width_marks)
+  switch (c->plan->shaper->zero_width_marks_preference (&c->plan->props))
   {
     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
       zero_mark_widths_by_gdef (c->buffer);
@@ -483,7 +483,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
     ret = true;
   }
 
-  switch (c->plan->shaper->zero_width_marks)
+  switch (c->plan->shaper->zero_width_marks_preference (&c->plan->props))
   {
     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
       zero_mark_widths_by_unicode (c->buffer);
commit bf029281b1b0f854f671969ab40eac3046a111bd
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 16:20:13 2013 +0200

    Bug 65258 - [...] Mongolian with free variation selector

diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index d549945..4f6c86e 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -280,7 +280,8 @@ arabic_joining (hb_buffer_t *buffer)
     const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
 
     if (entry->prev_action != NONE && prev != (unsigned int) -1)
-      buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+      for (; prev < i; prev++)
+	buffer->info[prev].arabic_shaping_action() = entry->prev_action;
 
     buffer->info[i].arabic_shaping_action() = entry->curr_action;
 
commit 0193649ce4ca78b8e2835a50bd51ee594cffe34e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 16:08:53 2013 +0200

    [otfallback] Don't shift down above-marks too much
    
    This seems to generate much better, almost-perfect, positioning for
    Arabic as well as Latin above marks.

diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index 2af924e..593c333 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -261,7 +261,7 @@ position_mark (const hb_ot_shape_plan_t *plan,
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
       pos.y_offset = base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
-      /* Never shift a "below" mark upwards. */
+      /* Never shift up "below" marks. */
       if ((y_gap > 0) == (pos.y_offset > 0))
       {
 	base_extents.height -= pos.y_offset;
@@ -281,6 +281,14 @@ position_mark (const hb_ot_shape_plan_t *plan,
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
       pos.y_offset = base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
+      /* Don't shift down "above" marks too much. */
+      if ((y_gap > 0) != (pos.y_offset > 0))
+      {
+	unsigned int correction = -pos.y_offset / 2;
+	base_extents.y_bearing += correction;
+	base_extents.height -= correction;
+	pos.y_offset += correction;
+      }
       base_extents.y_bearing -= mark_extents.height;
       base_extents.height += mark_extents.height;
       break;
commit dba9580237da788275b1ab5fe6be75c8a3f359b9
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 15:57:36 2013 +0200

    [otfallback] Never fallback-position a below-mark upwards
    
    Test with WinXP times.ttf and U+05D9,U+05B5.

diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index b7fd2d3..2af924e 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -261,6 +261,12 @@ position_mark (const hb_ot_shape_plan_t *plan,
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
       pos.y_offset = base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
+      /* Never shift a "below" mark upwards. */
+      if ((y_gap > 0) == (pos.y_offset > 0))
+      {
+	base_extents.height -= pos.y_offset;
+	pos.y_offset = 0;
+      }
       base_extents.height += mark_extents.height;
       break;
 
commit 8177da29ad07d8fa444ce07003fa65cd31a2776b
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 15:50:29 2013 +0200

    Minor

diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index a7e3b8e..b7fd2d3 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -260,7 +260,7 @@ position_mark (const hb_ot_shape_plan_t *plan,
 
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
-      pos.y_offset += base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
+      pos.y_offset = base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
       base_extents.height += mark_extents.height;
       break;
 
@@ -274,7 +274,7 @@ position_mark (const hb_ot_shape_plan_t *plan,
 
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
     case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
-      pos.y_offset += base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
+      pos.y_offset = base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
       base_extents.y_bearing -= mark_extents.height;
       base_extents.height += mark_extents.height;
       break;
commit c16012e9019ec59c2200a3cc29b8a37ea70eda70
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 02:27:00 2013 +0200

    [indic] Add Javanese support!
    
    Seems to be working just fine!

diff --git a/src/hb-ot-shape-complex-indic-machine.rl b/src/hb-ot-shape-complex-indic-machine.rl
index e964655..f3f550f 100644
--- a/src/hb-ot-shape-complex-indic-machine.rl
+++ b/src/hb-ot-shape-complex-indic-machine.rl
@@ -51,12 +51,13 @@ VD   = 9;
 A    = 10;
 NBSP = 11;
 DOTTEDCIRCLE = 12;
-RS   = 13;
+RS    = 13;
 Coeng = 14;
 Repha = 15;
 Ra    = 16;
 CM    = 17;
 Avag  = 18;
+CM2   = 41;
 
 c = (C | Ra);			# is_consonant
 n = ((ZWNJ?.RS)? (N.N?)?);	# is_consonant_modifier
@@ -73,14 +74,15 @@ syllable_tail =  (Coeng (cn|V))? avagraha? syllable_tail2;
 place_holder = NBSP | DOTTEDCIRCLE;
 halant_group = (z?.h.(ZWJ.N?)?);
 final_halant_group = halant_group | h.ZWNJ;
-halant_or_matra_group = (CM.CM* | final_halant_group | (h.ZWJ)? matra_group{0,4});
+medial_group = CM?.CM2?;
+halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4});
 
 
-consonant_syllable =	Repha? (cn.halant_group){0,4} cn halant_or_matra_group? syllable_tail;
-vowel_syllable =	reph? V.n? (ZWJ | (halant_group.cn){0,4} halant_or_matra_group? syllable_tail);
-standalone_cluster =	reph? place_holder.n? (halant_group.cn){0,4} halant_or_matra_group? syllable_tail;
+consonant_syllable =	Repha? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
+vowel_syllable =	reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail);
+standalone_cluster =	reph? place_holder.n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
 avagraha_cluster = 	avagraha syllable_tail2;
-broken_cluster =	reph? n? (halant_group.cn){0,4} halant_or_matra_group syllable_tail;
+broken_cluster =	reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
 other =			any;
 
 main := |*
diff --git a/src/hb-ot-shape-complex-indic-private.hh b/src/hb-ot-shape-complex-indic-private.hh
index cee1572..7101eb8 100644
--- a/src/hb-ot-shape-complex-indic-private.hh
+++ b/src/hb-ot-shape-complex-indic-private.hh
@@ -43,24 +43,25 @@
  * Not sure how to avoid duplication. */
 enum indic_category_t {
   OT_X = 0,
-  OT_C,
-  OT_V,
-  OT_N,
-  OT_H,
-  OT_ZWNJ,
-  OT_ZWJ,
-  OT_M,
-  OT_SM,
-  OT_VD,
-  OT_A,
-  OT_NBSP,
-  OT_DOTTEDCIRCLE, /* Not in the spec, but special in Uniscribe. /Very very/ special! */
-  OT_RS, /* Register Shifter, used in Khmer OT spec */
-  OT_Coeng,
-  OT_Repha,
-  OT_Ra, /* Not explicitly listed in the OT spec, but used in the grammar. */
-  OT_CM,
-  OT_Avag
+  OT_C = 1,
+  OT_V = 2,
+  OT_N = 3,
+  OT_H = 4,
+  OT_ZWNJ = 5,
+  OT_ZWJ = 6,
+  OT_M = 7,
+  OT_SM = 8,
+  OT_VD = 9,
+  OT_A = 10,
+  OT_NBSP = 11,
+  OT_DOTTEDCIRCLE = 12,
+  OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
+  OT_Coeng = 14, /* Khmer-style Virama. */
+  OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
+  OT_Ra = 16,
+  OT_CM = 17,  /* Consonant-Medial. */
+  OT_Avag = 18, /* Avagraha. */
+  OT_CM2 = 41 /* Consonant-Medial, second slot. */
 };
 
 /* Visual positions in a syllable from left to right. */
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index fcce57e..9a8b4e3 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -152,12 +152,14 @@ is_joiner (const hb_glyph_info_t &info)
   return is_one_of (info, JOINER_FLAGS);
 }
 
+#define MEDIAL_FLAGS (FLAG (OT_CM) | FLAG (OT_CM2))
+
 /* Note:
  *
  * We treat Vowels and placeholders as if they were consonants.  This is safe because Vowels
  * cannot happen in a consonant syllable.  The plus side however is, we can call the
  * consonant syllable logic from the vowel syllable function and get it all right! */
-#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CM) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
 static inline bool
 is_consonant (const hb_glyph_info_t &info)
 {
@@ -213,6 +215,9 @@ set_indic_properties (hb_glyph_info_t &info)
   else if (unlikely (u == 0x200D)) cat = OT_ZWJ;
   else if (unlikely (u == 0x25CC)) cat = OT_DOTTEDCIRCLE;
   else if (unlikely (u == 0x0A71)) cat = OT_SM; /* GURMUKHI ADDAK.  Move it to the end. */
+  else if (unlikely (u == 0xA982)) cat = OT_SM; /* Javanese repha. */
+  else if (unlikely (u == 0xA9BE)) cat = OT_CM2; /* Javanese medial ya. */
+  else if (unlikely (u == 0xA9BD)) { cat = OT_M; pos = POS_POST_C; } /* Javanese vocalic r. */
 
   if (cat == OT_Repha) {
     /* There are two kinds of characters marked as Repha:
@@ -931,7 +936,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
     indic_position_t last_pos = POS_START;
     for (unsigned int i = start; i < end; i++)
     {
-      if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | HALANT_OR_COENG_FLAGS)))
+      if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS)))
       {
 	info[i].indic_position() = last_pos;
 	if (unlikely (info[i].indic_category() == OT_H &&
commit 755b44cce6dc23376a3cf0212893609231fa4967
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 11:17:42 2013 +0200

    [ft] Round metrics instead of truncate
    
    Lohit-Punjabi has a upem of 769!  We were losing one unit in our
    code, and FreeType is losing another one...  Test with U+0A06.
    Has an advance of 854 in the font.  We were producing 852.
    Now we do 853, which is what FreeType is telling us.

diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index ff1e187..113b0eb 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -94,7 +94,7 @@ hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
   if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v)))
     return 0;
 
-  return v >> 10;
+  return (v + (1<<9)) >> 10;
 }
 
 static hb_position_t
@@ -112,7 +112,7 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
 
   /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
    * have a Y growing upward.  Hence the extra negation. */
-  return -v >> 10;
+  return (-v + (1<<9)) >> 10;
 }
 
 static hb_bool_t
@@ -418,8 +418,8 @@ hb_ft_font_create (FT_Face           ft_face,
 		     _hb_ft_get_font_funcs (),
 		     ft_face, (hb_destroy_func_t) _do_nothing);
   hb_font_set_scale (font,
-		     ((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM) >> 16,
-		     ((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM) >> 16);
+		     ((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16,
+		     ((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16);
   hb_font_set_ppem (font,
 		    ft_face->size->metrics.x_ppem,
 		    ft_face->size->metrics.y_ppem);
commit 9a49351cc2625de16a73e0e153d3097ef6c7cc0f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 02:14:53 2013 +0200

    [indic] Swith pref logic to use _hb_glyph_info_substituted()
    
    See comments from caveat!  Seems to work fine.
    
    This is useful for Javanese which has an atomically encoded pre-base
    reordering Ra which should only be reordered if it was substituted
    by the pref feature.

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 8016d85..fcce57e 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -1552,7 +1552,9 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
 	 *          of the <pref> feature. (Note that a font may shape a Ra consonant with
 	 *          the feature generally but block it in certain contexts.)
 	 */
-	if (i + 1 == end || (info[i + 1].mask & indic_plan->mask_array[PREF]) == 0)
+        /* Note: We just check that something got substituted.  We don't check that
+	 * the <pref> feature actually did it... */
+	if (_hb_glyph_info_substituted (&info[i]))
 	{
 	  /*
 	   *       2. Try to find a target position the same way as for pre-base matra.
@@ -1573,7 +1575,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
 		   !(is_one_of (info[new_pos - 1], FLAG(OT_M) | HALANT_OR_COENG_FLAGS)))
 	      new_pos--;
 
-	    /* In Khmer coeng model, a V,Ra can go *after* matras.  If it goes after a
+	    /* In Khmer coeng model, a H,Ra can go *after* matras.  If it goes after a
 	     * split matra, it should be reordered to *before* the left part of such matra. */
 	    if (new_pos > start && info[new_pos - 1].indic_category() == OT_M)
 	    {
commit f175aa33c5e94397c60648ac0697c80f5fe0dcb7
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 02:07:44 2013 +0200

    [indic] Fix compiler warnings

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 1407ada..8016d85 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -711,7 +711,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
      *    and has more than one consonant, Ra is excluded from candidates for
      *    base consonants. */
     unsigned int limit = start;
-    if (indic_plan->config->reph_pos != POS_RA_TO_BECOME_REPH &&
+    if (indic_plan->config->reph_pos != REPH_POS_DONT_CARE &&
 	indic_plan->mask_array[RPHF] &&
 	start + 3 <= end &&
 	(
@@ -1411,7 +1411,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
     unsigned int new_reph_pos;
     reph_position_t reph_pos = indic_plan->config->reph_pos;
 
-    assert (reph_pos != POS_RA_TO_BECOME_REPH);
+    assert (reph_pos != REPH_POS_DONT_CARE);
 
     /*       1. If reph should be positioned after post-base consonant forms,
      *          proceed to step 5.
commit 857027341423f15fd6084c7563cc355b06e7cbdd
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 01:11:05 2013 +0200

    [otlayout] Add _hb_glyph_info_substituted()
    
    Currently unused.

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 27648c9..93d2d76 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -371,6 +371,12 @@ _hb_glyph_info_is_mark (const hb_glyph_info_t *info)
 }
 
 static inline bool
+_hb_glyph_info_substituted (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
+}
+
+static inline bool
 _hb_glyph_info_ligated (const hb_glyph_info_t *info)
 {
   return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
commit a1f7b2856184959e965c9c2b80363f9f46d486a7
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 01:09:08 2013 +0200

    [otlayout] Switch over from old is_a_ligature() to IS_LIGATED
    
    Impact should be minimal and positive.

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 70e0af0..16c96fa 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -409,7 +409,7 @@ struct hb_apply_context_t
       if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
 		    (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
 		    (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
-		    !_hb_glyph_info_is_ligated (&info)))
+		    !_hb_glyph_info_ligated (&info)))
 	return SKIP_MAYBE;
 
       return SKIP_NO;
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index c37117b..27648c9 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -306,7 +306,7 @@ _hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
 }
 
 static inline bool
-_hb_glyph_info_is_ligated (const hb_glyph_info_t *info)
+_hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
 {
   return !!(info->lig_props() & IS_LIG_BASE);
 }
@@ -314,7 +314,7 @@ _hb_glyph_info_is_ligated (const hb_glyph_info_t *info)
 static inline unsigned int
 _hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
 {
-  if (_hb_glyph_info_is_ligated (info))
+  if (_hb_glyph_info_ligated_internal (info))
     return 0;
   else
     return info->lig_props() & 0x0F;
@@ -324,7 +324,7 @@ static inline unsigned int
 _hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
 {
   if ((info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) &&
-      _hb_glyph_info_is_ligated (info))
+      _hb_glyph_info_ligated_internal (info))
     return info->lig_props() & 0x0F;
   else
     return 1;
@@ -370,6 +370,12 @@ _hb_glyph_info_is_mark (const hb_glyph_info_t *info)
   return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
 }
 
+static inline bool
+_hb_glyph_info_ligated (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
+}
+
 /* Allocation / deallocation. */
 
 inline void
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 0835f7d..1407ada 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -141,7 +141,7 @@ static inline bool
 is_one_of (const hb_glyph_info_t &info, unsigned int flags)
 {
   /* If it ligated, all bets are off. */
-  if (_hb_glyph_info_is_ligated (&info)) return false;
+  if (_hb_glyph_info_ligated (&info)) return false;
   return !!(FLAG (info.indic_category()) & flags);
 }
 
@@ -1406,7 +1406,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
   if (start + 1 < end &&
       info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
       ((info[start].indic_category() == OT_Repha) ^
-       _hb_glyph_info_is_ligated (&info[start])))
+       _hb_glyph_info_ligated (&info[start])))
   {
     unsigned int new_reph_pos;
     reph_position_t reph_pos = indic_plan->config->reph_pos;
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index b5ac107..a32405a 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -151,7 +151,7 @@ static inline bool
 is_one_of (const hb_glyph_info_t &info, unsigned int flags)
 {
   /* If it ligated, all bets are off. */
-  if (_hb_glyph_info_is_ligated (&info)) return false;
+  if (_hb_glyph_info_ligated (&info)) return false;
   return !!(FLAG (info.myanmar_category()) & flags);
 }
 
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 16e6081..0296643 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -548,7 +548,7 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
   unsigned int j = 0;
   for (unsigned int i = 0; i < count; i++)
   {
-    if (unlikely (!_hb_glyph_info_is_ligated (&info[i]) &&
+    if (unlikely (!_hb_glyph_info_ligated (&info[i]) &&
 		  _hb_glyph_info_is_default_ignorable (&info[i])))
     {
       if (space_status == SPACE_DONT_KNOW)
commit 09675a8115b9d77261c33940401aa919cede8662
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 01:05:58 2013 +0200

    [otlayout] Add HB_OT_LAYOUT_GLYPH_PROPS_LIGATED
    
    Currently unused.

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 8a0ed0c..70e0af0 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -616,13 +616,18 @@ struct hb_apply_context_t
   }
 
   inline void _set_glyph_props (hb_codepoint_t glyph_index,
-			  unsigned int class_guess = 0) const
-  {
-    unsigned int add_in = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+			  unsigned int class_guess = 0,
+			  bool ligature = false) const
+  {
+    unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
+			  HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+    add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+    if (ligature)
+      add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
     if (likely (has_glyph_classes))
       _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
     else if (class_guess)
-      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in| class_guess);
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
   }
 
   inline void replace_glyph (hb_codepoint_t glyph_index) const
@@ -638,7 +643,7 @@ struct hb_apply_context_t
   inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
 					   unsigned int class_guess) const
   {
-    _set_glyph_props (glyph_index, class_guess);
+    _set_glyph_props (glyph_index, class_guess, true);
     buffer->replace_glyph (glyph_index);
   }
   inline void output_glyph (hb_codepoint_t glyph_index,
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 1da4400..c37117b 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -50,8 +50,11 @@ typedef enum
   HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u,
 
   /* The following are used internally; not derived from GDEF. */
-  HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED	= 0x10u
+  HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED	= 0x10u,
+  HB_OT_LAYOUT_GLYPH_PROPS_LIGATED	= 0x20u,
 
+  HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE     = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
+					  HB_OT_LAYOUT_GLYPH_PROPS_LIGATED
 } hb_ot_layout_glyph_class_mask_t;
 
 
commit 05ad6b50ac0a1b9a8da10d2ee2238068b7811e7d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 00:45:59 2013 +0200

    [otlayout] Add HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED
    
    Currently unused.

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 470ba30..8a0ed0c 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -618,10 +618,11 @@ struct hb_apply_context_t
   inline void _set_glyph_props (hb_codepoint_t glyph_index,
 			  unsigned int class_guess = 0) const
   {
+    unsigned int add_in = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
     if (likely (has_glyph_classes))
-      _hb_glyph_info_set_glyph_props (&buffer->cur(), gdef.get_glyph_props (glyph_index));
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
     else if (class_guess)
-      _hb_glyph_info_set_glyph_props (&buffer->cur(), class_guess);
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in| class_guess);
   }
 
   inline void replace_glyph (hb_codepoint_t glyph_index) const
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 6c7574f..1da4400 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -42,13 +42,15 @@
  * GDEF
  */
 
-typedef enum {
-  /* One bit available here...          = 0x01u */
-
+typedef enum
+{
   /* The following three match LookupFlags::Ignore* numbers. */
   HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH	= 0x02u,
   HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE	= 0x04u,
-  HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u
+  HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u,
+
+  /* The following are used internally; not derived from GDEF. */
+  HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED	= 0x10u
 
 } hb_ot_layout_glyph_class_mask_t;
 
commit 101303dbf7cf15d044bf2518f14b3aec65970fea
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 00:42:39 2013 +0200

    [otlayout] More shuffling around

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 0cf969d..b1f1a61 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -877,7 +877,7 @@ struct CursivePosFormat1
     TRACE_APPLY (this);
 
     /* We don't handle mark glyphs here. */
-    if (c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false);
+    if (unlikely (_hb_glyph_info_is_mark (&c->buffer->cur()))) return TRACE_RETURN (false);
 
     hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
     if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
@@ -1035,8 +1035,8 @@ struct MarkBasePosFormat1
       skippy_iter.reject ();
     } while (1);
 
-    /* The following assertion is too strong, so we've disabled it. */
-    if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
+    /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
+    if (!_hb_glyph_info_is_base_glyph (&c->buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
 
     unsigned int base_index = (this+baseCoverage).get_coverage  (c->buffer->info[skippy_iter.idx].codepoint);
     if (base_index == NOT_COVERED) return TRACE_RETURN (false);
@@ -1133,8 +1133,8 @@ struct MarkLigPosFormat1
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
     if (!skippy_iter.prev ()) return TRACE_RETURN (false);
 
-    /* The following assertion is too strong, so we've disabled it. */
-    if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
+    /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
+    if (!_hb_glyph_info_is_ligature (&c->buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
 
     unsigned int j = skippy_iter.idx;
     unsigned int lig_index = (this+ligatureCoverage).get_coverage  (c->buffer->info[j].codepoint);
@@ -1248,7 +1248,7 @@ struct MarkMarkPosFormat1
     skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
     if (!skippy_iter.prev ()) return TRACE_RETURN (false);
 
-    if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) { return TRACE_RETURN (false); }
+    if (!_hb_glyph_info_is_mark (&c->buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); }
 
     unsigned int j = skippy_iter.idx;
 
@@ -1591,9 +1591,7 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
   for (unsigned int i = 0; i < len; i++)
     fix_mark_attachment (pos, i, direction);
 
-  HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
-  HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
-  HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
+  _hb_buffer_deallocate_gsubgpos_vars (buffer);
 }
 
 
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index e0d2d36..d5f8b31 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -291,8 +291,7 @@ struct Sequence
     TRACE_APPLY (this);
     if (unlikely (!substitute.len)) return TRACE_RETURN (false);
 
-    unsigned int klass = c->buffer->cur().glyph_props() &
-			 HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ?
+    unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
 			 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
     unsigned int count = substitute.len;
     if (count == 1) /* Special-case to make it in-place. */
@@ -1375,15 +1374,15 @@ struct GSUB : GSUBGPOS
 void
 GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
 {
-  HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
-  HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
-  HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
+  _hb_buffer_allocate_gsubgpos_vars (buffer);
 
   const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
   unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++) {
-    buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
+  for (unsigned int i = 0; i < count; i++)
+  {
     _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
+    _hb_glyph_info_clear_lig_props (&buffer->info[i]);
+    buffer->info[i].syllable() = 0;
   }
 }
 
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 3cafbbd..470ba30 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -401,7 +401,7 @@ struct hb_apply_context_t
     {
       unsigned int property;
 
-      property = info.glyph_props();
+      property = _hb_glyph_info_get_glyph_props (&info);
 
       if (!c->match_properties (info.codepoint, property, lookup_props))
 	return SKIP_YES;
@@ -610,7 +610,7 @@ struct hb_apply_context_t
   {
     unsigned int property;
 
-    property = info->glyph_props();
+    property = _hb_glyph_info_get_glyph_props (info);
 
     return match_properties (info->codepoint, property, lookup_props);
   }
@@ -790,7 +790,7 @@ static inline bool match_input (hb_apply_context_t *c,
    *   ligate with a conjunct...)
    */
 
-  bool is_mark_ligature = !!(buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+  bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
 
   unsigned int total_component_count = 0;
   total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
@@ -822,7 +822,7 @@ static inline bool match_input (hb_apply_context_t *c,
 	return TRACE_RETURN (false);
     }
 
-    is_mark_ligature = is_mark_ligature && (buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+    is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]);
     total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
   }
 
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 9468b34..6c7574f 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -38,16 +38,6 @@
 #include "hb-set-private.hh"
 
 
-/* buffer var allocations, used during the entire shaping process */
-#define unicode_props0()	var2.u8[0]
-#define unicode_props1()	var2.u8[1]
-
-/* buffer var allocations, used during the GSUB/GPOS processing */
-#define glyph_props()		var1.u16[0] /* GDEF glyph properties */
-#define lig_props()		var1.u8[2] /* GSUB/GPOS ligature tracking */
-#define syllable()		var1.u8[3] /* GSUB/GPOS shaping boundaries */
-
-
 /*
  * GDEF
  */
@@ -171,6 +161,15 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout);
  * Buffer var routines.
  */
 
+/* buffer var allocations, used during the entire shaping process */
+#define unicode_props0()	var2.u8[0]
+#define unicode_props1()	var2.u8[1]
+
+/* buffer var allocations, used during the GSUB/GPOS processing */
+#define glyph_props()		var1.u16[0] /* GDEF glyph properties */
+#define lig_props()		var1.u8[2] /* GSUB/GPOS ligature tracking */
+#define syllable()		var1.u8[3] /* GSUB/GPOS shaping boundaries */
+
 /* unicode_props */
 
 enum {
@@ -264,7 +263,15 @@ _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
  * The numbers are also used in GPOS to do mark-to-mark positioning only
  * to marks that belong to the same component of the same ligature.
  */
+
+static inline void
+_hb_glyph_info_clear_lig_props (hb_glyph_info_t *info)
+{
+  info->lig_props() = 0;
+}
+
 #define IS_LIG_BASE 0x10
+
 static inline void
 _hb_glyph_info_set_lig_props_for_ligature (hb_glyph_info_t *info,
 					   unsigned int lig_id,
@@ -272,6 +279,7 @@ _hb_glyph_info_set_lig_props_for_ligature (hb_glyph_info_t *info,
 {
   info->lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
 }
+
 static inline void
 _hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info,
 				       unsigned int lig_id,
@@ -279,6 +287,7 @@ _hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info,
 {
   info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
 }
+
 static inline void
 _hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp)
 {
@@ -290,11 +299,13 @@ _hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
 {
   return info->lig_props() >> 5;
 }
+
 static inline bool
 _hb_glyph_info_is_ligated (const hb_glyph_info_t *info)
 {
   return !!(info->lig_props() & IS_LIG_BASE);
 }
+
 static inline unsigned int
 _hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
 {
@@ -303,6 +314,7 @@ _hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
   else
     return info->lig_props() & 0x0F;
 }
+
 static inline unsigned int
 _hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
 {
@@ -329,7 +341,67 @@ _hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
   info->glyph_props() = props;
 }
 
+inline unsigned int
+_hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
+{
+  return info->glyph_props();
+}
+
+inline bool
+_hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
+}
+
+inline bool
+_hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
+}
+
+inline bool
+_hb_glyph_info_is_mark (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+}
+
+/* Allocation / deallocation. */
+
+inline void
+_hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0);
+  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1);
+}
+
+inline void
+_hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1);
+}
+
+inline void
+_hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
+  HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
+  HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
+}
+
+inline void
+_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
+}
 
+/* Make sure no one directly touches our props... */
+#undef unicode_props0
+#undef unicode_props1
+#undef lig_props
+#undef glyph_props
 
 
 #endif /* HB_OT_LAYOUT_PRIVATE_HH */
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 0dcb9fc..16e6081 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -410,7 +410,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer)
 {
   unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++)
-    if ((buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
+    if (_hb_glyph_info_is_mark (&buffer->info[i]))
     {
       buffer->pos[i].x_advance = 0;
       buffer->pos[i].y_advance = 0;
@@ -584,8 +584,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
   /* Save the original direction, we use it later. */
   c->target_direction = c->buffer->props.direction;
 
-  HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0);
-  HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1);
+  _hb_buffer_allocate_unicode_vars (c->buffer);
 
   c->buffer->clear_output ();
 
@@ -600,8 +599,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
 
   hb_ot_hide_default_ignorables (c);
 
-  HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
-  HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);
+  _hb_buffer_deallocate_unicode_vars (c->buffer);
 
   c->buffer->props.direction = c->target_direction;
 
commit 91689de2603e4151e2a2d3a3852c61667f0c6264
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 00:21:59 2013 +0200

    [otlayout] Add _hb_glyph_info_set_glyph_props()
    
    No functional change.

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 1a0f183..e0d2d36 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1383,7 +1383,7 @@ GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
   unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++) {
     buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
-    buffer->info[i].glyph_props() = gdef.get_glyph_props (buffer->info[i].codepoint);
+    _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
   }
 }
 
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index ff53d3b..3cafbbd 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -619,9 +619,9 @@ struct hb_apply_context_t
 			  unsigned int class_guess = 0) const
   {
     if (likely (has_glyph_classes))
-      buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index);
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), gdef.get_glyph_props (glyph_index));
     else if (class_guess)
-      buffer->cur().glyph_props() = class_guess;
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), class_guess);
   }
 
   inline void replace_glyph (hb_codepoint_t glyph_index) const
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 406a042..9468b34 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -321,6 +321,15 @@ _hb_allocate_lig_id (hb_buffer_t *buffer) {
   return lig_id;
 }
 
+/* glyph_props: */
+
+inline void
+_hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
+{
+  info->glyph_props() = props;
+}
+
+
 
 
 #endif /* HB_OT_LAYOUT_PRIVATE_HH */
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index e68344b..0dcb9fc 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -339,9 +339,11 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
 {
   unsigned int count = c->buffer->len;
   for (unsigned int i = 0; i < count; i++)
-    c->buffer->info[i].glyph_props() = _hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
-				       HB_OT_LAYOUT_GLYPH_PROPS_MARK :
-				       HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+    _hb_glyph_info_set_glyph_props (&c->buffer->info[i],
+				    _hb_glyph_info_get_general_category (&c->buffer->info[i])
+				    == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
+				    HB_OT_LAYOUT_GLYPH_PROPS_MARK :
+				    HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
 }
 
 static inline void
commit a0161746589934e93c3b115814bbd81f56ab962f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 00:06:30 2013 +0200

    [otlayout] Simplify set_class() usage

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 329ba4b..ff53d3b 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -615,7 +615,8 @@ struct hb_apply_context_t
     return match_properties (info->codepoint, property, lookup_props);
   }
 
-  inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
+  inline void _set_glyph_props (hb_codepoint_t glyph_index,
+			  unsigned int class_guess = 0) const
   {
     if (likely (has_glyph_classes))
       buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index);
@@ -623,23 +624,27 @@ struct hb_apply_context_t
       buffer->cur().glyph_props() = class_guess;
   }
 
-  inline void output_glyph (hb_codepoint_t glyph_index,
-			    unsigned int class_guess = 0) const
+  inline void replace_glyph (hb_codepoint_t glyph_index) const
   {
-    set_class (glyph_index, class_guess);
-    buffer->output_glyph (glyph_index);
+    _set_glyph_props (glyph_index);
+    buffer->replace_glyph (glyph_index);
   }
-  inline void replace_glyph (hb_codepoint_t glyph_index,
-			     unsigned int class_guess = 0) const
+  inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const
   {
-    set_class (glyph_index, class_guess);
+    _set_glyph_props (glyph_index);
+    buffer->cur().codepoint = glyph_index;
+  }
+  inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
+					   unsigned int class_guess) const
+  {
+    _set_glyph_props (glyph_index, class_guess);
     buffer->replace_glyph (glyph_index);
   }
-  inline void replace_glyph_inplace (hb_codepoint_t glyph_index,
-				     unsigned int class_guess = 0) const
+  inline void output_glyph (hb_codepoint_t glyph_index,
+			    unsigned int class_guess) const
   {
-    set_class (glyph_index, class_guess);
-    buffer->cur().codepoint = glyph_index;
+    _set_glyph_props (glyph_index, class_guess);
+    buffer->output_glyph (glyph_index);
   }
 };
 
@@ -885,7 +890,7 @@ static inline void ligate_input (hb_apply_context_t *c,
     if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
       _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
   }
-  c->replace_glyph (lig_glyph, klass);
+  c->replace_glyph_with_ligature (lig_glyph, klass);
 
   for (unsigned int i = 1; i < count; i++)
   {
commit 3ddf892b5328b74afb6e7d9da727d8771ca5d288
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 18 00:02:43 2013 +0200

    [otlayout] Renaming

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 05a6f5e..0cf969d 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1031,7 +1031,7 @@ struct MarkBasePosFormat1
     do {
       if (!skippy_iter.prev ()) 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;
+      if (0 == _hb_glyph_info_get_lig_comp (&c->buffer->info[skippy_iter.idx])) break;
       skippy_iter.reject ();
     } while (1);
 
@@ -1152,11 +1152,11 @@ struct MarkLigPosFormat1
      * can directly use the component index.  If not, we attach the mark
      * glyph to the last component of the ligature. */
     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());
+    unsigned int lig_id = _hb_glyph_info_get_lig_id (&c->buffer->info[j]);
+    unsigned int mark_id = _hb_glyph_info_get_lig_id (&c->buffer->cur());
+    unsigned int mark_comp = _hb_glyph_info_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;
+      comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&c->buffer->cur())) - 1;
     else
       comp_index = comp_count - 1;
 
@@ -1252,10 +1252,10 @@ struct MarkMarkPosFormat1
 
     unsigned int j = skippy_iter.idx;
 
-    unsigned int id1 = get_lig_id (c->buffer->cur());
-    unsigned int id2 = get_lig_id (c->buffer->info[j]);
-    unsigned int comp1 = get_lig_comp (c->buffer->cur());
-    unsigned int comp2 = get_lig_comp (c->buffer->info[j]);
+    unsigned int id1 = _hb_glyph_info_get_lig_id (&c->buffer->cur());
+    unsigned int id2 = _hb_glyph_info_get_lig_id (&c->buffer->info[j]);
+    unsigned int comp1 = _hb_glyph_info_get_lig_comp (&c->buffer->cur());
+    unsigned int comp2 = _hb_glyph_info_get_lig_comp (&c->buffer->info[j]);
 
     if (likely (id1 == id2)) {
       if (id1 == 0) /* Marks belonging to the same base. */
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index a07a779..1a0f183 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -302,7 +302,7 @@ struct Sequence
     else
     {
       for (unsigned int i = 0; i < count; i++) {
-	set_lig_props_for_component (c->buffer->cur(), i);
+	_hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
 	c->output_glyph (substitute.array[i], klass);
       }
       c->buffer->skip_glyph ();
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index f156b98..329ba4b 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -409,7 +409,7 @@ struct hb_apply_context_t
       if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
 		    (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
 		    (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
-		    !is_a_ligature (info)))
+		    !_hb_glyph_info_is_ligated (&info)))
 	return SKIP_MAYBE;
 
       return SKIP_NO;
@@ -788,10 +788,10 @@ static inline bool match_input (hb_apply_context_t *c,
   bool is_mark_ligature = !!(buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
 
   unsigned int total_component_count = 0;
-  total_component_count += get_lig_num_comps (buffer->cur());
+  total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
 
-  unsigned int first_lig_id = get_lig_id (buffer->cur());
-  unsigned int first_lig_comp = get_lig_comp (buffer->cur());
+  unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+  unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
 
   match_positions[0] = buffer->idx;
   for (unsigned int i = 1; i < count; i++)
@@ -800,8 +800,8 @@ static inline bool match_input (hb_apply_context_t *c,
 
     match_positions[i] = skippy_iter.idx;
 
-    unsigned int this_lig_id = get_lig_id (buffer->info[skippy_iter.idx]);
-    unsigned int this_lig_comp = get_lig_comp (buffer->info[skippy_iter.idx]);
+    unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
+    unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
 
     if (first_lig_id && first_lig_comp) {
       /* If first component was attached to a previous ligature component,
@@ -818,7 +818,7 @@ static inline bool match_input (hb_apply_context_t *c,
     }
 
     is_mark_ligature = is_mark_ligature && (buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
-    total_component_count += get_lig_num_comps (buffer->info[skippy_iter.idx]);
+    total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
   }
 
   *end_offset = skippy_iter.idx - buffer->idx + 1;
@@ -874,14 +874,14 @@ static inline void ligate_input (hb_apply_context_t *c,
    */
 
   unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
-  unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (buffer);
-  unsigned int last_lig_id = get_lig_id (buffer->cur());
-  unsigned int last_num_components = get_lig_num_comps (buffer->cur());
+  unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer);
+  unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+  unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
   unsigned int components_so_far = last_num_components;
 
   if (!is_mark_ligature)
   {
-    set_lig_props_for_ligature (buffer->cur(), lig_id, total_component_count);
+    _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count);
     if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
       _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
   }
@@ -893,14 +893,14 @@ static inline void ligate_input (hb_apply_context_t *c,
     {
       if (!is_mark_ligature) {
 	unsigned int new_lig_comp = components_so_far - last_num_components +
-				    MIN (MAX (get_lig_comp (buffer->cur()), 1u), last_num_components);
-	set_lig_props_for_mark (buffer->cur(), lig_id, new_lig_comp);
+				    MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components);
+	_hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
       }
       buffer->next_glyph ();
     }
 
-    last_lig_id = get_lig_id (buffer->cur());
-    last_num_components = get_lig_num_comps (buffer->cur());
+    last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+    last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
     components_so_far += last_num_components;
 
     /* Skip the base glyph */
@@ -910,10 +910,10 @@ static inline void ligate_input (hb_apply_context_t *c,
   if (!is_mark_ligature && last_lig_id) {
     /* Re-adjust components for any marks following. */
     for (unsigned int i = buffer->idx; i < buffer->len; i++) {
-      if (last_lig_id == get_lig_id (buffer->info[i])) {
+      if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
 	unsigned int new_lig_comp = components_so_far - last_num_components +
-				    MIN (MAX (get_lig_comp (buffer->info[i]), 1u), last_num_components);
-	set_lig_props_for_mark (buffer->info[i], lig_id, new_lig_comp);
+				    MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components);
+	_hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
       } else
 	break;
     }
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 5b16dfc..406a042 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -191,7 +191,8 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *uni
 }
 
 inline void
-_hb_glyph_info_set_general_category (hb_glyph_info_t *info, hb_unicode_general_category_t gen_cat)
+_hb_glyph_info_set_general_category (hb_glyph_info_t *info,
+				     hb_unicode_general_category_t gen_cat)
 {
   info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT);
 }
@@ -203,7 +204,8 @@ _hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
 }
 
 inline void
-_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class)
+_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
+					     unsigned int modified_class)
 {
   info->unicode_props1() = modified_class;
 }
@@ -264,52 +266,58 @@ _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
  */
 #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)
+_hb_glyph_info_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) | IS_LIG_BASE | (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)
+_hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info,
+				       unsigned int lig_id,
+				       unsigned int lig_comp)
 {
-  info.lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
+  info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
 }
 static inline void
-set_lig_props_for_component (hb_glyph_info_t &info, unsigned int comp)
+_hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp)
 {
-  set_lig_props_for_mark (info, 0, comp);
+  _hb_glyph_info_set_lig_props_for_mark (info, 0, comp);
 }
 
 static inline unsigned int
-get_lig_id (const hb_glyph_info_t &info)
+_hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
 {
-  return info.lig_props() >> 5;
+  return info->lig_props() >> 5;
 }
 static inline bool
-is_a_ligature (const hb_glyph_info_t &info)
+_hb_glyph_info_is_ligated (const hb_glyph_info_t *info)
 {
-  return !!(info.lig_props() & IS_LIG_BASE);
+  return !!(info->lig_props() & IS_LIG_BASE);
 }
 static inline unsigned int
-get_lig_comp (const hb_glyph_info_t &info)
+_hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
 {
-  if (is_a_ligature (info))
+  if (_hb_glyph_info_is_ligated (info))
     return 0;
   else
-    return info.lig_props() & 0x0F;
+    return info->lig_props() & 0x0F;
 }
 static inline unsigned int
-get_lig_num_comps (const hb_glyph_info_t &info)
+_hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
 {
-  if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && is_a_ligature (info))
-    return info.lig_props() & 0x0F;
+  if ((info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) &&
+      _hb_glyph_info_is_ligated (info))
+    return info->lig_props() & 0x0F;
   else
     return 1;
 }
 
-static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
+static inline uint8_t
+_hb_allocate_lig_id (hb_buffer_t *buffer) {
   uint8_t lig_id = buffer->next_serial () & 0x07;
   if (unlikely (!lig_id))
-    lig_id = allocate_lig_id (buffer); /* in case of overflow */
+    lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
   return lig_id;
 }
 
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index bc79025..0835f7d 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -141,7 +141,7 @@ static inline bool
 is_one_of (const hb_glyph_info_t &info, unsigned int flags)
 {
   /* If it ligated, all bets are off. */
-  if (is_a_ligature (info)) return false;
+  if (_hb_glyph_info_is_ligated (&info)) return false;
   return !!(FLAG (info.indic_category()) & flags);
 }
 
@@ -1405,7 +1405,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
    */
   if (start + 1 < end &&
       info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
-      ((info[start].indic_category() == OT_Repha) ^ is_a_ligature (info[start])))
+      ((info[start].indic_category() == OT_Repha) ^
+       _hb_glyph_info_is_ligated (&info[start])))
   {
     unsigned int new_reph_pos;
     reph_position_t reph_pos = indic_plan->config->reph_pos;
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index 17811b5..b5ac107 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -151,7 +151,7 @@ static inline bool
 is_one_of (const hb_glyph_info_t &info, unsigned int flags)
 {
   /* If it ligated, all bets are off. */
-  if (is_a_ligature (info)) return false;
+  if (_hb_glyph_info_is_ligated (&info)) return false;
   return !!(FLAG (info.myanmar_category()) & flags);
 }
 
diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index 284d030..a7e3b8e 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -300,8 +300,8 @@ position_around_base (const hb_ot_shape_plan_t *plan,
   base_extents.x_bearing += buffer->pos[base].x_offset;
   base_extents.y_bearing += buffer->pos[base].y_offset;
 
-  unsigned int lig_id = get_lig_id (buffer->info[base]);
-  unsigned int num_lig_components = get_lig_num_comps (buffer->info[base]);
+  unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[base]);
+  unsigned int num_lig_components = _hb_glyph_info_get_lig_num_comps (&buffer->info[base]);
 
   hb_position_t x_offset = 0, y_offset = 0;
   if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
@@ -317,8 +317,8 @@ position_around_base (const hb_ot_shape_plan_t *plan,
     if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]))
     {
       if (num_lig_components > 1) {
-	unsigned int this_lig_id = get_lig_id (buffer->info[i]);
-	unsigned int this_lig_component = get_lig_comp (buffer->info[i]) - 1;
+	unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[i]);
+	unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&buffer->info[i]) - 1;
 	/* Conditions for attaching to the last component. */
 	if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
 	  this_lig_component = num_lig_components - 1;
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 4ed6b84..e68344b 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -546,7 +546,7 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
   unsigned int j = 0;
   for (unsigned int i = 0; i < count; i++)
   {
-    if (unlikely (!is_a_ligature (info[i]) &&
+    if (unlikely (!_hb_glyph_info_is_ligated (&info[i]) &&
 		  _hb_glyph_info_is_default_ignorable (&info[i])))
     {
       if (space_status == SPACE_DONT_KNOW)
commit 2e96d2c6ee34142375373be07217c9953e7822cc
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 17 21:16:20 2013 +0200

    [otlayout] More shuffling

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 0278cb5..5b16dfc 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -48,6 +48,131 @@
 #define syllable()		var1.u8[3] /* GSUB/GPOS shaping boundaries */
 
 
+/*
+ * GDEF
+ */
+
+typedef enum {
+  /* One bit available here...          = 0x01u */
+
+  /* The following three match LookupFlags::Ignore* numbers. */
+  HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH	= 0x02u,
+  HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE	= 0x04u,
+  HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u
+
+} hb_ot_layout_glyph_class_mask_t;
+
+
+/*
+ * GSUB/GPOS
+ */
+
+HB_INTERNAL hb_bool_t
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t            *face,
+					   unsigned int          lookup_index,
+					   const hb_codepoint_t *glyphs,
+					   unsigned int          glyphs_length,
+					   hb_bool_t             zero_context);
+
+
+/* Should be called before all the substitute_lookup's are done. */
+HB_INTERNAL void
+hb_ot_layout_substitute_start (hb_font_t    *font,
+			       hb_buffer_t  *buffer);
+
+
+struct hb_ot_layout_lookup_accelerator_t;
+
+namespace OT {
+  struct hb_apply_context_t;
+  struct SubstLookup;
+}
+
+HB_INTERNAL void
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+				const OT::SubstLookup &lookup,
+				const hb_ot_layout_lookup_accelerator_t &accel);
+
+
+/* Should be called after all the substitute_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_substitute_finish (hb_font_t    *font,
+				hb_buffer_t  *buffer);
+
+
+/* Should be called before all the position_lookup's are done.  Resets positions to zero. */
+HB_INTERNAL void
+hb_ot_layout_position_start (hb_font_t    *font,
+			     hb_buffer_t  *buffer);
+
+/* Should be called after all the position_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_position_finish (hb_font_t    *font,
+			      hb_buffer_t  *buffer);
+
+
+
+/*
+ * hb_ot_layout_t
+ */
+
+namespace OT {
+  struct GDEF;
+  struct GSUB;
+  struct GPOS;
+}
+
+struct hb_ot_layout_lookup_accelerator_t
+{
+  template <typename TLookup>
+  inline void init (const TLookup &lookup)
+  {
+    digest.init ();
+    lookup.add_coverage (&digest);
+  }
+
+  template <typename TLookup>
+  inline void fini (const TLookup &lookup)
+  {
+  }
+
+  hb_set_digest_t digest;
+};
+
+struct hb_ot_layout_t
+{
+  hb_blob_t *gdef_blob;
+  hb_blob_t *gsub_blob;
+  hb_blob_t *gpos_blob;
+
+  const struct OT::GDEF *gdef;
+  const struct OT::GSUB *gsub;
+  const struct OT::GPOS *gpos;
+
+  unsigned int gsub_lookup_count;
+  unsigned int gpos_lookup_count;
+
+  hb_ot_layout_lookup_accelerator_t *gsub_accels;
+  hb_ot_layout_lookup_accelerator_t *gpos_accels;
+};
+
+
+HB_INTERNAL hb_ot_layout_t *
+_hb_ot_layout_create (hb_face_t *face);
+
+HB_INTERNAL void
+_hb_ot_layout_destroy (hb_ot_layout_t *layout);
+
+
+#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
+
+
+/*
+ * Buffer var routines.
+ */
+
+/* unicode_props */
+
 enum {
   MASK0_ZWJ       = 0x20u,
   MASK0_ZWNJ      = 0x40u,
@@ -113,27 +238,7 @@ _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
   info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ;
 }
 
-
-/*
- * GDEF
- */
-
-typedef enum {
-  /* One bit available here...          = 0x01u */
-
-  /* The following three match LookupFlags::Ignore* numbers. */
-  HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH	= 0x02u,
-  HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE	= 0x04u,
-  HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u
-
-} hb_ot_layout_glyph_class_mask_t;
-
-
-/*
- * GSUB/GPOS
- */
-
-/* lig_id / lig_comp
+/* lig_props: aka lig_id / lig_comp
  *
  * When a ligature is formed:
  *
@@ -143,7 +248,9 @@ typedef enum {
  *   - 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
- *     in MarkLigPos.
+ *     in MarkLigPos,
+ *   - Note that when marks are ligated together, much of the above is skipped
+ *     and the current lig_id reused.
  *
  * When a multiple-substitution is done:
  *
@@ -153,7 +260,7 @@ typedef enum {
  *     multiple substitution in MarkBasePos.
  *
  * 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.
+ * to marks that belong to the same component of the same ligature.
  */
 #define IS_LIG_BASE 0x10
 static inline void
@@ -207,104 +314,5 @@ static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
 }
 
 
-HB_INTERNAL hb_bool_t
-hb_ot_layout_lookup_would_substitute_fast (hb_face_t            *face,
-					   unsigned int          lookup_index,
-					   const hb_codepoint_t *glyphs,
-					   unsigned int          glyphs_length,
-					   hb_bool_t             zero_context);
-
-
-/* Should be called before all the substitute_lookup's are done. */
-HB_INTERNAL void
-hb_ot_layout_substitute_start (hb_font_t    *font,
-			       hb_buffer_t  *buffer);
-
-
-struct hb_ot_layout_lookup_accelerator_t;
-
-namespace OT {
-  struct hb_apply_context_t;
-  struct SubstLookup;
-}
-
-HB_INTERNAL void
-hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
-				const OT::SubstLookup &lookup,
-				const hb_ot_layout_lookup_accelerator_t &accel);
-
-
-/* Should be called after all the substitute_lookup's are done */
-HB_INTERNAL void
-hb_ot_layout_substitute_finish (hb_font_t    *font,
-				hb_buffer_t  *buffer);
-
-
-/* Should be called before all the position_lookup's are done.  Resets positions to zero. */
-HB_INTERNAL void
-hb_ot_layout_position_start (hb_font_t    *font,
-			     hb_buffer_t  *buffer);
-
-/* Should be called after all the position_lookup's are done */
-HB_INTERNAL void
-hb_ot_layout_position_finish (hb_font_t    *font,
-			      hb_buffer_t  *buffer);
-
-
-
-/*
- * hb_ot_layout_t
- */
-
-namespace OT {
-  struct GDEF;
-  struct GSUB;
-  struct GPOS;
-}
-
-struct hb_ot_layout_lookup_accelerator_t
-{
-  template <typename TLookup>
-  inline void init (const TLookup &lookup)
-  {
-    digest.init ();
-    lookup.add_coverage (&digest);
-  }
-
-  template <typename TLookup>
-  inline void fini (const TLookup &lookup)
-  {
-  }
-
-  hb_set_digest_t digest;
-};
-
-struct hb_ot_layout_t
-{
-  hb_blob_t *gdef_blob;
-  hb_blob_t *gsub_blob;
-  hb_blob_t *gpos_blob;
-
-  const struct OT::GDEF *gdef;
-  const struct OT::GSUB *gsub;
-  const struct OT::GPOS *gpos;
-
-  unsigned int gsub_lookup_count;
-  unsigned int gpos_lookup_count;
-
-  hb_ot_layout_lookup_accelerator_t *gsub_accels;
-  hb_ot_layout_lookup_accelerator_t *gpos_accels;
-};
-
-
-HB_INTERNAL hb_ot_layout_t *
-_hb_ot_layout_create (hb_face_t *face);
-
-HB_INTERNAL void
-_hb_ot_layout_destroy (hb_ot_layout_t *layout);
-
-
-#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
-
 
 #endif /* HB_OT_LAYOUT_PRIVATE_HH */
commit 469524692bd0a258b28e63294c984e677a9c2477
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 17 21:01:57 2013 +0200

    [otlayout] Code shuffling

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 9a4d6d8..0278cb5 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2007,2008,2009  Red Hat, Inc.
- * Copyright © 2012  Google, Inc.
+ * Copyright © 2012,2013  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -38,15 +38,15 @@
 #include "hb-set-private.hh"
 
 
-/* buffer var allocations, used during the GSUB/GPOS processing */
-#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 */
-
 /* buffer var allocations, used during the entire shaping process */
 #define unicode_props0()	var2.u8[0]
 #define unicode_props1()	var2.u8[1]
 
+/* buffer var allocations, used during the GSUB/GPOS processing */
+#define glyph_props()		var1.u16[0] /* GDEF glyph properties */
+#define lig_props()		var1.u8[2] /* GSUB/GPOS ligature tracking */
+#define syllable()		var1.u8[3] /* GSUB/GPOS shaping boundaries */
+
 
 enum {
   MASK0_ZWJ       = 0x20u,
@@ -114,8 +114,6 @@ _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
 }
 
 
-#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
-
 /*
  * GDEF
  */
@@ -306,5 +304,7 @@ HB_INTERNAL void
 _hb_ot_layout_destroy (hb_ot_layout_t *layout);
 
 
+#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
+
 
 #endif /* HB_OT_LAYOUT_PRIVATE_HH */
commit 11fb16cb849285a178d9e80991b1d60a960326ee
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 17 20:57:57 2013 +0200

    Use unsigned enums for mask types

diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index 87c4ce5..3086851 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -172,10 +172,10 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
 
 
 typedef enum { /*< flags >*/
-  HB_BUFFER_FLAG_DEFAULT			= 0x00000000,
-  HB_BUFFER_FLAG_BOT				= 0x00000001, /* Beginning-of-text */
-  HB_BUFFER_FLAG_EOT				= 0x00000002, /* End-of-text */
-  HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES	= 0x00000004
+  HB_BUFFER_FLAG_DEFAULT			= 0x00000000u,
+  HB_BUFFER_FLAG_BOT				= 0x00000001u, /* Beginning-of-text */
+  HB_BUFFER_FLAG_EOT				= 0x00000002u, /* End-of-text */
+  HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES	= 0x00000004u
 } hb_buffer_flags_t;
 
 void
@@ -275,10 +275,10 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
  */
 
 typedef enum { /*< flags >*/
-  HB_BUFFER_SERIALIZE_FLAG_DEFAULT		= 0x00000000,
-  HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS		= 0x00000001,
-  HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS		= 0x00000002,
-  HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES	= 0x00000004
+  HB_BUFFER_SERIALIZE_FLAG_DEFAULT		= 0x00000000u,
+  HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS		= 0x00000001u,
+  HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS		= 0x00000002u,
+  HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES	= 0x00000004u
 } hb_buffer_serialize_flags_t;
 
 typedef enum {
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 92d7bdc..9a4d6d8 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -49,10 +49,10 @@
 
 
 enum {
-  MASK0_ZWJ  = 0x20,
-  MASK0_ZWNJ = 0x40,
-  MASK0_IGNORABLE = 0x80,
-  MASK0_GEN_CAT = 0x1F
+  MASK0_ZWJ       = 0x20u,
+  MASK0_ZWNJ      = 0x40u,
+  MASK0_IGNORABLE = 0x80u,
+  MASK0_GEN_CAT   = 0x1Fu
 };
 
 inline void
commit 03058c3d1e8c18858c1e0b0c738ce9d299f2787a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 17 20:55:34 2013 +0200

    [otlayout] Remove two unused HB_OT_LAYOUT_GLYPH_PROPS_* values

diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh
index f0e040c..389cbb9 100644
--- a/src/hb-ot-layout-gdef-table.hh
+++ b/src/hb-ot-layout-gdef-table.hh
@@ -391,7 +391,6 @@ struct GDEF
     default:			return 0;
     case BaseGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
     case LigatureGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
-    case ComponentGlyph:	return HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT;
     case MarkGlyph:
 	  klass = get_mark_attachment_type (glyph);
 	  return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 28ba3b9..a07a779 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -292,7 +292,8 @@ struct Sequence
     if (unlikely (!substitute.len)) return TRACE_RETURN (false);
 
     unsigned int klass = c->buffer->cur().glyph_props() &
-			 HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
+			 HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ?
+			 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
     unsigned int count = substitute.len;
     if (count == 1) /* Special-case to make it in-place. */
     {
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 2d7afb0..92d7bdc 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -121,10 +121,13 @@ _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
  */
 
 typedef enum {
+  /* One bit available here...          = 0x01u */
+
+  /* The following three match LookupFlags::Ignore* numbers. */
   HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH	= 0x02u,
   HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE	= 0x04u,
-  HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u,
-  HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT	= 0x10u, /* Unused; can be removed. */
+  HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u
+
 } hb_ot_layout_glyph_class_mask_t;
 
 
commit 941b6992042e7b73b3a2aab1448383adf33bef28
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 17 20:47:33 2013 +0200

    [otlayout] Remove unused HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED

diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh
index d2fd875..f0e040c 100644
--- a/src/hb-ot-layout-gdef-table.hh
+++ b/src/hb-ot-layout-gdef-table.hh
@@ -383,9 +383,12 @@ struct GDEF
   {
     unsigned int klass = get_glyph_class (glyph);
 
+    ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs);
+    ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures);
+    ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks);
+
     switch (klass) {
-    default:
-    case UnclassifiedGlyph:	return HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED;
+    default:			return 0;
     case BaseGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
     case LigatureGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
     case ComponentGlyph:	return HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT;
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 3f02c80..2d7afb0 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -121,15 +121,13 @@ _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
  */
 
 typedef enum {
-  HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED	= 1 << HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED,
-  HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH	= 1 << HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH,
-  HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE	= 1 << HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE,
-  HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 1 << HB_OT_LAYOUT_GLYPH_CLASS_MARK,
-  HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT	= 1 << HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT
+  HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH	= 0x02u,
+  HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE	= 0x04u,
+  HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u,
+  HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT	= 0x10u, /* Unused; can be removed. */
 } hb_ot_layout_glyph_class_mask_t;
 
 
-
 /*
  * GSUB/GPOS
  */



More information about the HarfBuzz mailing list