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

Behdad Esfahbod behdad at kemper.freedesktop.org
Thu Jul 7 21:15:24 PDT 2011


 TODO                                     |    4 
 src/Makefile.am                          |    1 
 src/hb-font-private.hh                   |   16 +-
 src/hb-font.cc                           |    3 
 src/hb-glib.cc                           |    6 -
 src/hb-icu.cc                            |    6 -
 src/hb-ot-map-private.hh                 |    2 
 src/hb-ot-map.cc                         |    2 
 src/hb-ot-shape-complex-arabic.cc        |   36 +++---
 src/hb-ot-shape-complex-indic-machine.rl |   12 +-
 src/hb-ot-shape-complex-indic.cc         |   25 ++--
 src/hb-ot-shape-complex-misc.cc          |   51 +++++++++
 src/hb-ot-shape-complex-private.hh       |   72 +++++++++----
 src/hb-ot-shape-private.hh               |   13 --
 src/hb-ot-shape.cc                       |   12 +-
 src/hb-shape.cc                          |    2 
 src/hb-unicode-private.hh                |   60 +++++------
 src/hb-unicode.cc                        |  168 ++++++++++++++++++-------------
 src/hb-unicode.h                         |   70 +++++++++---
 test/test-unicode.c                      |   21 ++-
 20 files changed, 367 insertions(+), 215 deletions(-)

New commits:
commit c4641723fbf6532b2e80a662e15573b31276bc73
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Jul 7 23:47:19 2011 -0400

    [API] Add compose() and decompose() unicode funcs, rename other ones
    
    Add compose() and decompose() unicode funcs.  These implement
    pair-wise canonical composition/decomposition.
    
    The glib/icu implementations are lacking for now.  We are adding
    API for this to glib, but I cannot find any useful API in ICU.
    May end of implementing these in-house.
    
    Changed all unicode_funcs callback names to remove the "_get" part.
    Eg, hb_unicode_get_script_func_t is now hb_unicode_script_func_t,
    and hb_unicode_get_script() is hb_unicode_script() now.

diff --git a/TODO b/TODO
index c5fe068..e15e295 100644
--- a/TODO
+++ b/TODO
@@ -68,7 +68,9 @@ Tests to write:
 
 - ot-layout enumeration API (needs font)
 
-- Finish test-shape.c
+- Finish test-shape.c, grep for TODO
+
+- Finish test-unicode.c, grep for TODO
 
 
 Optimizations:
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 109b9ba..de90972 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -231,7 +231,11 @@ hb_unicode_funcs_t _hb_glib_unicode_funcs = {
     hb_glib_get_eastasian_width,
     hb_glib_get_general_category,
     hb_glib_get_mirroring,
-    hb_glib_get_script
+    hb_glib_get_script,
+    /* TODO
+    hb_glib_compose,
+    hb_glib_decompose,
+    */
   }
 };
 
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 1e0134c..4797cc5 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -174,7 +174,11 @@ hb_unicode_funcs_t _hb_icu_unicode_funcs = {
     hb_icu_get_eastasian_width,
     hb_icu_get_general_category,
     hb_icu_get_mirroring,
-    hb_icu_get_script
+    hb_icu_get_script,
+    /* TODO
+    hb_icu_compose,
+    hb_icu_decompose,
+    */
   }
 };
 
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 248f2bd..8378e81 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -197,8 +197,8 @@ hb_set_unicode_props (hb_ot_shape_context_t *c)
 
   unsigned int count = c->buffer->len;
   for (unsigned int i = 1; i < count; i++) {
-    info[i].general_category() = hb_unicode_get_general_category (unicode, info[i].codepoint);
-    info[i].combining_class() = hb_unicode_get_combining_class (unicode, info[i].codepoint);
+    info[i].general_category() = hb_unicode_general_category (unicode, info[i].codepoint);
+    info[i].combining_class() = hb_unicode_combining_class (unicode, info[i].codepoint);
   }
 }
 
@@ -252,7 +252,7 @@ hb_mirror_chars (hb_ot_shape_context_t *c)
 
   unsigned int count = c->buffer->len;
   for (unsigned int i = 0; i < count; i++) {
-    hb_codepoint_t codepoint = hb_unicode_get_mirroring (unicode, c->buffer->info[i].codepoint);
+    hb_codepoint_t codepoint = hb_unicode_mirroring (unicode, c->buffer->info[i].codepoint);
     if (likely (codepoint == c->buffer->info[i].codepoint))
       c->buffer->info[i].mask |= rtlm_mask; /* XXX this should be moved to before setting user-feature masks */
     else
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 5db6cfe..1ff830a 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -63,7 +63,7 @@ hb_shape (hb_font_t          *font,
     hb_unicode_funcs_t *unicode = buffer->unicode;
     unsigned int count = buffer->len;
     for (unsigned int i = 0; i < count; i++) {
-      hb_script_t script = hb_unicode_get_script (unicode, buffer->info[i].codepoint);
+      hb_script_t script = hb_unicode_script (unicode, buffer->info[i].codepoint);
       if (likely (script != HB_SCRIPT_COMMON &&
 		  script != HB_SCRIPT_INHERITED &&
 		  script != HB_SCRIPT_UNKNOWN)) {
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index 55b94a7..2b0ec99 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -49,6 +49,8 @@ HB_BEGIN_DECLS
   HB_UNICODE_FUNC_IMPLEMENT (general_category) \
   HB_UNICODE_FUNC_IMPLEMENT (mirroring) \
   HB_UNICODE_FUNC_IMPLEMENT (script) \
+  HB_UNICODE_FUNC_IMPLEMENT (compose) \
+  HB_UNICODE_FUNC_IMPLEMENT (decompose) \
   /* ^--- Add new callbacks here */
 
 /* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */
@@ -67,13 +69,13 @@ struct _hb_unicode_funcs_t {
 
   bool immutable;
 
-  /* Don't access these directly.  Call hb_unicode_get_*() instead. */
+  /* Don't access these directly.  Call hb_unicode_*() instead. */
 
   struct {
-#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_get_##name##_func_t name;
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name;
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
-  } get;
+  } func;
 
   struct {
 #define HB_UNICODE_FUNC_IMPLEMENT(name) void *name;
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index ba0004b..e2043c2 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -40,45 +40,67 @@ HB_BEGIN_DECLS
  */
 
 static unsigned int
-hb_unicode_get_combining_class_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-				    hb_codepoint_t      unicode   HB_UNUSED,
-				    void               *user_data HB_UNUSED)
+hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+				hb_codepoint_t      unicode   HB_UNUSED,
+				void               *user_data HB_UNUSED)
 {
   return 0;
 }
 
 static unsigned int
-hb_unicode_get_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-				    hb_codepoint_t      unicode   HB_UNUSED,
-				    void               *user_data HB_UNUSED)
+hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+				hb_codepoint_t      unicode   HB_UNUSED,
+				void               *user_data HB_UNUSED)
 {
   return 1;
 }
 
 static hb_unicode_general_category_t
-hb_unicode_get_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-				     hb_codepoint_t      unicode   HB_UNUSED,
-				     void               *user_data HB_UNUSED)
+hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+				 hb_codepoint_t      unicode   HB_UNUSED,
+				 void               *user_data HB_UNUSED)
 {
   return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
 }
 
 static hb_codepoint_t
-hb_unicode_get_mirroring_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-			      hb_codepoint_t      unicode   HB_UNUSED,
-			      void               *user_data HB_UNUSED)
+hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+			  hb_codepoint_t      unicode   HB_UNUSED,
+			  void               *user_data HB_UNUSED)
 {
   return unicode;
 }
 
 static hb_script_t
-hb_unicode_get_script_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-			   hb_codepoint_t      unicode   HB_UNUSED,
-			   void               *user_data HB_UNUSED)
+hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+		       hb_codepoint_t      unicode   HB_UNUSED,
+		       void               *user_data HB_UNUSED)
 {
   return HB_SCRIPT_UNKNOWN;
 }
 
+static hb_bool_t
+hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs,
+			hb_codepoint_t      a         HB_UNUSED,
+			hb_codepoint_t      b         HB_UNUSED,
+			hb_codepoint_t     *ab        HB_UNUSED,
+			void               *user_data HB_UNUSED)
+{
+  /* TODO handle Hangul jamo here? */
+  return FALSE;
+}
+
+static hb_bool_t
+hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs,
+			  hb_codepoint_t      ab        HB_UNUSED,
+			  hb_codepoint_t     *a         HB_UNUSED,
+			  hb_codepoint_t     *b         HB_UNUSED,
+			  void               *user_data HB_UNUSED)
+{
+  /* TODO handle Hangul jamo here? */
+  return FALSE;
+}
+
 
 hb_unicode_funcs_t _hb_unicode_funcs_nil = {
   HB_OBJECT_HEADER_STATIC,
@@ -86,7 +108,7 @@ hb_unicode_funcs_t _hb_unicode_funcs_nil = {
   NULL, /* parent */
   TRUE, /* immutable */
   {
-#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_get_##name##_nil,
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
   }
@@ -113,7 +135,7 @@ hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
   hb_unicode_funcs_make_immutable (parent);
   ufuncs->parent = hb_unicode_funcs_reference (parent);
 
-  ufuncs->get = parent->get;
+  ufuncs->func = parent->func;
 
   /* We can safely copy user_data from parent since we hold a reference
    * onto it and it's immutable.  We should not copy the destroy notifiers
@@ -193,7 +215,7 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
 										\
 void										\
 hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
-				    hb_unicode_get_##name##_func_t  func,	\
+				    hb_unicode_##name##_func_t	    func,	\
 				    void			   *user_data,	\
 				    hb_destroy_func_t		    destroy)	\
 {										\
@@ -204,11 +226,11 @@ hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
     ufuncs->destroy.name (ufuncs->user_data.name);				\
 										\
   if (func) {									\
-    ufuncs->get.name = func;							\
+    ufuncs->func.name = func;							\
     ufuncs->user_data.name = user_data;						\
     ufuncs->destroy.name = destroy;						\
   } else {									\
-    ufuncs->get.name = ufuncs->parent->get.name;				\
+    ufuncs->func.name = ufuncs->parent->func.name;				\
     ufuncs->user_data.name = ufuncs->parent->user_data.name;			\
     ufuncs->destroy.name = NULL;						\
   }										\
@@ -221,13 +243,30 @@ hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
 #define HB_UNICODE_FUNC_IMPLEMENT(return_type, name)				\
 										\
 return_type									\
-hb_unicode_get_##name (hb_unicode_funcs_t *ufuncs,				\
-		       hb_codepoint_t      unicode)				\
+hb_unicode_##name (hb_unicode_funcs_t *ufuncs,					\
+		   hb_codepoint_t      unicode)					\
 {										\
-  return ufuncs->get.name (ufuncs, unicode, ufuncs->user_data.name);		\
+  return ufuncs->func.name (ufuncs, unicode, ufuncs->user_data.name);		\
 }
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
 #undef HB_UNICODE_FUNC_IMPLEMENT
 
+hb_bool_t
+hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
+		    hb_codepoint_t      a,
+		    hb_codepoint_t      b,
+		    hb_codepoint_t     *ab)
+{
+  return ufuncs->func.compose (ufuncs, a, b, ab, ufuncs->user_data.compose);
+}
+
+hb_bool_t
+hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
+		      hb_codepoint_t      ab,
+		      hb_codepoint_t     *a,
+		      hb_codepoint_t     *b)
+{
+  return ufuncs->func.decompose (ufuncs, ab, a, b, ufuncs->user_data.decompose);
+}
 
 HB_END_DECLS
diff --git a/src/hb-unicode.h b/src/hb-unicode.h
index e7a2005..9aa97a6 100644
--- a/src/hb-unicode.h
+++ b/src/hb-unicode.h
@@ -90,73 +90,103 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
 
 /* typedefs */
 
-typedef unsigned int                  (*hb_unicode_get_combining_class_func_t)  (hb_unicode_funcs_t *ufuncs,
+typedef unsigned int			(*hb_unicode_combining_class_func_t)	(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t      unicode,
 										 void               *user_data);
-typedef unsigned int                  (*hb_unicode_get_eastasian_width_func_t)  (hb_unicode_funcs_t *ufuncs,
+typedef unsigned int			(*hb_unicode_eastasian_width_func_t)	(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t      unicode,
 										 void               *user_data);
-typedef hb_unicode_general_category_t (*hb_unicode_get_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
+typedef hb_unicode_general_category_t	(*hb_unicode_general_category_func_t)	(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t      unicode,
 										 void               *user_data);
-typedef hb_codepoint_t                (*hb_unicode_get_mirroring_func_t)        (hb_unicode_funcs_t *ufuncs,
+typedef hb_codepoint_t			(*hb_unicode_mirroring_func_t)		(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t      unicode,
 										 void               *user_data);
-typedef hb_script_t                   (*hb_unicode_get_script_func_t)           (hb_unicode_funcs_t *ufuncs,
+typedef hb_script_t			(*hb_unicode_script_func_t)		(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t      unicode,
 										 void               *user_data);
 
+typedef hb_bool_t			(*hb_unicode_compose_func_t)		(hb_unicode_funcs_t *ufuncs,
+										 hb_codepoint_t      a,
+										 hb_codepoint_t      b,
+										 hb_codepoint_t     *ab,
+										 void               *user_data);
+typedef hb_bool_t			(*hb_unicode_decompose_func_t)		(hb_unicode_funcs_t *ufuncs,
+										 hb_codepoint_t      ab,
+										 hb_codepoint_t     *a,
+										 hb_codepoint_t     *b,
+										 void               *user_data);
+
 /* setters */
 
 void
 hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
-					   hb_unicode_get_combining_class_func_t combining_class_func,
+					   hb_unicode_combining_class_func_t combining_class_func,
 					   void *user_data, hb_destroy_func_t destroy);
 
 void
 hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
-					   hb_unicode_get_eastasian_width_func_t eastasian_width_func,
+					   hb_unicode_eastasian_width_func_t eastasian_width_func,
 					   void *user_data, hb_destroy_func_t destroy);
 
 void
 hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
-					    hb_unicode_get_general_category_func_t general_category_func,
+					    hb_unicode_general_category_func_t general_category_func,
 					    void *user_data, hb_destroy_func_t destroy);
 
 void
 hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
-				     hb_unicode_get_mirroring_func_t mirroring_func,
+				     hb_unicode_mirroring_func_t mirroring_func,
 				     void *user_data, hb_destroy_func_t destroy);
 
 void
 hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
-				  hb_unicode_get_script_func_t script_func,
+				  hb_unicode_script_func_t script_func,
 				  void *user_data, hb_destroy_func_t destroy);
 
+void
+hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
+				   hb_unicode_compose_func_t compose_func,
+				   void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
+				     hb_unicode_decompose_func_t decompose_func,
+				     void *user_data, hb_destroy_func_t destroy);
 
 
 /* accessors */
 
 unsigned int
-hb_unicode_get_combining_class (hb_unicode_funcs_t *ufuncs,
-				hb_codepoint_t unicode);
+hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
+			    hb_codepoint_t unicode);
 
 unsigned int
-hb_unicode_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
-				hb_codepoint_t unicode);
+hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
+			    hb_codepoint_t unicode);
 
 hb_unicode_general_category_t
-hb_unicode_get_general_category (hb_unicode_funcs_t *ufuncs,
-				 hb_codepoint_t unicode);
+hb_unicode_general_category (hb_unicode_funcs_t *ufuncs,
+			     hb_codepoint_t unicode);
 
 hb_codepoint_t
-hb_unicode_get_mirroring (hb_unicode_funcs_t *ufuncs,
-			  hb_codepoint_t unicode);
+hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs,
+		      hb_codepoint_t unicode);
 
 hb_script_t
-hb_unicode_get_script (hb_unicode_funcs_t *ufuncs,
-		       hb_codepoint_t unicode);
+hb_unicode_script (hb_unicode_funcs_t *ufuncs,
+		   hb_codepoint_t unicode);
 
+hb_bool_t
+hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
+		    hb_codepoint_t      a,
+		    hb_codepoint_t      b,
+		    hb_codepoint_t     *ab);
+hb_bool_t
+hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
+		      hb_codepoint_t      ab,
+		      hb_codepoint_t     *a,
+		      hb_codepoint_t     *b);
 
 HB_END_DECLS
 
diff --git a/test/test-unicode.c b/test/test-unicode.c
index c84ba86..a691cb4 100644
--- a/test/test-unicode.c
+++ b/test/test-unicode.c
@@ -93,7 +93,7 @@ a_is_for_arabic_get_script (hb_unicode_funcs_t *ufuncs,
   } else {
     hb_unicode_funcs_t *parent = hb_unicode_funcs_get_parent (ufuncs);
 
-    return hb_unicode_get_script (parent, codepoint);
+    return hb_unicode_script (parent, codepoint);
   }
 }
 
@@ -457,7 +457,7 @@ typedef struct {
   { \
     #name, \
     (func_setter_func_t) hb_unicode_funcs_set_##name##_func, \
-    (getter_func_t) hb_unicode_get_##name, \
+    (getter_func_t) hb_unicode_##name, \
     name##_tests, \
     G_N_ELEMENTS (name##_tests), \
     name##_tests_more, \
@@ -667,8 +667,8 @@ test_unicode_subclassing_nil (data_fixture_t *f, gconstpointer user_data)
   hb_unicode_funcs_set_script_func (aa, a_is_for_arabic_get_script,
                                     &f->data[1], free_up);
 
-  g_assert_cmphex (hb_unicode_get_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
-  g_assert_cmphex (hb_unicode_get_script (aa, 'b'), ==, HB_SCRIPT_UNKNOWN);
+  g_assert_cmphex (hb_unicode_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
+  g_assert_cmphex (hb_unicode_script (aa, 'b'), ==, HB_SCRIPT_UNKNOWN);
 
   g_assert (!f->data[0].freed && !f->data[1].freed);
   hb_unicode_funcs_destroy (aa);
@@ -686,8 +686,8 @@ test_unicode_subclassing_default (data_fixture_t *f, gconstpointer user_data)
   hb_unicode_funcs_set_script_func (aa, a_is_for_arabic_get_script,
                                     &f->data[1], free_up);
 
-  g_assert_cmphex (hb_unicode_get_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
-  g_assert_cmphex (hb_unicode_get_script (aa, 'b'), ==, HB_SCRIPT_LATIN);
+  g_assert_cmphex (hb_unicode_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
+  g_assert_cmphex (hb_unicode_script (aa, 'b'), ==, HB_SCRIPT_LATIN);
 
   g_assert (!f->data[0].freed && !f->data[1].freed);
   hb_unicode_funcs_destroy (aa);
@@ -714,9 +714,9 @@ test_unicode_subclassing_deep (data_fixture_t *f, gconstpointer user_data)
   hb_unicode_funcs_set_script_func (aa, a_is_for_arabic_get_script,
                                     &f->data[1], free_up);
 
-  g_assert_cmphex (hb_unicode_get_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
-  g_assert_cmphex (hb_unicode_get_script (aa, 'b'), ==, HB_SCRIPT_LATIN);
-  g_assert_cmphex (hb_unicode_get_script (aa, '0'), ==, HB_SCRIPT_UNKNOWN);
+  g_assert_cmphex (hb_unicode_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
+  g_assert_cmphex (hb_unicode_script (aa, 'b'), ==, HB_SCRIPT_LATIN);
+  g_assert_cmphex (hb_unicode_script (aa, '0'), ==, HB_SCRIPT_UNKNOWN);
 
   g_assert (!f->data[0].freed && !f->data[1].freed);
   hb_unicode_funcs_destroy (aa);
@@ -779,6 +779,9 @@ test_unicode_script_roundtrip (gconstpointer user_data)
 }
 
 
+/* TODO test compose() and decompose() */
+
+
 int
 main (int argc, char **argv)
 {
commit d05dded1676924e8894c90f7a7c3527b492bcdff
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Jul 7 23:42:40 2011 -0400

    More code generation through preprocessor

diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index 93268ba..c10fdf9 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -39,10 +39,16 @@ HB_BEGIN_DECLS
 #define combining_class() var1.u8[1] /* unicode combining_class (uint8_t) */
 
 
+#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
+  HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
+  HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
+  /* ^--- Add new shapers here */
+
 enum hb_ot_complex_shaper_t {
-  hb_ot_complex_shaper_default,
-  hb_ot_complex_shaper_arabic,
-  hb_ot_complex_shaper_indic
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) hb_ot_complex_shaper_##name,
+  HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
 };
 
 static inline hb_ot_complex_shaper_t
@@ -50,6 +56,9 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
 {
   switch ((int) props->script)
   {
+    default:
+      return hb_ot_complex_shaper_default;
+
     case HB_SCRIPT_ARABIC:
     case HB_SCRIPT_MANDAIC:
     case HB_SCRIPT_MONGOLIAN:
@@ -103,8 +112,7 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
     case HB_SCRIPT_TIBETAN:
       return hb_ot_complex_shaper_indic;
 
-    default:
-      return hb_ot_complex_shaper_default;
+    /* ^--- Add new shapers here */
   }
 }
 
@@ -119,9 +127,10 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
  */
 
 typedef void hb_ot_shape_complex_collect_features_func_t (hb_ot_map_builder_t *map, const hb_segment_properties_t  *props);
-HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_default;
-HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_arabic;
-HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_indic;
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
+  HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_##name;
+  HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
 
 static inline void
 hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper,
@@ -130,9 +139,10 @@ hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper,
 {
   switch (shaper) {
     default:
-    case hb_ot_complex_shaper_default:	_hb_ot_shape_complex_collect_features_default	(map, props);	return;
-    case hb_ot_complex_shaper_arabic:	_hb_ot_shape_complex_collect_features_arabic	(map, props);	return;
-    case hb_ot_complex_shaper_indic:	_hb_ot_shape_complex_collect_features_indic	(map, props);	return;
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
+    case hb_ot_complex_shaper_##name:	_hb_ot_shape_complex_collect_features_##name	(map, props);	return;
+    HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
   }
 }
 
@@ -145,9 +155,10 @@ hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper,
  */
 
 typedef void hb_ot_shape_complex_setup_masks_func_t (hb_ot_map_t *map, hb_buffer_t *buffer);
-HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_default;
-HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_arabic;
-HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_indic;
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
+  HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_##name;
+  HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
 
 static inline void
 hb_ot_shape_complex_setup_masks (hb_ot_complex_shaper_t shaper,
@@ -156,9 +167,10 @@ hb_ot_shape_complex_setup_masks (hb_ot_complex_shaper_t shaper,
 {
   switch (shaper) {
     default:
-    case hb_ot_complex_shaper_default:	_hb_ot_shape_complex_setup_masks_default(map, buffer);	return;
-    case hb_ot_complex_shaper_arabic:	_hb_ot_shape_complex_setup_masks_arabic	(map, buffer);	return;
-    case hb_ot_complex_shaper_indic:	_hb_ot_shape_complex_setup_masks_indic	(map, buffer);	return;
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) \
+    case hb_ot_complex_shaper_##name:	_hb_ot_shape_complex_setup_masks_##name	(map, buffer);	return;
+    HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
   }
 }
 
commit 891c4755baae6cd59fad59d27fd8933e5f548a74
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Jul 7 23:19:27 2011 -0400

    Humm, undo some shuffling
    
    In preparation for adding more advanced unicode funcs.

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 584ffbd..248f2bd 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -197,8 +197,8 @@ hb_set_unicode_props (hb_ot_shape_context_t *c)
 
   unsigned int count = c->buffer->len;
   for (unsigned int i = 1; i < count; i++) {
-    info[i].general_category() = unicode->get_general_category (info[i].codepoint);
-    info[i].combining_class() = unicode->get_combining_class (info[i].codepoint);
+    info[i].general_category() = hb_unicode_get_general_category (unicode, info[i].codepoint);
+    info[i].combining_class() = hb_unicode_get_combining_class (unicode, info[i].codepoint);
   }
 }
 
@@ -252,7 +252,7 @@ hb_mirror_chars (hb_ot_shape_context_t *c)
 
   unsigned int count = c->buffer->len;
   for (unsigned int i = 0; i < count; i++) {
-    hb_codepoint_t codepoint = unicode->get_mirroring (c->buffer->info[i].codepoint);
+    hb_codepoint_t codepoint = hb_unicode_get_mirroring (unicode, c->buffer->info[i].codepoint);
     if (likely (codepoint == c->buffer->info[i].codepoint))
       c->buffer->info[i].mask |= rtlm_mask; /* XXX this should be moved to before setting user-feature masks */
     else
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 8855eaf..5db6cfe 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -63,7 +63,7 @@ hb_shape (hb_font_t          *font,
     hb_unicode_funcs_t *unicode = buffer->unicode;
     unsigned int count = buffer->len;
     for (unsigned int i = 0; i < count; i++) {
-      hb_script_t script = unicode->get_script (buffer->info[i].codepoint);
+      hb_script_t script = hb_unicode_get_script (unicode, buffer->info[i].codepoint);
       if (likely (script != HB_SCRIPT_COMMON &&
 		  script != HB_SCRIPT_INHERITED &&
 		  script != HB_SCRIPT_UNKNOWN)) {
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index 1f0e490..55b94a7 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -44,13 +44,22 @@ HB_BEGIN_DECLS
  */
 
 #define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \
-  HB_UNICODE_FUNC_IMPLEMENT (unsigned int, combining_class, 0) \
-  HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width, 1) \
-  HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category, HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) \
-  HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring, unicode) \
-  HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script, HB_SCRIPT_UNKNOWN) \
+  HB_UNICODE_FUNC_IMPLEMENT (combining_class) \
+  HB_UNICODE_FUNC_IMPLEMENT (eastasian_width) \
+  HB_UNICODE_FUNC_IMPLEMENT (general_category) \
+  HB_UNICODE_FUNC_IMPLEMENT (mirroring) \
+  HB_UNICODE_FUNC_IMPLEMENT (script) \
   /* ^--- Add new callbacks here */
 
+/* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */
+#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE \
+  HB_UNICODE_FUNC_IMPLEMENT (unsigned int, combining_class) \
+  HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width) \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category) \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring) \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \
+  /* ^--- Add new simple callbacks here */
+
 struct _hb_unicode_funcs_t {
   hb_object_header_t header;
 
@@ -58,31 +67,22 @@ struct _hb_unicode_funcs_t {
 
   bool immutable;
 
-#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) \
-  inline return_type \
-  get_##name (hb_codepoint_t unicode) \
-  { return this->get.name (this, unicode, this->user_data.name); }
-
-  HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
-
-#undef HB_UNICODE_FUNC_IMPLEMENT
-
-  /* Don't access these directly.  Call get_*() instead. */
+  /* Don't access these directly.  Call hb_unicode_get_*() instead. */
 
   struct {
-#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) hb_unicode_get_##name##_func_t name;
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_get_##name##_func_t name;
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
   } get;
 
   struct {
-#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) void *name;
+#define HB_UNICODE_FUNC_IMPLEMENT(name) void *name;
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
   } user_data;
 
   struct {
-#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) hb_destroy_func_t name;
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
   } destroy;
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index 8ca178e..ba0004b 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -39,19 +39,45 @@ HB_BEGIN_DECLS
  * hb_unicode_funcs_t
  */
 
-#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value)		\
-										\
-										\
-static return_type								\
-hb_unicode_get_##name##_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,		\
-			     hb_codepoint_t      unicode   HB_UNUSED,		\
-			     void               *user_data HB_UNUSED)		\
-{										\
-  return default_value;								\
+static unsigned int
+hb_unicode_get_combining_class_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+				    hb_codepoint_t      unicode   HB_UNUSED,
+				    void               *user_data HB_UNUSED)
+{
+  return 0;
 }
 
-  HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_UNICODE_FUNC_IMPLEMENT
+static unsigned int
+hb_unicode_get_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+				    hb_codepoint_t      unicode   HB_UNUSED,
+				    void               *user_data HB_UNUSED)
+{
+  return 1;
+}
+
+static hb_unicode_general_category_t
+hb_unicode_get_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+				     hb_codepoint_t      unicode   HB_UNUSED,
+				     void               *user_data HB_UNUSED)
+{
+  return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
+}
+
+static hb_codepoint_t
+hb_unicode_get_mirroring_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+			      hb_codepoint_t      unicode   HB_UNUSED,
+			      void               *user_data HB_UNUSED)
+{
+  return unicode;
+}
+
+static hb_script_t
+hb_unicode_get_script_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+			   hb_codepoint_t      unicode   HB_UNUSED,
+			   void               *user_data HB_UNUSED)
+{
+  return HB_SCRIPT_UNKNOWN;
+}
 
 
 hb_unicode_funcs_t _hb_unicode_funcs_nil = {
@@ -60,7 +86,7 @@ hb_unicode_funcs_t _hb_unicode_funcs_nil = {
   NULL, /* parent */
   TRUE, /* immutable */
   {
-#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) hb_unicode_get_##name##_nil,
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_get_##name##_nil,
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
   }
@@ -114,7 +140,7 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
 {
   if (!hb_object_destroy (ufuncs)) return;
 
-#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) \
+#define HB_UNICODE_FUNC_IMPLEMENT(name) \
   if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
@@ -163,7 +189,7 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
 }
 
 
-#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value)		\
+#define HB_UNICODE_FUNC_IMPLEMENT(name)						\
 										\
 void										\
 hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
@@ -186,7 +212,13 @@ hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
     ufuncs->user_data.name = ufuncs->parent->user_data.name;			\
     ufuncs->destroy.name = NULL;						\
   }										\
-}										\
+}
+
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+
+
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name)				\
 										\
 return_type									\
 hb_unicode_get_##name (hb_unicode_funcs_t *ufuncs,				\
@@ -194,8 +226,7 @@ hb_unicode_get_##name (hb_unicode_funcs_t *ufuncs,				\
 {										\
   return ufuncs->get.name (ufuncs, unicode, ufuncs->user_data.name);		\
 }
-
-    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
 #undef HB_UNICODE_FUNC_IMPLEMENT
 
 
commit 4b6317c4f426cfaf21e509dbf6ee6d4e0422cdac
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Jul 7 23:14:42 2011 -0400

    More code shuffling

diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index b170c9d..dd71b67 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -41,13 +41,6 @@ HB_BEGIN_DECLS
  * hb_font_funcs_t
  */
 
-struct _hb_font_funcs_t {
-  hb_object_header_t header;
-
-  hb_bool_t immutable;
-
-  /* Don't access these directly.  Call hb_font_get_*() instead. */
-
 #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
   HB_FONT_FUNC_IMPLEMENT (glyph) \
   HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
@@ -57,8 +50,15 @@ struct _hb_font_funcs_t {
   HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
   HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
   HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_contour_point)
+  HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
+  /* ^--- Add new callbacks here */
 
+struct _hb_font_funcs_t {
+  hb_object_header_t header;
+
+  hb_bool_t immutable;
+
+  /* Don't access these directly.  Call hb_font_get_*() instead. */
 
   struct {
 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 27ec005..0406e10 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -236,7 +236,8 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
 {
   if (!hb_object_destroy (ffuncs)) return;
 
-#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) ffuncs->destroy.name (ffuncs->user_data.name);
+#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
+  ffuncs->destroy.name (ffuncs->user_data.name);
   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
 
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index 34da030..1f0e490 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -43,6 +43,14 @@ HB_BEGIN_DECLS
  * hb_unicode_funcs_t
  */
 
+#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \
+  HB_UNICODE_FUNC_IMPLEMENT (unsigned int, combining_class, 0) \
+  HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width, 1) \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category, HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring, unicode) \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script, HB_SCRIPT_UNKNOWN) \
+  /* ^--- Add new callbacks here */
+
 struct _hb_unicode_funcs_t {
   hb_object_header_t header;
 
@@ -50,43 +58,33 @@ struct _hb_unicode_funcs_t {
 
   bool immutable;
 
-#define IMPLEMENT(return_type, name) \
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) \
   inline return_type \
   get_##name (hb_codepoint_t unicode) \
   { return this->get.name (this, unicode, this->user_data.name); }
 
-  IMPLEMENT (unsigned int, combining_class)
-  IMPLEMENT (unsigned int, eastasian_width)
-  IMPLEMENT (hb_unicode_general_category_t, general_category)
-  IMPLEMENT (hb_codepoint_t, mirroring)
-  IMPLEMENT (hb_script_t, script)
+  HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 
-#undef IMPLEMENT
+#undef HB_UNICODE_FUNC_IMPLEMENT
 
   /* Don't access these directly.  Call get_*() instead. */
 
   struct {
-    hb_unicode_get_combining_class_func_t	combining_class;
-    hb_unicode_get_eastasian_width_func_t	eastasian_width;
-    hb_unicode_get_general_category_func_t	general_category;
-    hb_unicode_get_mirroring_func_t		mirroring;
-    hb_unicode_get_script_func_t		script;
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) hb_unicode_get_##name##_func_t name;
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
   } get;
 
   struct {
-    void 					*combining_class;
-    void 					*eastasian_width;
-    void 					*general_category;
-    void 					*mirroring;
-    void 					*script;
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) void *name;
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
   } user_data;
 
   struct {
-    hb_destroy_func_t				combining_class;
-    hb_destroy_func_t				eastasian_width;
-    hb_destroy_func_t				general_category;
-    hb_destroy_func_t				mirroring;
-    hb_destroy_func_t				script;
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) hb_destroy_func_t name;
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
   } destroy;
 };
 
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index c2d7311..8ca178e 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -39,45 +39,19 @@ HB_BEGIN_DECLS
  * hb_unicode_funcs_t
  */
 
-static unsigned int
-hb_unicode_get_combining_class_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-				    hb_codepoint_t      unicode   HB_UNUSED,
-				    void               *user_data HB_UNUSED)
-{
-  return 0;
-}
-
-static unsigned int
-hb_unicode_get_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-				    hb_codepoint_t      unicode   HB_UNUSED,
-				    void               *user_data HB_UNUSED)
-{
-  return 1;
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value)		\
+										\
+										\
+static return_type								\
+hb_unicode_get_##name##_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,		\
+			     hb_codepoint_t      unicode   HB_UNUSED,		\
+			     void               *user_data HB_UNUSED)		\
+{										\
+  return default_value;								\
 }
 
-static hb_unicode_general_category_t
-hb_unicode_get_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-				     hb_codepoint_t      unicode   HB_UNUSED,
-				     void               *user_data HB_UNUSED)
-{
-  return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
-}
-
-static hb_codepoint_t
-hb_unicode_get_mirroring_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-			      hb_codepoint_t      unicode   HB_UNUSED,
-			      void               *user_data HB_UNUSED)
-{
-  return unicode;
-}
-
-static hb_script_t
-hb_unicode_get_script_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-			   hb_codepoint_t      unicode   HB_UNUSED,
-			   void               *user_data HB_UNUSED)
-{
-  return HB_SCRIPT_UNKNOWN;
-}
+  HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
 
 
 hb_unicode_funcs_t _hb_unicode_funcs_nil = {
@@ -86,11 +60,9 @@ hb_unicode_funcs_t _hb_unicode_funcs_nil = {
   NULL, /* parent */
   TRUE, /* immutable */
   {
-    hb_unicode_get_combining_class_nil,
-    hb_unicode_get_eastasian_width_nil,
-    hb_unicode_get_general_category_nil,
-    hb_unicode_get_mirroring_nil,
-    hb_unicode_get_script_nil,
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) hb_unicode_get_##name##_nil,
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
   }
 };
 
@@ -142,13 +114,10 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
 {
   if (!hb_object_destroy (ufuncs)) return;
 
-#define DESTROY(name) if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name)
-  DESTROY (combining_class);
-  DESTROY (eastasian_width);
-  DESTROY (general_category);
-  DESTROY (mirroring);
-  DESTROY (script);
-#undef DESTROY
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value) \
+  if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
 
   hb_unicode_funcs_destroy (ufuncs->parent);
 
@@ -194,45 +163,40 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
 }
 
 
-#define IMPLEMENT(return_type, name)                                           \
-                                                                               \
-void                                                                           \
-hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t             *ufuncs,    \
-                                    hb_unicode_get_##name##_func_t  func,      \
-                                    void                           *user_data, \
-                                    hb_destroy_func_t               destroy)   \
-{                                                                              \
-  if (ufuncs->immutable)                                                       \
-    return;                                                                    \
-                                                                               \
-  if (ufuncs->destroy.name)                                                    \
-    ufuncs->destroy.name (ufuncs->user_data.name);                             \
-                                                                               \
-  if (func) {                                                                  \
-    ufuncs->get.name = func;                                                   \
-    ufuncs->user_data.name = user_data;                                        \
-    ufuncs->destroy.name = destroy;                                            \
-  } else {                                                                     \
-    ufuncs->get.name = ufuncs->parent->get.name;                               \
-    ufuncs->user_data.name = ufuncs->parent->user_data.name;                   \
-    ufuncs->destroy.name = NULL;                                               \
-  }                                                                            \
-}                                                                              \
-                                                                               \
-return_type                                                                    \
-hb_unicode_get_##name (hb_unicode_funcs_t *ufuncs,                             \
-		       hb_codepoint_t      unicode)                            \
-{                                                                              \
-  return ufuncs->get.name (ufuncs, unicode, ufuncs->user_data.name);           \
-}
-
-IMPLEMENT (unsigned int, combining_class)
-IMPLEMENT (unsigned int, eastasian_width)
-IMPLEMENT (hb_unicode_general_category_t, general_category)
-IMPLEMENT (hb_codepoint_t, mirroring)
-IMPLEMENT (hb_script_t, script)
-
-#undef IMPLEMENT
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name, default_value)		\
+										\
+void										\
+hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
+				    hb_unicode_get_##name##_func_t  func,	\
+				    void			   *user_data,	\
+				    hb_destroy_func_t		    destroy)	\
+{										\
+  if (ufuncs->immutable)							\
+    return;									\
+										\
+  if (ufuncs->destroy.name)							\
+    ufuncs->destroy.name (ufuncs->user_data.name);				\
+										\
+  if (func) {									\
+    ufuncs->get.name = func;							\
+    ufuncs->user_data.name = user_data;						\
+    ufuncs->destroy.name = destroy;						\
+  } else {									\
+    ufuncs->get.name = ufuncs->parent->get.name;				\
+    ufuncs->user_data.name = ufuncs->parent->user_data.name;			\
+    ufuncs->destroy.name = NULL;						\
+  }										\
+}										\
+										\
+return_type									\
+hb_unicode_get_##name (hb_unicode_funcs_t *ufuncs,				\
+		       hb_codepoint_t      unicode)				\
+{										\
+  return ufuncs->get.name (ufuncs, unicode, ufuncs->user_data.name);		\
+}
+
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
 
 
 HB_END_DECLS
commit 3361c9a323575309d9fd55fe076697a3e22073c0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Jul 7 22:35:17 2011 -0400

    Minor

diff --git a/src/Makefile.am b/src/Makefile.am
index e58bb50..7966dd0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -58,6 +58,7 @@ HBSOURCES += \
 	hb-ot-shape-complex-indic.cc \
 	hb-ot-shape-complex-indic-machine.hh \
 	hb-ot-shape-complex-indic-table.hh \
+	hb-ot-shape-complex-misc.cc \
 	hb-ot-shape-complex-private.hh \
 	hb-ot-shape-private.hh \
 	hb-ot-tag.cc \
diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc
new file mode 100644
index 0000000..92dee49
--- /dev/null
+++ b/src/hb-ot-shape-complex-misc.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2010  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+HB_BEGIN_DECLS
+
+/* TODO Add kana, hangul, and other small sahpers here */
+
+/* When adding trivial shapers, eg. kana, hangul, etc, we can either
+ * add a full shaper enum value for them, or switch on the script in
+ * the default complex shaper.  The former is faster, so I think that's
+ * what we would do, and hence the default complex shaper shall remain
+ * empty.
+ */
+
+void
+_hb_ot_shape_complex_collect_features_default (hb_ot_map_builder_t *map, const hb_segment_properties_t  *props)
+{
+}
+
+void
+_hb_ot_shape_complex_setup_masks_default (hb_ot_map_t *map, hb_buffer_t *buffer)
+{
+}
+
+
+HB_END_DECLS
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index bf79890..93268ba 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -40,7 +40,7 @@ HB_BEGIN_DECLS
 
 
 enum hb_ot_complex_shaper_t {
-  hb_ot_complex_shaper_none,
+  hb_ot_complex_shaper_default,
   hb_ot_complex_shaper_arabic,
   hb_ot_complex_shaper_indic
 };
@@ -104,7 +104,7 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
       return hb_ot_complex_shaper_indic;
 
     default:
-      return hb_ot_complex_shaper_none;
+      return hb_ot_complex_shaper_default;
   }
 }
 
@@ -119,6 +119,7 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
  */
 
 typedef void hb_ot_shape_complex_collect_features_func_t (hb_ot_map_builder_t *map, const hb_segment_properties_t  *props);
+HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_default;
 HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_arabic;
 HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_indic;
 
@@ -128,9 +129,10 @@ hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper,
 				      const hb_segment_properties_t  *props)
 {
   switch (shaper) {
+    default:
+    case hb_ot_complex_shaper_default:	_hb_ot_shape_complex_collect_features_default	(map, props);	return;
     case hb_ot_complex_shaper_arabic:	_hb_ot_shape_complex_collect_features_arabic	(map, props);	return;
     case hb_ot_complex_shaper_indic:	_hb_ot_shape_complex_collect_features_indic	(map, props);	return;
-    case hb_ot_complex_shaper_none:	default:							return;
   }
 }
 
@@ -143,6 +145,7 @@ hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper,
  */
 
 typedef void hb_ot_shape_complex_setup_masks_func_t (hb_ot_map_t *map, hb_buffer_t *buffer);
+HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_default;
 HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_arabic;
 HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_indic;
 
@@ -152,9 +155,10 @@ hb_ot_shape_complex_setup_masks (hb_ot_complex_shaper_t shaper,
 				 hb_buffer_t *buffer)
 {
   switch (shaper) {
+    default:
+    case hb_ot_complex_shaper_default:	_hb_ot_shape_complex_setup_masks_default(map, buffer);	return;
     case hb_ot_complex_shaper_arabic:	_hb_ot_shape_complex_setup_masks_arabic	(map, buffer);	return;
     case hb_ot_complex_shaper_indic:	_hb_ot_shape_complex_setup_masks_indic	(map, buffer);	return;
-    case hb_ot_complex_shaper_none:	default:						return;
   }
 }
 
commit 76f76812ac7cca8ac6935952a2360d5e151480fa
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Jul 7 22:25:25 2011 -0400

    Shuffle code around, remove shape_plan from complex shapers

diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 4cbdde1..3b0bb93 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -151,7 +151,7 @@ static const struct arabic_state_table_entry {
 
 
 void
-_hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_planner_t *planner, const hb_segment_properties_t  *props)
+_hb_ot_shape_complex_collect_features_arabic (hb_ot_map_builder_t *map, const hb_segment_properties_t  *props)
 {
   /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together,
    * then rlig and calt each in their own stage.  This makes IranNastaliq's ALLAH
@@ -163,57 +163,57 @@ _hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_planner_t *planner, co
    * TODO: Add test cases for these two.
    */
 
-  planner->map.add_gsub_pause (NULL, NULL);
+  map->add_gsub_pause (NULL, NULL);
 
   unsigned int num_features = props->script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
   for (unsigned int i = 0; i < num_features; i++)
-    planner->map.add_bool_feature (arabic_syriac_features[i], false);
+    map->add_bool_feature (arabic_syriac_features[i], false);
 
-  planner->map.add_gsub_pause (NULL, NULL);
+  map->add_gsub_pause (NULL, NULL);
 
-  planner->map.add_bool_feature (HB_TAG('r','l','i','g'));
-  planner->map.add_gsub_pause (NULL, NULL);
+  map->add_bool_feature (HB_TAG('r','l','i','g'));
+  map->add_gsub_pause (NULL, NULL);
 
-  planner->map.add_bool_feature (HB_TAG('c','a','l','t'));
-  planner->map.add_gsub_pause (NULL, NULL);
+  map->add_bool_feature (HB_TAG('c','a','l','t'));
+  map->add_gsub_pause (NULL, NULL);
 
   /* ArabicOT spec enables 'cswh' for Arabic where as for basic shaper it's disabled by default. */
-  planner->map.add_bool_feature (HB_TAG('c','s','w','h'));
+  map->add_bool_feature (HB_TAG('c','s','w','h'));
 }
 
 void
-_hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c)
+_hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map, hb_buffer_t *buffer)
 {
-  unsigned int count = c->buffer->len;
+  unsigned int count = buffer->len;
   unsigned int prev = 0, state = 0;
 
   for (unsigned int i = 0; i < count; i++)
   {
-    unsigned int this_type = get_joining_type (c->buffer->info[i].codepoint, (hb_unicode_general_category_t) c->buffer->info[i].general_category());
+    unsigned int this_type = get_joining_type (buffer->info[i].codepoint, (hb_unicode_general_category_t) buffer->info[i].general_category());
 
     if (unlikely (this_type == JOINING_TYPE_T)) {
-      c->buffer->info[i].arabic_shaping_action() = NONE;
+      buffer->info[i].arabic_shaping_action() = NONE;
       continue;
     }
 
     const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
 
     if (entry->prev_action != NONE)
-      c->buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+      buffer->info[prev].arabic_shaping_action() = entry->prev_action;
 
-    c->buffer->info[i].arabic_shaping_action() = entry->curr_action;
+    buffer->info[i].arabic_shaping_action() = entry->curr_action;
 
     prev = i;
     state = entry->next_state;
   }
 
   hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0};
-  unsigned int num_masks = c->buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
+  unsigned int num_masks = buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
   for (unsigned int i = 0; i < num_masks; i++)
-    mask_array[i] = c->plan->map.get_1_mask (arabic_syriac_features[i]);
+    mask_array[i] = map->get_1_mask (arabic_syriac_features[i]);
 
   for (unsigned int i = 0; i < count; i++)
-    c->buffer->info[i].mask |= mask_array[c->buffer->info[i].arabic_shaping_action()];
+    buffer->info[i].mask |= mask_array[buffer->info[i].arabic_shaping_action()];
 }
 
 
diff --git a/src/hb-ot-shape-complex-indic-machine.rl b/src/hb-ot-shape-complex-indic-machine.rl
index e21814d..640d8cb 100644
--- a/src/hb-ot-shape-complex-indic-machine.rl
+++ b/src/hb-ot-shape-complex-indic-machine.rl
@@ -59,12 +59,12 @@ z = ZWJ|ZWNJ;
 matra_group = M N? H?;
 syllable_tail = SM? (VD VD?)?;
 
-action matched_syllable {
-  matched_syllable (c, last, p);
+action found_syllable {
+  found_syllable (map, buffer, last, p);
   last = p;
 }
 
-consonant_syllable =	(c.N? (z.H|H.z?))* c.N? A? (H.z? | matra_group*)? syllable_tail %(matched_syllable);
+consonant_syllable =	(c.N? (z.H|H.z?))* c.N? A? (H.z? | matra_group*)? syllable_tail %(found_syllable);
 vowel_syllable =	(Ra H)? V N? (z.H.c | ZWJ.c)? matra_group* syllable_tail;
 standalone_cluster =	(Ra H)? NBSP N? (z? H c)? matra_group* syllable_tail;
 non_indic = X;
@@ -85,17 +85,17 @@ main := syllable**;
 #include <string.h>
 
 static void
-find_syllables (hb_ot_shape_context_t *c)
+find_syllables (hb_ot_map_t *map, hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof;
   int cs;
   %%{
     write init;
-    getkey c->buffer->info[p].indic_category();
+    getkey buffer->info[p].indic_category();
   }%%
 
   p = 0;
-  pe = eof = c->buffer->len;
+  pe = eof = buffer->len;
 
   unsigned int last = 0;
   %%{
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 8619b56..e3832f4 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -283,20 +283,19 @@ static const hb_tag_t indic_other_features[] =
 
 
 void
-_hb_ot_shape_complex_collect_features_indic (hb_ot_shape_planner_t *planner, const hb_segment_properties_t *props HB_UNUSED)
+_hb_ot_shape_complex_collect_features_indic (hb_ot_map_builder_t *map, const hb_segment_properties_t  *props)
 {
   for (unsigned int i = 0; i < ARRAY_LENGTH (indic_basic_features); i++)
-    planner->map.add_bool_feature (indic_basic_features[i].tag, indic_basic_features[i].is_global);
+    map->add_bool_feature (indic_basic_features[i].tag, indic_basic_features[i].is_global);
 
   for (unsigned int i = 0; i < ARRAY_LENGTH (indic_other_features); i++)
-    planner->map.add_bool_feature (indic_other_features[i], true);
+    map->add_bool_feature (indic_other_features[i], true);
 }
 
 
 static void
-matched_syllable (hb_ot_shape_context_t *c,
-		  unsigned int start,
-		  unsigned int end)
+found_syllable (hb_ot_map_t *map, hb_buffer_t *buffer,
+		unsigned int start, unsigned int end)
 {
   //fprintf (stderr, "%d %d\n", start, end);
 }
@@ -305,24 +304,24 @@ matched_syllable (hb_ot_shape_context_t *c,
 
 
 void
-_hb_ot_shape_complex_setup_masks_indic (hb_ot_shape_context_t *c)
+_hb_ot_shape_complex_setup_masks_indic (hb_ot_map_t *map, hb_buffer_t *buffer)
 {
-  unsigned int count = c->buffer->len;
+  unsigned int count = buffer->len;
 
   for (unsigned int i = 0; i < count; i++)
   {
-    unsigned int type = get_indic_categories (c->buffer->info[i].codepoint);
+    unsigned int type = get_indic_categories (buffer->info[i].codepoint);
 
-    c->buffer->info[i].indic_category() = type & 0x0F;
-    c->buffer->info[i].indic_position() = type >> 4;
+    buffer->info[i].indic_category() = type & 0x0F;
+    buffer->info[i].indic_position() = type >> 4;
   }
 
-  find_syllables (c);
+  find_syllables (map, buffer);
 
   hb_mask_t 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++)
-    mask_array[i] = c->plan->map.get_1_mask (indic_basic_features[i].tag);
+    mask_array[i] = map->get_1_mask (indic_basic_features[i].tag);
 }
 
 
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index 6a837eb..bf79890 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -29,11 +29,22 @@
 
 #include "hb-private.hh"
 
-#include "hb-ot-shape-private.hh"
+#include "hb-ot-map-private.hh"
 
 HB_BEGIN_DECLS
 
 
+/* buffer var allocations, used by all shapers */
+#define general_category() var1.u8[0] /* unicode general_category (hb_unicode_general_category_t) */
+#define combining_class() var1.u8[1] /* unicode combining_class (uint8_t) */
+
+
+enum hb_ot_complex_shaper_t {
+  hb_ot_complex_shaper_none,
+  hb_ot_complex_shaper_arabic,
+  hb_ot_complex_shaper_indic
+};
+
 static inline hb_ot_complex_shaper_t
 hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
 {
@@ -104,21 +115,22 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
  *
  * Called during shape_plan().
  *
- * Shapers should use plan->map to add their features.
+ * Shapers should use map to add their features and callbacks.
  */
 
-typedef void hb_ot_shape_complex_collect_features_func_t (hb_ot_shape_planner_t *plan, const hb_segment_properties_t  *props);
+typedef void hb_ot_shape_complex_collect_features_func_t (hb_ot_map_builder_t *map, const hb_segment_properties_t  *props);
 HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_arabic;
 HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_indic;
 
 static inline void
-hb_ot_shape_complex_collect_features (hb_ot_shape_planner_t *planner,
+hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper,
+				      hb_ot_map_builder_t *map,
 				      const hb_segment_properties_t  *props)
 {
-  switch (planner->shaper) {
-    case hb_ot_complex_shaper_arabic:	_hb_ot_shape_complex_collect_features_arabic	(planner, props);	return;
-    case hb_ot_complex_shaper_indic:	_hb_ot_shape_complex_collect_features_indic	(planner, props);	return;
-    case hb_ot_complex_shaper_none:	default:								return;
+  switch (shaper) {
+    case hb_ot_complex_shaper_arabic:	_hb_ot_shape_complex_collect_features_arabic	(map, props);	return;
+    case hb_ot_complex_shaper_indic:	_hb_ot_shape_complex_collect_features_indic	(map, props);	return;
+    case hb_ot_complex_shaper_none:	default:							return;
   }
 }
 
@@ -127,20 +139,22 @@ hb_ot_shape_complex_collect_features (hb_ot_shape_planner_t *planner,
  *
  * Called during shape_execute().
  *
- * Shapers should use c->plan.map to get feature masks and set on buffer.
+ * Shapers should use map to get feature masks and set on buffer.
  */
 
-typedef void hb_ot_shape_complex_setup_masks_func_t (hb_ot_shape_context_t *c);
+typedef void hb_ot_shape_complex_setup_masks_func_t (hb_ot_map_t *map, hb_buffer_t *buffer);
 HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_arabic;
 HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_indic;
 
 static inline void
-hb_ot_shape_complex_setup_masks (hb_ot_shape_context_t *c)
+hb_ot_shape_complex_setup_masks (hb_ot_complex_shaper_t shaper,
+				 hb_ot_map_t *map,
+				 hb_buffer_t *buffer)
 {
-  switch (c->plan->shaper) {
-    case hb_ot_complex_shaper_arabic:	_hb_ot_shape_complex_setup_masks_arabic (c);	return;
-    case hb_ot_complex_shaper_indic:	_hb_ot_shape_complex_setup_masks_indic (c);	return;
-    case hb_ot_complex_shaper_none:	default:					return;
+  switch (shaper) {
+    case hb_ot_complex_shaper_arabic:	_hb_ot_shape_complex_setup_masks_arabic	(map, buffer);	return;
+    case hb_ot_complex_shaper_indic:	_hb_ot_shape_complex_setup_masks_indic	(map, buffer);	return;
+    case hb_ot_complex_shaper_none:	default:						return;
   }
 }
 
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index f7f1cae..307784d 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -32,21 +32,12 @@
 #include "hb-ot-shape.h"
 
 #include "hb-ot-map-private.hh"
+#include "hb-ot-shape-complex-private.hh"
 
 HB_BEGIN_DECLS
 
 
-/* buffer var allocations */
-#define general_category() var1.u8[0] /* unicode general_category (hb_unicode_general_category_t) */
-#define combining_class() var1.u8[1] /* unicode combining_class (uint8_t) */
-
-
-enum hb_ot_complex_shaper_t {
-  hb_ot_complex_shaper_none,
-  hb_ot_complex_shaper_arabic,
-  hb_ot_complex_shaper_indic
-};
-
+enum hb_ot_complex_shaper_t;
 
 struct hb_ot_shape_plan_t
 {
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 749f273..584ffbd 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -96,7 +96,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
 
   ADD_FEATURES (early_features);
 
-  hb_ot_shape_complex_collect_features (planner, props);
+  hb_ot_shape_complex_collect_features (planner->shaper, &planner->map, props);
 
   ADD_FEATURES (common_features);
 
@@ -120,7 +120,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
   hb_mask_t global_mask = c->plan->map.get_global_mask ();
   c->buffer->reset_masks (global_mask);
 
-  hb_ot_shape_complex_setup_masks (c); /* BUFFER: Clobbers var2 */
+  hb_ot_shape_complex_setup_masks (c->plan->shaper, &c->plan->map, c->buffer); /* BUFFER: Clobbers var2 */
 
   for (unsigned int i = 0; i < c->num_user_features; i++)
   {
commit e88bff9b4d77dc86c04832163081effbff752216
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Jul 7 22:03:02 2011 -0400

    Minor, use function typedefs

diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index 468204e..6a837eb 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -107,8 +107,9 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
  * Shapers should use plan->map to add their features.
  */
 
-HB_INTERNAL void _hb_ot_shape_complex_collect_features_arabic	(hb_ot_shape_planner_t *plan, const hb_segment_properties_t  *props);
-HB_INTERNAL void _hb_ot_shape_complex_collect_features_indic	(hb_ot_shape_planner_t *plan, const hb_segment_properties_t  *props);
+typedef void hb_ot_shape_complex_collect_features_func_t (hb_ot_shape_planner_t *plan, const hb_segment_properties_t  *props);
+HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_arabic;
+HB_INTERNAL hb_ot_shape_complex_collect_features_func_t _hb_ot_shape_complex_collect_features_indic;
 
 static inline void
 hb_ot_shape_complex_collect_features (hb_ot_shape_planner_t *planner,
@@ -129,8 +130,9 @@ hb_ot_shape_complex_collect_features (hb_ot_shape_planner_t *planner,
  * Shapers should use c->plan.map to get feature masks and set on buffer.
  */
 
-HB_INTERNAL void _hb_ot_shape_complex_setup_masks_arabic	(hb_ot_shape_context_t *c);
-HB_INTERNAL void _hb_ot_shape_complex_setup_masks_indic		(hb_ot_shape_context_t *c);
+typedef void hb_ot_shape_complex_setup_masks_func_t (hb_ot_shape_context_t *c);
+HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_arabic;
+HB_INTERNAL hb_ot_shape_complex_setup_masks_func_t _hb_ot_shape_complex_setup_masks_indic;
 
 static inline void
 hb_ot_shape_complex_setup_masks (hb_ot_shape_context_t *c)
commit 359dcaa0d33271025ca42a5f54ecbac7ae3b56d3
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Jul 7 21:55:05 2011 -0400

    Update copyright headers

diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index a66049f..84b4ccf 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2009,2010  Red Hat, Inc.
- * Copyright © 2010  Google, Inc.
+ * Copyright © 2010,2011  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 9bd4e0f..67035ba 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2009,2010  Red Hat, Inc.
- * Copyright © 2010  Google, Inc.
+ * Copyright © 2010,2011  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index a7a1afb..468204e 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2010  Google, Inc.
+ * Copyright © 2010,2011  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 6bda700..749f273 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2009,2010  Red Hat, Inc.
- * Copyright © 2010  Google, Inc.
+ * Copyright © 2010,2011  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *



More information about the HarfBuzz mailing list