src/hb-ot-layout-gsub-table.hh           |   13 -
 src/hb-ot-layout-gsubgpos-private.hh     |    9 
 src/hb-ot-layout-private.hh              |   40 +++
 src/hb-ot-layout.cc                      |   38 ---
 src/hb-ot-layout.h                       |   34 ---
 src/hb-ot-map-private.hh                 |   15 -
 src/hb-ot-map.cc                         |   12 -
 src/hb-ot-shape-complex-indic-private.hh |  210 ++++++++++++++++++++
 src/hb-ot-shape-complex-indic.cc         |  319 ++++++-------------------------
 src/hb-ot-shape.cc                       |    6 
 10 files changed, 343 insertions(+), 353 deletions(-)

New commits:
commit 24eacf17c801c66a2d466e8ae02b73f501a26b25
Author: Behdad Esfahbod <beh...@behdad.org>
Date:   Thu Aug 2 08:42:11 2012 -0400

    [Indic] Move consonant-position-setting into initial_reordering()

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index cbc1231..19ff048 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -237,6 +237,34 @@ override_features_indic (const hb_ot_complex_shaper_t  
*shaper,
 
 
 static void
+setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
+                  const hb_ot_map_t            *map,
+                  hb_buffer_t                  *buffer,
+                  hb_font_t                    *font HB_UNUSED)
+{
+  HB_BUFFER_ALLOCATE_VAR (buffer, indic_category);
+  HB_BUFFER_ALLOCATE_VAR (buffer, indic_position);
+
+  /* We cannot setup masks here.  We save information about characters
+   * and setup masks later on in a pause-callback. */
+
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    set_indic_properties (buffer->info[i]);
+}
+
+static int
+compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+  int a = pa->indic_position();
+  int b = pb->indic_position();
+
+  return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+
+static void
 update_consonant_positions (const hb_ot_map_t *map,
                            hb_buffer_t       *buffer,
                            hb_font_t         *font)
@@ -254,7 +282,7 @@ update_consonant_positions (const hb_ot_map_t *map,
     case HB_SCRIPT_MALAYALAM:  virama = 0x0D4D; break;
     case HB_SCRIPT_SINHALA:    virama = 0x0DCA; break;
     case HB_SCRIPT_KHMER:      virama = 0x17D2; break;
-    default:                   virama = 0;       break;
+    default:                   virama = 0;      break;
   }
 
   indic_shape_plan_t indic_plan (map);
@@ -263,43 +291,18 @@ update_consonant_positions (const hb_ot_map_t *map,
   hb_codepoint_t glyphs[2];
   if (virama && font->get_glyph (virama, 0, &glyphs[1 - consonant_pos]))
   {
+    /* Technically speaking, the spec says we should apply 'locl' to virama 
too.
+     * Maybe one day... */
     hb_face_t *face = font->face;
     unsigned int count = buffer->len;
     for (unsigned int i = 0; i < count; i++)
       if (buffer->info[i].indic_position() == POS_BASE_C) {
-       font->get_glyph (buffer->info[i].codepoint, 0, &glyphs[consonant_pos]);
+       glyphs[consonant_pos] = buffer->info[i].codepoint;
        buffer->info[i].indic_position() = consonant_position_from_font 
(&indic_plan, glyphs, 2, face);
       }
   }
 }
 
-static void
-setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
-                  const hb_ot_map_t            *map,
-                  hb_buffer_t                  *buffer,
-                  hb_font_t                    *font)
-{
-  HB_BUFFER_ALLOCATE_VAR (buffer, indic_category);
-  HB_BUFFER_ALLOCATE_VAR (buffer, indic_position);
-
-  /* We cannot setup masks here.  We save information about characters
-   * and setup masks later on in a pause-callback. */
-
-  unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-    set_indic_properties (buffer->info[i]);
-
-  update_consonant_positions (map, buffer, font);
-}
-
-static int
-compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
-{
-  int a = pa->indic_position();
-  int b = pb->indic_position();
-
-  return a < b ? -1 : a == b ? 0 : +1;
-}
 
 /* Rules from:
  * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
@@ -696,10 +699,12 @@ initial_reordering_non_indic (const hb_ot_map_t *map 
HB_UNUSED,
 
 static void
 initial_reordering (const hb_ot_map_t *map,
-                   hb_font_t *font HB_UNUSED,
+                   hb_font_t *font,
                    hb_buffer_t *buffer,
                    void *user_data HB_UNUSED)
 {
+  update_consonant_positions (map, buffer, font);
+
   hb_mask_t basic_mask_array[ARRAY_LENGTH (indic_basic_features)] = {0};
   unsigned int num_masks = ARRAY_LENGTH (indic_basic_features);
   for (unsigned int i = 0; i < num_masks; i++)
commit afbcc24be01a64bdb5c05c63880269145fa1d3c8
Author: Behdad Esfahbod <beh...@behdad.org>
Date:   Thu Aug 2 08:36:40 2012 -0400

    [GSUB] Wire the font, not just the face, down to substitute()
    
    We need the font for glyph lookup during GSUB pauses in Indic shaper.
    Could perhaps be avoided, but at this point, we don't mean to support
    separate substitute()/position() entry points (anymore), so there is
    no point in not providing the font to GSUB.

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 77ff3d9..b69af4c 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1287,8 +1287,8 @@ struct GSUB : GSUBGPOS
   inline bool substitute_lookup (hb_apply_context_t *c, unsigned int 
lookup_index) const
   { return get_lookup (lookup_index).apply_string (c); }
 
-  static inline void substitute_start (hb_face_t *face, hb_buffer_t *buffer);
-  static inline void substitute_finish (hb_face_t *face, hb_buffer_t *buffer);
+  static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer);
+  static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer);
 
   inline void closure_lookup (hb_closure_context_t *c,
                              unsigned int          lookup_index) const
@@ -1306,16 +1306,13 @@ struct GSUB : GSUBGPOS
 
 
 void
-GSUB::substitute_start (hb_face_t *face, hb_buffer_t *buffer)
+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);
 
-  /* TODO This pattern is duplicated from gsubgpos-private.h.  Do something 
about it. */
-  const GDEF &gdef = hb_ot_layout_from_face (face) &&
-                    !HB_SHAPER_DATA_IS_INVALID (hb_ot_layout_from_face (face)) 
?
-                    *hb_ot_layout_from_face (face)->gdef : Null(GDEF);
+  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;
@@ -1324,7 +1321,7 @@ GSUB::substitute_start (hb_face_t *face, hb_buffer_t 
*buffer)
 }
 
 void
-GSUB::substitute_finish (hb_face_t *face HB_UNUSED, hb_buffer_t *buffer 
HB_UNUSED)
+GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer 
HB_UNUSED)
 {
 }
 
diff --git a/src/hb-ot-layout-gsubgpos-private.hh 
b/src/hb-ot-layout-gsubgpos-private.hh
index f2863b3..d91686d 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -118,18 +118,15 @@ struct hb_apply_context_t
 
 
   hb_apply_context_t (hb_font_t *font_,
-                     hb_face_t *face_,
                      hb_buffer_t *buffer_,
                      hb_mask_t lookup_mask_,
                      const hb_set_digest_t *digest_) :
-                       font (font_), face (face_), buffer (buffer_),
+                       font (font_), face (font->face), buffer (buffer_),
                        direction (buffer_->props.direction),
                        lookup_mask (lookup_mask_),
                        nesting_level_left (MAX_NESTING_LEVEL),
                        lookup_props (0), property (0), debug_depth (0),
-                       gdef (hb_ot_layout_from_face (face_) &&
-                             !HB_SHAPER_DATA_IS_INVALID 
(hb_ot_layout_from_face (face_)) ?
-                             *hb_ot_layout_from_face (face_)->gdef : 
Null(GDEF)),
+                       gdef (*hb_ot_layout_from_face (face)->gdef),
                        has_glyph_classes (gdef.has_glyph_classes ()),
                        digest (*digest_) {}
 
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index ac0d9a7..510aec9 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -146,18 +146,18 @@ hb_ot_layout_would_substitute_lookup_fast (hb_face_t      
      *face,
 
 /* Should be called before all the substitute_lookup's are done. */
 HB_INTERNAL void
-hb_ot_layout_substitute_start (hb_face_t    *face,
+hb_ot_layout_substitute_start (hb_font_t    *font,
                               hb_buffer_t  *buffer);
 
 HB_INTERNAL hb_bool_t
-hb_ot_layout_substitute_lookup (hb_face_t    *face,
+hb_ot_layout_substitute_lookup (hb_font_t    *font,
                                hb_buffer_t  *buffer,
                                unsigned int  lookup_index,
                                hb_mask_t     mask);
 
 /* Should be called after all the substitute_lookup's are done */
 HB_INTERNAL void
-hb_ot_layout_substitute_finish (hb_face_t    *face,
+hb_ot_layout_substitute_finish (hb_font_t    *font,
                                hb_buffer_t  *buffer);
 
 
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 31b3abb..0280f0b 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -422,26 +422,26 @@ hb_ot_layout_would_substitute_lookup_fast (hb_face_t      
      *face,
 }
 
 void
-hb_ot_layout_substitute_start (hb_face_t *face, hb_buffer_t *buffer)
+hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer)
 {
-  GSUB::substitute_start (face, buffer);
+  GSUB::substitute_start (font, buffer);
 }
 
 hb_bool_t
-hb_ot_layout_substitute_lookup (hb_face_t    *face,
+hb_ot_layout_substitute_lookup (hb_font_t    *font,
                                hb_buffer_t  *buffer,
                                unsigned int  lookup_index,
                                hb_mask_t     mask)
 {
-  if (unlikely (lookup_index >= hb_ot_layout_from_face 
(face)->gsub_lookup_count)) return false;
-  hb_apply_context_t c (NULL, face, buffer, mask, &hb_ot_layout_from_face 
(face)->gsub_digests[lookup_index]);
-  return hb_ot_layout_from_face (face)->gsub->substitute_lookup (&c, 
lookup_index);
+  if (unlikely (lookup_index >= hb_ot_layout_from_face 
(font->face)->gsub_lookup_count)) return false;
+  hb_apply_context_t c (font, buffer, mask, &hb_ot_layout_from_face 
(font->face)->gsub_digests[lookup_index]);
+  return hb_ot_layout_from_face (font->face)->gsub->substitute_lookup (&c, 
lookup_index);
 }
 
 void
-hb_ot_layout_substitute_finish (hb_face_t *face, hb_buffer_t *buffer)
+hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer)
 {
-  GSUB::substitute_finish (face, buffer);
+  GSUB::substitute_finish (font, buffer);
 }
 
 void
@@ -476,7 +476,7 @@ hb_ot_layout_position_lookup (hb_font_t    *font,
                              hb_mask_t     mask)
 {
   if (unlikely (lookup_index >= hb_ot_layout_from_face 
(font->face)->gpos_lookup_count)) return false;
-  hb_apply_context_t c (font, font->face, buffer, mask, 
&hb_ot_layout_from_face (font->face)->gpos_digests[lookup_index]);
+  hb_apply_context_t c (font, buffer, mask, &hb_ot_layout_from_face 
(font->face)->gpos_digests[lookup_index]);
   return hb_ot_layout_from_face (font->face)->gpos->position_lookup (&c, 
lookup_index);
 }
 
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 5e3c967..648e5df 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -62,7 +62,7 @@ struct hb_ot_map_t
     { return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
   };
 
-  typedef void (*pause_func_t) (const hb_ot_map_t *map, void *face_or_font, 
hb_buffer_t *buffer, void *user_data);
+  typedef void (*pause_func_t) (const hb_ot_map_t *map, hb_font_t *font, 
hb_buffer_t *buffer, void *user_data);
   typedef struct {
     pause_func_t func;
     void *user_data;
@@ -76,9 +76,6 @@ struct hb_ot_map_t
 
   hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }
 
-  typedef void (*gsub_pause_func_t) (const hb_ot_map_t *map, hb_face_t *face, 
hb_buffer_t *buffer, void *user_data);
-  typedef void (*gpos_pause_func_t) (const hb_ot_map_t *map, hb_font_t *font, 
hb_buffer_t *buffer, void *user_data);
-
   inline hb_mask_t get_global_mask (void) const { return global_mask; }
 
   inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = NULL) 
const {
@@ -120,7 +117,7 @@ struct hb_ot_map_t
   { return chosen_script[table_index]; }
 
   HB_INTERNAL void substitute_closure (hb_face_t *face, hb_set_t *glyphs) 
const;
-  HB_INTERNAL void substitute (hb_face_t *face, hb_buffer_t *buffer) const;
+  HB_INTERNAL void substitute (hb_font_t *font, hb_buffer_t *buffer) const;
   HB_INTERNAL void position (hb_font_t *font, hb_buffer_t *buffer) const;
 
   inline void finish (void) {
@@ -159,10 +156,10 @@ struct hb_ot_map_builder_t
   inline void add_bool_feature (hb_tag_t tag, bool global = true)
   { add_feature (tag, 1, global); }
 
-  inline void add_gsub_pause (hb_ot_map_t::gsub_pause_func_t pause_func, void 
*user_data)
-  { add_pause (0, (hb_ot_map_t::pause_func_t) pause_func, user_data); }
-  inline void add_gpos_pause (hb_ot_map_t::gpos_pause_func_t pause_func, void 
*user_data)
-  { add_pause (1, (hb_ot_map_t::pause_func_t) pause_func, user_data); }
+  inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func, void 
*user_data)
+  { add_pause (0, pause_func, user_data); }
+  inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func, void 
*user_data)
+  { add_pause (1, pause_func, user_data); }
 
   HB_INTERNAL void compile (hb_face_t *face,
                            const hb_segment_properties_t *props,
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 1bab186..03c9ba1 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -77,7 +77,7 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned 
int value, bool gl
 
 /* Keep the next two functions in sync. */
 
-void hb_ot_map_t::substitute (hb_face_t *face, hb_buffer_t *buffer) const
+void hb_ot_map_t::substitute (hb_font_t *font, hb_buffer_t *buffer) const
 {
   const unsigned int table_index = 0;
   unsigned int i = 0;
@@ -85,16 +85,16 @@ void hb_ot_map_t::substitute (hb_face_t *face, hb_buffer_t 
*buffer) const
   for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; 
pause_index++) {
     const pause_map_t *pause = &pauses[table_index][pause_index];
     for (; i < pause->num_lookups; i++)
-      hb_ot_layout_substitute_lookup (face, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
+      hb_ot_layout_substitute_lookup (font, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
 
     buffer->clear_output ();
 
     if (pause->callback.func)
-      pause->callback.func (this, face, buffer, pause->callback.user_data);
+      pause->callback.func (this, font, buffer, pause->callback.user_data);
   }
 
   for (; i < lookups[table_index].len; i++)
-    hb_ot_layout_substitute_lookup (face, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
+    hb_ot_layout_substitute_lookup (font, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
 }
 
 void hb_ot_map_t::position (hb_font_t *font, hb_buffer_t *buffer) const
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 639be08..cbc1231 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -193,12 +193,12 @@ indic_other_features[] =
 
 static void
 initial_reordering (const hb_ot_map_t *map,
-                   hb_face_t *face,
+                   hb_font_t *font,
                    hb_buffer_t *buffer,
                    void *user_data HB_UNUSED);
 static void
 final_reordering (const hb_ot_map_t *map,
-                 hb_face_t *face,
+                 hb_font_t *font,
                  hb_buffer_t *buffer,
                  void *user_data HB_UNUSED);
 
@@ -696,7 +696,7 @@ initial_reordering_non_indic (const hb_ot_map_t *map 
HB_UNUSED,
 
 static void
 initial_reordering (const hb_ot_map_t *map,
-                   hb_face_t *face HB_UNUSED,
+                   hb_font_t *font HB_UNUSED,
                    hb_buffer_t *buffer,
                    void *user_data HB_UNUSED)
 {
@@ -1059,7 +1059,7 @@ final_reordering_syllable (hb_buffer_t *buffer,
 
 static void
 final_reordering (const hb_ot_map_t *map,
-                 hb_face_t *face HB_UNUSED,
+                 hb_font_t *font HB_UNUSED,
                  hb_buffer_t *buffer,
                  void *user_data HB_UNUSED)
 {
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 755999b..66664c5 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -367,15 +367,15 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
 static void
 hb_ot_substitute_complex (hb_ot_shape_context_t *c)
 {
-  hb_ot_layout_substitute_start (c->face, c->buffer);
+  hb_ot_layout_substitute_start (c->font, c->buffer);
 
   if (!hb_ot_layout_has_glyph_classes (c->face))
     hb_synthesize_glyph_classes (c);
 
   if (hb_ot_layout_has_substitution (c->face))
-    c->plan->map.substitute (c->face, c->buffer);
+    c->plan->map.substitute (c->font, c->buffer);
 
-  hb_ot_layout_substitute_finish (c->face, c->buffer);
+  hb_ot_layout_substitute_finish (c->font, c->buffer);
 
   return;
 }
commit b0e6a26a10ccca70ebc88a9e158a89ccfab0add5
Author: Behdad Esfahbod <beh...@behdad.org>
Date:   Thu Aug 2 08:11:14 2012 -0400

    [OT] Hide some API
    
    It was impossible to meaningfully use them from the outside these days.

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index ea2e64d..ac0d9a7 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -143,17 +143,41 @@ hb_ot_layout_would_substitute_lookup_fast (hb_face_t      
      *face,
                                           unsigned int          glyphs_length,
                                           unsigned int          lookup_index);
 
+
+/* Should be called before all the substitute_lookup's are done. */
+HB_INTERNAL void
+hb_ot_layout_substitute_start (hb_face_t    *face,
+                              hb_buffer_t  *buffer);
+
 HB_INTERNAL hb_bool_t
-hb_ot_layout_substitute_lookup_fast (hb_face_t    *face,
-                                    hb_buffer_t  *buffer,
-                                    unsigned int  lookup_index,
-                                    hb_mask_t     mask);
+hb_ot_layout_substitute_lookup (hb_face_t    *face,
+                               hb_buffer_t  *buffer,
+                               unsigned int  lookup_index,
+                               hb_mask_t     mask);
+
+/* Should be called after all the substitute_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_substitute_finish (hb_face_t    *face,
+                               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);
 
 HB_INTERNAL hb_bool_t
-hb_ot_layout_position_lookup_fast (hb_font_t    *font,
-                                  hb_buffer_t  *buffer,
-                                  unsigned int  lookup_index,
-                                  hb_mask_t     mask);
+hb_ot_layout_position_lookup (hb_font_t    *font,
+                             hb_buffer_t  *buffer,
+                             unsigned int  lookup_index,
+                             hb_mask_t     mask);
+
+/* 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_bool_t     zero_width_attached_marks);
+
 
 
 /*
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 63f3095..31b3abb 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -433,16 +433,6 @@ hb_ot_layout_substitute_lookup (hb_face_t    *face,
                                unsigned int  lookup_index,
                                hb_mask_t     mask)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false;
-  return hb_ot_layout_substitute_lookup_fast (face, buffer, lookup_index, 
mask);
-}
-
-hb_bool_t
-hb_ot_layout_substitute_lookup_fast (hb_face_t    *face,
-                                    hb_buffer_t  *buffer,
-                                    unsigned int  lookup_index,
-                                    hb_mask_t     mask)
-{
   if (unlikely (lookup_index >= hb_ot_layout_from_face 
(face)->gsub_lookup_count)) return false;
   hb_apply_context_t c (NULL, face, buffer, mask, &hb_ot_layout_from_face 
(face)->gsub_digests[lookup_index]);
   return hb_ot_layout_from_face (face)->gsub->substitute_lookup (&c, 
lookup_index);
@@ -485,16 +475,6 @@ hb_ot_layout_position_lookup (hb_font_t    *font,
                              unsigned int  lookup_index,
                              hb_mask_t     mask)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (font->face))) return false;
-  return hb_ot_layout_position_lookup_fast (font, buffer, lookup_index, mask);
-}
-
-hb_bool_t
-hb_ot_layout_position_lookup_fast (hb_font_t    *font,
-                                  hb_buffer_t  *buffer,
-                                  unsigned int  lookup_index,
-                                  hb_mask_t     mask)
-{
   if (unlikely (lookup_index >= hb_ot_layout_from_face 
(font->face)->gpos_lookup_count)) return false;
   hb_apply_context_t c (font, font->face, buffer, mask, 
&hb_ot_layout_from_face (font->face)->gpos_digests[lookup_index]);
   return hb_ot_layout_from_face (font->face)->gpos->position_lookup (&c, 
lookup_index);
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index d663ab0..e14cde8 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -176,23 +176,6 @@ hb_ot_layout_would_substitute_lookup (hb_face_t            
*face,
                                      unsigned int          glyphs_length,
                                      unsigned int          lookup_index);
 
-/* Should be called before all the substitute_lookup's are done. */
-void
-hb_ot_layout_substitute_start (hb_face_t    *face,
-                              hb_buffer_t  *buffer);
-
-hb_bool_t
-hb_ot_layout_substitute_lookup (hb_face_t    *face,
-                               hb_buffer_t  *buffer,
-                               unsigned int  lookup_index,
-                               hb_mask_t     mask);
-
-/* Should be called after all the substitute_lookup's are done */
-void
-hb_ot_layout_substitute_finish (hb_face_t    *face,
-                               hb_buffer_t  *buffer);
-
-
 void
 hb_ot_layout_substitute_closure_lookup (hb_face_t    *face,
                                        hb_set_t     *glyphs,
@@ -205,23 +188,6 @@ hb_ot_layout_substitute_closure_lookup (hb_face_t    *face,
 hb_bool_t
 hb_ot_layout_has_positioning (hb_face_t *face);
 
-/* Should be called before all the position_lookup's are done.  Resets 
positions to zero. */
-void
-hb_ot_layout_position_start (hb_font_t    *font,
-                            hb_buffer_t  *buffer);
-
-hb_bool_t
-hb_ot_layout_position_lookup (hb_font_t    *font,
-                             hb_buffer_t  *buffer,
-                             unsigned int  lookup_index,
-                             hb_mask_t     mask);
-
-/* Should be called after all the position_lookup's are done */
-void
-hb_ot_layout_position_finish (hb_font_t    *font,
-                             hb_buffer_t  *buffer,
-                             hb_bool_t     zero_width_attached_marks);
-
 
 HB_END_DECLS
 
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index ae0cb61..1bab186 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -85,7 +85,7 @@ void hb_ot_map_t::substitute (hb_face_t *face, hb_buffer_t 
*buffer) const
   for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; 
pause_index++) {
     const pause_map_t *pause = &pauses[table_index][pause_index];
     for (; i < pause->num_lookups; i++)
-      hb_ot_layout_substitute_lookup_fast (face, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
+      hb_ot_layout_substitute_lookup (face, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
 
     buffer->clear_output ();
 
@@ -94,7 +94,7 @@ void hb_ot_map_t::substitute (hb_face_t *face, hb_buffer_t 
*buffer) const
   }
 
   for (; i < lookups[table_index].len; i++)
-    hb_ot_layout_substitute_lookup_fast (face, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
+    hb_ot_layout_substitute_lookup (face, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
 }
 
 void hb_ot_map_t::position (hb_font_t *font, hb_buffer_t *buffer) const
@@ -105,14 +105,14 @@ void hb_ot_map_t::position (hb_font_t *font, hb_buffer_t 
*buffer) const
   for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; 
pause_index++) {
     const pause_map_t *pause = &pauses[table_index][pause_index];
     for (; i < pause->num_lookups; i++)
-      hb_ot_layout_position_lookup_fast (font, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
+      hb_ot_layout_position_lookup (font, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
 
     if (pause->callback.func)
       pause->callback.func (this, font, buffer, pause->callback.user_data);
   }
 
   for (; i < lookups[table_index].len; i++)
-    hb_ot_layout_position_lookup_fast (font, buffer, 
lookups[table_index][i].index, lookups[table_index][i].mask);
+    hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, 
lookups[table_index][i].mask);
 }
 
 void hb_ot_map_t::substitute_closure (hb_face_t *face,
commit 305246744ed178f116e01498b7f9d1af6950ca30
Author: Behdad Esfahbod <beh...@behdad.org>
Date:   Thu Aug 2 08:08:04 2012 -0400

    Minor

diff --git a/src/hb-ot-layout-gsubgpos-private.hh 
b/src/hb-ot-layout-gsubgpos-private.hh
index 15a0b0c..f2863b3 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -77,8 +77,8 @@ struct hb_would_apply_context_t
   hb_face_t *face;
   hb_codepoint_t first;
   hb_codepoint_t second;
-  const hb_set_digest_t digest;
   unsigned int len;
+  const hb_set_digest_t digest;
   unsigned int debug_depth;
 
   hb_would_apply_context_t (hb_face_t *face_,
commit 8ef3d53255ae9fbb0e46c22909e50009d1e7eeb0
Author: Behdad Esfahbod <beh...@behdad.org>
Date:   Thu Aug 2 07:53:18 2012 -0400

    [Indic] More refactoring of consonant position peeking in the font
    
    To be moved to initial_reordering next...

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index a56ea70..639be08 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -123,20 +123,10 @@ struct indic_shape_plan_t
 };
 
 static indic_position_t
-consonant_position_from_font (hb_codepoint_t  u,
-                             const indic_shape_plan_t *indic_plan,
-                             hb_font_t      *font)
+consonant_position_from_font (const indic_shape_plan_t *indic_plan,
+                             hb_codepoint_t *glyphs, unsigned int glyphs_len,
+                             hb_face_t      *face)
 {
-  hb_codepoint_t virama = (u & ~0x007F) | 0x004D;
-  if ((u & ~0x007F) == 0x0D80) virama = 0x0DCA; /* Sinahla */
-  if ((u & ~0x007F) == 0x1780) virama = 0x17D2; /* Khmaer */
-  hb_codepoint_t glyphs[2];
-
-  unsigned int virama_pos = indic_plan->is_old_spec ? 1 : 0;
-  font->get_glyph (virama, 0, &glyphs[virama_pos]);
-  font->get_glyph (u,      0, &glyphs[1-virama_pos]);
-
-  hb_face_t *face = font->face;
   if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) 
return POS_BELOW_C;
   if (indic_plan->blwf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) 
return POS_BELOW_C;
   if (indic_plan->pstf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) 
return POS_POST_C;
@@ -247,6 +237,43 @@ override_features_indic (const hb_ot_complex_shaper_t  
*shaper,
 
 
 static void
+update_consonant_positions (const hb_ot_map_t *map,
+                           hb_buffer_t       *buffer,
+                           hb_font_t         *font)
+{
+  hb_codepoint_t virama;
+  switch ((int) buffer->props.script) {
+    case HB_SCRIPT_DEVANAGARI: virama = 0x094D; break;
+    case HB_SCRIPT_BENGALI:    virama = 0x09CD; break;
+    case HB_SCRIPT_GURMUKHI:   virama = 0x0A4D; break;
+    case HB_SCRIPT_GUJARATI:   virama = 0x0ACD; break;
+    case HB_SCRIPT_ORIYA:      virama = 0x0B4D; break;
+    case HB_SCRIPT_TAMIL:      virama = 0x0BCD; break;
+    case HB_SCRIPT_TELUGU:     virama = 0x0C4D; break;
+    case HB_SCRIPT_KANNADA:    virama = 0x0CCD; break;
+    case HB_SCRIPT_MALAYALAM:  virama = 0x0D4D; break;
+    case HB_SCRIPT_SINHALA:    virama = 0x0DCA; break;
+    case HB_SCRIPT_KHMER:      virama = 0x17D2; break;
+    default:                   virama = 0;       break;
+  }
+
+  indic_shape_plan_t indic_plan (map);
+
+  unsigned int consonant_pos = indic_plan.is_old_spec ? 0 : 1;
+  hb_codepoint_t glyphs[2];
+  if (virama && font->get_glyph (virama, 0, &glyphs[1 - consonant_pos]))
+  {
+    hb_face_t *face = font->face;
+    unsigned int count = buffer->len;
+    for (unsigned int i = 0; i < count; i++)
+      if (buffer->info[i].indic_position() == POS_BASE_C) {
+       font->get_glyph (buffer->info[i].codepoint, 0, &glyphs[consonant_pos]);
+       buffer->info[i].indic_position() = consonant_position_from_font 
(&indic_plan, glyphs, 2, face);
+      }
+  }
+}
+
+static void
 setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
                   const hb_ot_map_t            *map,
                   hb_buffer_t                  *buffer,
@@ -258,15 +285,11 @@ setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
   /* We cannot setup masks here.  We save information about characters
    * and setup masks later on in a pause-callback. */
 
-  indic_shape_plan_t indic_plan (map);
-
   unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++)
     set_indic_properties (buffer->info[i]);
 
-  for (unsigned int i = 0; i < count; i++)
-    if (buffer->info[i].indic_position() == POS_BASE_C)
-      buffer->info[i].indic_position() = consonant_position_from_font 
(buffer->info[i].codepoint, &indic_plan, font);
+  update_consonant_positions (map, buffer, font);
 }
 
 static int
commit 3eb6f81fd3f1e56679eec10d08f5e2303121753f
Author: Behdad Esfahbod <beh...@behdad.org>
Date:   Thu Aug 2 07:37:46 2012 -0400

    [Indic] Refactor
    
    Move all the logic that needs to eventually move into the indic table
    into hb-ot-shape-complex-indic-private.hh.

diff --git a/src/hb-ot-shape-complex-indic-private.hh 
b/src/hb-ot-shape-complex-indic-private.hh
index ce9a184..d4cfe0d 100644
--- a/src/hb-ot-shape-complex-indic-private.hh
+++ b/src/hb-ot-shape-complex-indic-private.hh
@@ -31,6 +31,7 @@
 
 
 #include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-private.hh" /* XXX Remove */
 
 
 /* buffer var allocations */
@@ -152,6 +153,79 @@ enum indic_matra_category_t {
 #include "hb-ot-shape-complex-indic-table.hh"
 
 
+#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7F) == (Base))
+
+#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900))
+#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980))
+#define IS_GURM(u) (IN_HALF_BLOCK (u, 0x0A00))
+#define IS_GUJA(u) (IN_HALF_BLOCK (u, 0x0A80))
+#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00))
+#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80))
+#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00))
+#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80))
+#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00))
+#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80))
+#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780))
+
+
+#define MATRA_POS_LEFT(u)      POS_PRE_M
+#define MATRA_POS_RIGHT(u)     ( \
+                                 IS_DEVA(u) ? POS_AFTER_SUB  : \
+                                 IS_BENG(u) ? POS_AFTER_POST : \
+                                 IS_GURM(u) ? POS_AFTER_POST : \
+                                 IS_GUJA(u) ? POS_AFTER_POST : \
+                                 IS_ORYA(u) ? POS_AFTER_POST : \
+                                 IS_TAML(u) ? POS_AFTER_POST : \
+                                 IS_TELU(u) ? (u <= 0x0C42 ? POS_BEFORE_SUB : 
POS_AFTER_SUB) : \
+                                 IS_KNDA(u) ? (u < 0x0CC3 || u > 0xCD6 ? 
POS_BEFORE_SUB : POS_AFTER_SUB) : \
+                                 IS_MLYM(u) ? POS_AFTER_POST : \
+                                 IS_SINH(u) ? POS_AFTER_SUB  : \
+                                 IS_KHMR(u) ? POS_AFTER_POST : \
+                                 /*default*/  POS_AFTER_SUB    \
+                               )
+#define MATRA_POS_TOP(u)       ( /* BENG and MLYM don't have top matras. */ \
+                                 IS_DEVA(u) ? POS_AFTER_SUB  : \
+                                 IS_GURM(u) ? POS_AFTER_POST : /* Deviate from 
spec */ \
+                                 IS_GUJA(u) ? POS_AFTER_SUB  : \
+                                 IS_ORYA(u) ? POS_AFTER_MAIN : \
+                                 IS_TAML(u) ? POS_AFTER_SUB  : \
+                                 IS_TELU(u) ? POS_BEFORE_SUB : \
+                                 IS_KNDA(u) ? POS_BEFORE_SUB : \
+                                 IS_SINH(u) ? POS_AFTER_SUB  : \
+                                 IS_KHMR(u) ? POS_AFTER_POST : \
+                                 /*default*/  POS_AFTER_SUB    \
+                               )
+#define MATRA_POS_BOTTOM(u)    ( \
+                                 IS_DEVA(u) ? POS_AFTER_SUB  : \
+                                 IS_BENG(u) ? POS_AFTER_SUB  : \
+                                 IS_GURM(u) ? POS_AFTER_POST : \
+                                 IS_GUJA(u) ? POS_AFTER_POST : \
+                                 IS_ORYA(u) ? POS_AFTER_SUB  : \
+                                 IS_TAML(u) ? POS_AFTER_POST : \
+                                 IS_TELU(u) ? POS_BEFORE_SUB : \
+                                 IS_KNDA(u) ? POS_BEFORE_SUB : \
+                                 IS_MLYM(u) ? POS_AFTER_POST : \
+                                 IS_SINH(u) ? POS_AFTER_SUB  : \
+                                 IS_KHMR(u) ? POS_AFTER_POST : \
+                                 /*default*/  POS_AFTER_SUB    \
+                               )
+
+
+static inline indic_position_t
+matra_position (hb_codepoint_t u, indic_position_t side)
+{
+  switch ((int) side)
+  {
+    case POS_PRE_C:    return MATRA_POS_LEFT (u);
+    case POS_POST_C:   return MATRA_POS_RIGHT (u);
+    case POS_ABOVE_C:  return MATRA_POS_TOP (u);
+    case POS_BELOW_C:  return MATRA_POS_BOTTOM (u);
+  };
+  abort ();
+}
+
+
+
 /* XXX
  * This is a hack for now.  We should move this data into the main Indic table.
  * Or completely remove it and just check in the tables.
@@ -173,5 +247,141 @@ static const hb_codepoint_t ra_chars[] = {
   0x179A, /* Khmer */          /* No Reph, Visual Repha */
 };
 
+static inline indic_position_t
+consonant_position (hb_codepoint_t  u)
+{
+  if ((u & ~0x007F) == 0x1780)
+    return POS_BELOW_C; /* In Khmer coeng model, post and below forms should 
not be reordered. */
+  return POS_BASE_C; /* Will recategorize later based on font lookups. */
+}
+
+static inline bool
+is_ra (hb_codepoint_t u)
+{
+  for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++)
+    if (u == ra_chars[i])
+      return true;
+  return false;
+}
+
+
+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;
+  return !!(FLAG (info.indic_category()) & flags);
+}
+
+#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
+static inline bool
+is_joiner (const hb_glyph_info_t &info)
+{
+  return is_one_of (info, JOINER_FLAGS);
+}
+
+/* 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_Ra) | FLAG (OT_V) | FLAG 
(OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
+static inline bool
+is_consonant (const hb_glyph_info_t &info)
+{
+  return is_one_of (info, CONSONANT_FLAGS);
+}
+
+#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
+static inline bool
+is_halant_or_coeng (const hb_glyph_info_t &info)
+{
+  return is_one_of (info, HALANT_OR_COENG_FLAGS);
+}
+
+static inline void
+set_indic_properties (hb_glyph_info_t   &info)
+{
+  hb_codepoint_t u = info.codepoint;
+  unsigned int type = get_indic_categories (u);
+  indic_category_t cat = (indic_category_t) (type & 0x0F);
+  indic_position_t pos = (indic_position_t) (type >> 4);
+
+
+  /*
+   * Re-assign category
+   */
+
+
+  /* The spec says U+0952 is OT_A.  However, testing shows that Uniscribe
+   * treats U+0951..U+0952 all as OT_VD.
+   * TESTS:
+   * U+092E,U+0947,U+0952
+   * U+092E,U+0952,U+0947
+   * U+092E,U+0947,U+0951
+   * U+092E,U+0951,U+0947
+   * */
+  if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0951, 0x0954)))
+    cat = OT_VD;
+
+  if (unlikely (u == 0x17D1))
+    cat = OT_X;
+  if (cat == OT_X &&
+      unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CB, 0x17D3))) /* Khmer 
Various signs */
+  {
+    /* These are like Top Matras. */
+    cat = OT_M;
+    pos = POS_ABOVE_C;
+  }
+  if (u == 0x17C6) /* Khmer Bindu doesn't like to be repositioned. */
+    cat = OT_N;
+
+  if (unlikely (u == 0x17D2)) cat = OT_Coeng; /* Khmer coeng */
+  else if (unlikely (u == 0x200C)) cat = OT_ZWNJ;
+  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.  More like 
consonant medial. like 0A75. */
+
+  if (cat == OT_Repha) {
+    /* There are two kinds of characters marked as Repha:
+     * - The ones that are GenCat=Mn are already positioned visually, ie. 
after base. (eg. Khmer)
+     * - The ones that are GenCat=Lo is encoded logically, ie. beginning of 
syllable. (eg. Malayalam)
+     *
+     * We recategorize the first kind to look like a Nukta and attached to the 
base directly.
+     */
+    if (_hb_glyph_info_get_general_category (&info) == 
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+      cat = OT_N;
+  }
+
+
+
+  /*
+   * Re-assign position.
+   */
+
+  if ((FLAG (cat) & CONSONANT_FLAGS))
+  {
+    pos = consonant_position (u);
+    if (is_ra (u))
+      cat = OT_Ra;
+  }
+  else if (cat == OT_M)
+  {
+    pos = matra_position (u, pos);
+  }
+  else if (cat == OT_SM || cat == OT_VD)
+  {
+    pos = POS_SMVD;
+  }
+
+  if (unlikely (u == 0x0B01)) pos = POS_BEFORE_SUB; /* Oriya Bindu is 
BeforeSub in the spec. */
+
+
+
+  info.indic_category() = cat;
+  info.indic_position() = pos;
+}
+
+
 
 #endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 883e32f..a56ea70 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -29,21 +29,6 @@
 #include "hb-ot-layout-private.hh"
 
 
-#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7F) == (Base))
-
-#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900))
-#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980))
-#define IS_GURM(u) (IN_HALF_BLOCK (u, 0x0A00))
-#define IS_GUJA(u) (IN_HALF_BLOCK (u, 0x0A80))
-#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00))
-#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80))
-#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00))
-#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80))
-#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00))
-#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80))
-#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780))
-
-
 #define OLD_INDIC_TAG(script) (((hb_tag_t) script) | 0x20000000)
 #define IS_OLD_INDIC_TAG(tag) ( \
                                (tag) == OLD_INDIC_TAG (HB_SCRIPT_BENGALI)      
|| \
@@ -97,15 +82,6 @@ indic_options (void)
 }
 
 
-static int
-compare_codepoint (const void *pa, const void *pb)
-{
-  hb_codepoint_t a = * (hb_codepoint_t *) pa;
-  hb_codepoint_t b = * (hb_codepoint_t *) pb;
-
-  return a < b ? -1 : a == b ? 0 : +1;
-}
-
 struct indic_shape_plan_t
 {
   struct would_apply_feature_t
@@ -147,13 +123,10 @@ struct indic_shape_plan_t
 };
 
 static indic_position_t
-consonant_position (hb_codepoint_t  u,
-                   const indic_shape_plan_t *indic_plan,
-                   hb_font_t      *font)
+consonant_position_from_font (hb_codepoint_t  u,
+                             const indic_shape_plan_t *indic_plan,
+                             hb_font_t      *font)
 {
-  if ((u & ~0x007F) == 0x1780)
-    return POS_BELOW_C; /* In Khmer coeng model, post and below forms should 
not be reordered. */
-
   hb_codepoint_t virama = (u & ~0x007F) | 0x004D;
   if ((u & ~0x007F) == 0x0D80) virama = 0x0DCA; /* Sinahla */
   if ((u & ~0x007F) == 0x1780) virama = 0x17D2; /* Khmaer */
@@ -170,194 +143,6 @@ consonant_position (hb_codepoint_t  u,
   return POS_BASE_C;
 }
 
-#define MATRA_POS_LEFT(u)      POS_PRE_M
-#define MATRA_POS_RIGHT(u)     ( \
-                                 IS_DEVA(u) ? POS_AFTER_SUB  : \
-                                 IS_BENG(u) ? POS_AFTER_POST : \
-                                 IS_GURM(u) ? POS_AFTER_POST : \
-                                 IS_GUJA(u) ? POS_AFTER_POST : \
-                                 IS_ORYA(u) ? POS_AFTER_POST : \
-                                 IS_TAML(u) ? POS_AFTER_POST : \
-                                 IS_TELU(u) ? (u <= 0x0C42 ? POS_BEFORE_SUB : 
POS_AFTER_SUB) : \
-                                 IS_KNDA(u) ? (u < 0x0CC3 || u > 0xCD6 ? 
POS_BEFORE_SUB : POS_AFTER_SUB) : \
-                                 IS_MLYM(u) ? POS_AFTER_POST : \
-                                 IS_SINH(u) ? POS_AFTER_SUB  : \
-                                 IS_KHMR(u) ? POS_AFTER_POST : \
-                                 /*default*/  POS_AFTER_SUB    \
-                               )
-#define MATRA_POS_TOP(u)       ( /* BENG and MLYM don't have top matras. */ \
-                                 IS_DEVA(u) ? POS_AFTER_SUB  : \
-                                 IS_GURM(u) ? POS_AFTER_POST : /* Deviate from 
spec */ \
-                                 IS_GUJA(u) ? POS_AFTER_SUB  : \
-                                 IS_ORYA(u) ? POS_AFTER_MAIN : \
-                                 IS_TAML(u) ? POS_AFTER_SUB  : \
-                                 IS_TELU(u) ? POS_BEFORE_SUB : \
-                                 IS_KNDA(u) ? POS_BEFORE_SUB : \
-                                 IS_SINH(u) ? POS_AFTER_SUB  : \
-                                 IS_KHMR(u) ? POS_AFTER_POST : \
-                                 /*default*/  POS_AFTER_SUB    \
-                               )
-#define MATRA_POS_BOTTOM(u)    ( \
-                                 IS_DEVA(u) ? POS_AFTER_SUB  : \
-                                 IS_BENG(u) ? POS_AFTER_SUB  : \
-                                 IS_GURM(u) ? POS_AFTER_POST : \
-                                 IS_GUJA(u) ? POS_AFTER_POST : \
-                                 IS_ORYA(u) ? POS_AFTER_SUB  : \
-                                 IS_TAML(u) ? POS_AFTER_POST : \
-                                 IS_TELU(u) ? POS_BEFORE_SUB : \
-                                 IS_KNDA(u) ? POS_BEFORE_SUB : \
-                                 IS_MLYM(u) ? POS_AFTER_POST : \
-                                 IS_SINH(u) ? POS_AFTER_SUB  : \
-                                 IS_KHMR(u) ? POS_AFTER_POST : \
-                                 /*default*/  POS_AFTER_SUB    \
-                               )
-
-
-static indic_position_t
-matra_position (hb_codepoint_t u, indic_position_t side)
-{
-  switch ((int) side)
-  {
-    case POS_PRE_C:    return MATRA_POS_LEFT (u);
-    case POS_POST_C:   return MATRA_POS_RIGHT (u);
-    case POS_ABOVE_C:  return MATRA_POS_TOP (u);
-    case POS_BELOW_C:  return MATRA_POS_BOTTOM (u);
-  };
-  abort ();
-}
-
-static inline bool
-is_ra (hb_codepoint_t u)
-{
-  return !!bsearch (&u, ra_chars,
-                   ARRAY_LENGTH (ra_chars),
-                   sizeof (ra_chars[0]),
-                   compare_codepoint);
-}
-
-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;
-  return !!(FLAG (info.indic_category()) & flags);
-}
-
-#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
-static inline bool
-is_joiner (const hb_glyph_info_t &info)
-{
-  return is_one_of (info, JOINER_FLAGS);
-}
-
-/* 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_Ra) | FLAG (OT_V) | FLAG 
(OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
-static inline bool
-is_consonant (const hb_glyph_info_t &info)
-{
-  return is_one_of (info, CONSONANT_FLAGS);
-}
-
-#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
-static inline bool
-is_halant_or_coeng (const hb_glyph_info_t &info)
-{
-  return is_one_of (info, HALANT_OR_COENG_FLAGS);
-}
-
-static inline void
-set_indic_properties (hb_glyph_info_t   &info,
-                     const indic_shape_plan_t *closure,
-                     hb_font_t         *font)
-{
-  hb_codepoint_t u = info.codepoint;
-  unsigned int type = get_indic_categories (u);
-  indic_category_t cat = (indic_category_t) (type & 0x0F);
-  indic_position_t pos = (indic_position_t) (type >> 4);
-
-
-  /*
-   * Re-assign category
-   */
-
-
-  /* The spec says U+0952 is OT_A.  However, testing shows that Uniscribe
-   * treats U+0951..U+0952 all as OT_VD.
-   * TESTS:
-   * U+092E,U+0947,U+0952
-   * U+092E,U+0952,U+0947
-   * U+092E,U+0947,U+0951
-   * U+092E,U+0951,U+0947
-   * */
-  if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0951, 0x0954)))
-    cat = OT_VD;
-
-  if (unlikely (u == 0x17D1))
-    cat = OT_X;
-  if (cat == OT_X &&
-      unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CB, 0x17D3))) /* Khmer 
Various signs */
-  {
-    /* These are like Top Matras. */
-    cat = OT_M;
-    pos = POS_ABOVE_C;
-  }
-  if (u == 0x17C6) /* Khmer Bindu doesn't like to be repositioned. */
-    cat = OT_N;
-
-  if (unlikely (u == 0x17D2)) cat = OT_Coeng; /* Khmer coeng */
-  else if (unlikely (u == 0x200C)) cat = OT_ZWNJ;
-  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.  More like 
consonant medial. like 0A75. */
-
-  if (cat == OT_Repha) {
-    /* There are two kinds of characters marked as Repha:
-     * - The ones that are GenCat=Mn are already positioned visually, ie. 
after base. (eg. Khmer)
-     * - The ones that are GenCat=Lo is encoded logically, ie. beginning of 
syllable. (eg. Malayalam)
-     *
-     * We recategorize the first kind to look like a Nukta and attached to the 
base directly.
-     */
-    if (_hb_glyph_info_get_general_category (&info) == 
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
-      cat = OT_N;
-  }
-
-
-
-  /*
-   * Re-assign position.
-   */
-
-  if ((FLAG (cat) & CONSONANT_FLAGS))
-  {
-    pos = consonant_position (u, closure, font);
-    if (is_ra (u))
-      cat = OT_Ra;
-  }
-  else if (cat == OT_M)
-  {
-    pos = matra_position (u, pos);
-  }
-  else if (cat == OT_SM || cat == OT_VD)
-  {
-    pos = POS_SMVD;
-  }
-
-  if (unlikely (u == 0x0B01)) pos = POS_BEFORE_SUB; /* Oriya Bindu is 
BeforeSub in the spec. */
-
-
-
-  info.indic_category() = cat;
-  info.indic_position() = pos;
-}
-
-
-
-
-
 
 
 struct feature_list_t {
@@ -477,7 +262,11 @@ setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
 
   unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++)
-    set_indic_properties (buffer->info[i], &indic_plan, font);
+    set_indic_properties (buffer->info[i]);
+
+  for (unsigned int i = 0; i < count; i++)
+    if (buffer->info[i].indic_position() == POS_BASE_C)
+      buffer->info[i].indic_position() = consonant_position_from_font 
(buffer->info[i].codepoint, &indic_plan, font);
 }
 
 static int
commit 3614ba242fc7d338761acdda365a134706035b6d
Author: Behdad Esfahbod <beh...@behdad.org>
Date:   Thu Aug 2 07:13:55 2012 -0400

    [Indic] Rename

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 8e3f3e6..883e32f 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -106,11 +106,11 @@ compare_codepoint (const void *pa, const void *pb)
   return a < b ? -1 : a == b ? 0 : +1;
 }
 
-struct consonant_position_closure_t
+struct indic_shape_plan_t
 {
-  struct feature_t
+  struct would_apply_feature_t
   {
-    feature_t (const hb_ot_map_t *map, hb_tag_t feature_tag)
+    would_apply_feature_t (const hb_ot_map_t *map, hb_tag_t feature_tag)
     {
       map->get_stage_lookups (0/*GSUB*/,
                              map->get_feature_stage (0/*GSUB*/, feature_tag),
@@ -132,21 +132,23 @@ struct consonant_position_closure_t
     unsigned int count;
   };
 
-  consonant_position_closure_t (const hb_ot_map_t *map_) :
-                                       map (map_),
-                                       pref (map_, HB_TAG('p','r','e','f')),
-                                       blwf (map_, HB_TAG('b','l','w','f')),
-                                       pstf (map_, HB_TAG('p','s','t','f')) {}
+  indic_shape_plan_t (const hb_ot_map_t *map_) :
+                     map (map_),
+                     pref (map_, HB_TAG('p','r','e','f')),
+                     blwf (map_, HB_TAG('b','l','w','f')),
+                     pstf (map_, HB_TAG('p','s','t','f')),
+                     is_old_spec (IS_OLD_INDIC_TAG (map->get_chosen_script 
(0))) {}
 
   const hb_ot_map_t *map;
-  feature_t pref;
-  feature_t blwf;
-  feature_t pstf;
+  would_apply_feature_t pref;
+  would_apply_feature_t blwf;
+  would_apply_feature_t pstf;
+  bool is_old_spec;
 };
 
 static indic_position_t
 consonant_position (hb_codepoint_t  u,
-                   const consonant_position_closure_t *closure,
+                   const indic_shape_plan_t *indic_plan,
                    hb_font_t      *font)
 {
   if ((u & ~0x007F) == 0x1780)
@@ -157,14 +159,14 @@ consonant_position (hb_codepoint_t  u,
   if ((u & ~0x007F) == 0x1780) virama = 0x17D2; /* Khmaer */
   hb_codepoint_t glyphs[2];
 
-  unsigned int virama_pos = IS_OLD_INDIC_TAG (closure->map->get_chosen_script 
(0)) ? 1 : 0;
+  unsigned int virama_pos = indic_plan->is_old_spec ? 1 : 0;
   font->get_glyph (virama, 0, &glyphs[virama_pos]);
   font->get_glyph (u,      0, &glyphs[1-virama_pos]);
 
   hb_face_t *face = font->face;
-  if (closure->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) 
return POS_BELOW_C;
-  if (closure->blwf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) 
return POS_BELOW_C;
-  if (closure->pstf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) 
return POS_POST_C;
+  if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) 
return POS_BELOW_C;
+  if (indic_plan->blwf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) 
return POS_BELOW_C;
+  if (indic_plan->pstf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) 
return POS_POST_C;
   return POS_BASE_C;
 }
 
@@ -269,7 +271,7 @@ is_halant_or_coeng (const hb_glyph_info_t &info)
 
 static inline void
 set_indic_properties (hb_glyph_info_t   &info,
-                     const consonant_position_closure_t *closure,
+                     const indic_shape_plan_t *closure,
                      hb_font_t         *font)
 {
   hb_codepoint_t u = info.codepoint;
@@ -471,11 +473,11 @@ setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
   /* We cannot setup masks here.  We save information about characters
    * and setup masks later on in a pause-callback. */
 
-  consonant_position_closure_t closure (map);
+  indic_shape_plan_t indic_plan (map);
 
   unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++)
-    set_indic_properties (buffer->info[i], &closure, font);
+    set_indic_properties (buffer->info[i], &indic_plan, font);
 }
 
 static int
_______________________________________________
HarfBuzz mailing list
HarfBuzz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/harfbuzz

Reply via email to