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

Behdad Esfahbod behdad at kemper.freedesktop.org
Tue Aug 9 01:38:26 PDT 2011


 TODO                        |    4 -
 src/hb-blob.cc              |    5 -
 src/hb-blob.h               |    3 
 src/hb-buffer.cc            |   17 ++--
 src/hb-buffer.h             |   15 ++-
 src/hb-common.cc            |   13 ++-
 src/hb-font-private.hh      |    9 +-
 src/hb-font.cc              |  100 ++++++++++++++++++-------
 src/hb-font.h               |   34 ++++++--
 src/hb-ft.cc                |   10 +-
 src/hb-object-private.hh    |   13 ++-
 src/hb-ot-layout-private.hh |    9 --
 src/hb-ot-layout.cc         |   23 -----
 src/hb-private.hh           |   16 ++--
 src/hb-shape.cc             |   78 ++++++++------------
 src/hb-unicode.cc           |    5 -
 src/hb-unicode.h            |    3 
 src/hb-uniscribe-shape.cc   |  170 +++++++++++++++++++++++++++++++++-----------
 src/main.cc                 |    1 
 test/Makefile.am            |    8 ++
 test/test-c.c               |   10 +-
 test/test-object.c          |   33 ++++----
 22 files changed, 357 insertions(+), 222 deletions(-)

New commits:
commit 255f176fdcd42ab94f9c3c54e2bffb55d0b1a8f5
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Aug 9 08:35:07 2011 +0200

    Minor

diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc
index 7962f3a..a0020ca 100644
--- a/src/hb-uniscribe-shape.cc
+++ b/src/hb-uniscribe-shape.cc
@@ -92,7 +92,7 @@ populate_log_font (LOGFONTW  *lf,
 }
 
 
-static struct hb_uniscribe_face_data_t{
+static struct hb_uniscribe_face_data_t {
   HANDLE fh;
 } _hb_uniscribe_face_data_nil = {0};
 
commit a9057eb3f38018faa1ece53c4aaeeba798b41fd1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Aug 9 00:47:55 2011 +0200

    [uniscribe] Unbreak

diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc
index b3653e7..7962f3a 100644
--- a/src/hb-uniscribe-shape.cc
+++ b/src/hb-uniscribe-shape.cc
@@ -219,11 +219,11 @@ hb_uniscribe_shape (hb_font_t          *font,
   } HB_STMT_END;
 
   hb_uniscribe_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face);
-  if (unlikely (!face_data))
+  if (unlikely (!face_data->fh))
     FAIL ("Couldn't get face data");
 
   hb_uniscribe_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
-  if (unlikely (!font_data))
+  if (unlikely (!font_data->hfont))
     FAIL ("Couldn't get font font");
 
   if (unlikely (!buffer->len))
commit c0975e12315b7167b92411584d2f00a751bbc204
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Aug 9 00:46:18 2011 +0200

    Fix build again

diff --git a/test/Makefile.am b/test/Makefile.am
index 9e22b1f..07f3ccf 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -58,6 +58,9 @@ endif
 if HAVE_FREETYPE
 test_object_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS)
 test_object_LDADD = $(LDADD) $(FREETYPE_LIBS)
+else
+test_object_CPPFLAGS = $(AM_CPPFLAGS)
+test_object_LDADD = $(LDADD)
 endif
 
 
commit 33ccc77902660ed4b49184e5ec99f4fd0ef63175
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Aug 9 00:43:24 2011 +0200

    [API] Make set_user_data() functions take a replace parameter
    
    We need this to set data on objects safely without worrying that some
    other thread unsets it by setting it at the same time.

diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index 7ed3812..58d7324 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -165,9 +165,10 @@ hb_bool_t
 hb_blob_set_user_data (hb_blob_t          *blob,
 		       hb_user_data_key_t *key,
 		       void *              data,
-		       hb_destroy_func_t   destroy)
+		       hb_destroy_func_t   destroy,
+		       hb_bool_t           replace)
 {
-  return hb_object_set_user_data (blob, key, data, destroy);
+  return hb_object_set_user_data (blob, key, data, destroy, replace);
 }
 
 void *
diff --git a/src/hb-blob.h b/src/hb-blob.h
index f2eaae9..50c9ae3 100644
--- a/src/hb-blob.h
+++ b/src/hb-blob.h
@@ -66,7 +66,8 @@ hb_bool_t
 hb_blob_set_user_data (hb_blob_t          *blob,
 		       hb_user_data_key_t *key,
 		       void *              data,
-		       hb_destroy_func_t   destroy);
+		       hb_destroy_func_t   destroy,
+		       hb_bool_t           replace);
 
 
 void *
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index e0c86f5..3be3f44 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -532,9 +532,10 @@ hb_bool_t
 hb_buffer_set_user_data (hb_buffer_t        *buffer,
 			 hb_user_data_key_t *key,
 			 void *              data,
-			 hb_destroy_func_t   destroy)
+			 hb_destroy_func_t   destroy,
+			 hb_bool_t           replace)
 {
-  return hb_object_set_user_data (buffer, key, data, destroy);
+  return hb_object_set_user_data (buffer, key, data, destroy, replace);
 }
 
 void *
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index a43a8d1..a5efce3 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -75,7 +75,8 @@ hb_bool_t
 hb_buffer_set_user_data (hb_buffer_t        *buffer,
 			 hb_user_data_key_t *key,
 			 void *              data,
-			 hb_destroy_func_t   destroy);
+			 hb_destroy_func_t   destroy,
+			 hb_bool_t           replace);
 
 void *
 hb_buffer_get_user_data (hb_buffer_t        *buffer,
diff --git a/src/hb-common.cc b/src/hb-common.cc
index afbe941..48382ca 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -301,17 +301,20 @@ static hb_static_mutex_t user_data_lock;
 bool
 hb_user_data_array_t::set (hb_user_data_key_t *key,
 			   void *              data,
-			   hb_destroy_func_t   destroy)
+			   hb_destroy_func_t   destroy,
+			   hb_bool_t           replace)
 {
   if (!key)
     return false;
 
-  if (!data && !destroy) {
-    items.remove (key, user_data_lock);
-    return true;
+  if (replace) {
+    if (!data && !destroy) {
+      items.remove (key, user_data_lock);
+      return true;
+    }
   }
   hb_user_data_item_t item = {key, data, destroy};
-  bool ret = !!items.replace_or_insert (item, user_data_lock);
+  bool ret = !!items.replace_or_insert (item, user_data_lock, replace);
 
   return ret;
 }
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 4be2a2e..d3fbcbe 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -248,9 +248,10 @@ hb_bool_t
 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
 			     hb_user_data_key_t *key,
 			     void *              data,
-			     hb_destroy_func_t   destroy)
+			     hb_destroy_func_t   destroy,
+			     hb_bool_t           replace)
 {
-  return hb_object_set_user_data (ffuncs, key, data, destroy);
+  return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
 }
 
 void *
@@ -667,9 +668,10 @@ hb_bool_t
 hb_face_set_user_data (hb_face_t          *face,
 		       hb_user_data_key_t *key,
 		       void *              data,
-		       hb_destroy_func_t   destroy)
+		       hb_destroy_func_t   destroy,
+		       hb_bool_t           replace)
 {
-  return hb_object_set_user_data (face, key, data, destroy);
+  return hb_object_set_user_data (face, key, data, destroy, replace);
 }
 
 void *
@@ -852,9 +854,10 @@ hb_bool_t
 hb_font_set_user_data (hb_font_t          *font,
 		       hb_user_data_key_t *key,
 		       void *              data,
-		       hb_destroy_func_t   destroy)
+		       hb_destroy_func_t   destroy,
+		       hb_bool_t           replace)
 {
-  return hb_object_set_user_data (font, key, data, destroy);
+  return hb_object_set_user_data (font, key, data, destroy, replace);
 }
 
 void *
diff --git a/src/hb-font.h b/src/hb-font.h
index 7f8cd5e..363ab55 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -65,7 +65,8 @@ hb_bool_t
 hb_face_set_user_data (hb_face_t          *face,
 		       hb_user_data_key_t *key,
 		       void *              data,
-		       hb_destroy_func_t   destroy);
+		       hb_destroy_func_t   destroy,
+		       hb_bool_t           replace);
 
 
 void *
@@ -123,7 +124,8 @@ hb_bool_t
 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
 			     hb_user_data_key_t *key,
 			     void *              data,
-			     hb_destroy_func_t   destroy);
+			     hb_destroy_func_t   destroy,
+			     hb_bool_t           replace);
 
 
 void *
@@ -338,7 +340,8 @@ hb_bool_t
 hb_font_set_user_data (hb_font_t          *font,
 		       hb_user_data_key_t *key,
 		       void *              data,
-		       hb_destroy_func_t   destroy);
+		       hb_destroy_func_t   destroy,
+		       hb_bool_t           replace);
 
 
 void *
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index c0a7bbe..adaa6e8 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -122,7 +122,8 @@ struct hb_user_data_array_t {
 
   HB_INTERNAL bool set (hb_user_data_key_t *key,
 			void *              data,
-			hb_destroy_func_t   destroy);
+			hb_destroy_func_t   destroy,
+			hb_bool_t           replace);
 
   HB_INTERNAL void *get (hb_user_data_key_t *key);
 
@@ -178,11 +179,12 @@ struct _hb_object_header_t {
 
   inline bool set_user_data (hb_user_data_key_t *key,
 			     void *              data,
-			     hb_destroy_func_t   destroy_func) {
+			     hb_destroy_func_t   destroy_func,
+			     hb_bool_t           replace) {
     if (unlikely (!this || this->is_inert ()))
       return false;
 
-    return user_data.set (key, data, destroy_func);
+    return user_data.set (key, data, destroy_func, replace);
   }
 
   inline void *get_user_data (hb_user_data_key_t *key) {
@@ -237,9 +239,10 @@ template <typename Type>
 static inline bool hb_object_set_user_data (Type               *obj,
 					    hb_user_data_key_t *key,
 					    void *              data,
-					    hb_destroy_func_t   destroy)
+					    hb_destroy_func_t   destroy,
+					    hb_bool_t           replace)
 {
-  return obj->header.set_user_data (key, data, destroy);
+  return obj->header.set_user_data (key, data, destroy, replace);
 }
 
 template <typename Type>
diff --git a/src/hb-private.hh b/src/hb-private.hh
index b2ef802..413becd 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -343,15 +343,21 @@ struct hb_lockable_set_t
   hb_array_t <item_t> items;
 
   template <typename T>
-  inline item_t *replace_or_insert (T v, lock_t &l)
+  inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
   {
     l.lock ();
     item_t *item = items.find (v);
     if (item) {
-      item_t old = *item;
-      *item = v;
-      l.unlock ();
-      old.finish ();
+      if (replace) {
+	item_t old = *item;
+	*item = v;
+	l.unlock ();
+	old.finish ();
+      }
+      else {
+        item = NULL;
+	l.unlock ();
+      }
     } else {
       item = items.push ();
       if (likely (item))
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 4202302..9a4ebfe 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -76,7 +76,7 @@ static struct static_shaper_list_t
           end = p + strlen (p);
 
 	for (unsigned int j = i; j < ARRAY_LENGTH (shapers); j++)
-	  if (end - p == strlen (shapers[j].name) &&
+	  if (end - p == (int) strlen (shapers[j].name) &&
 	      0 == strncmp (shapers[j].name, p, end - p))
 	  {
 	    /* Reorder this shaper to position i */
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index 2286f7b..4b285c5 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -175,9 +175,10 @@ hb_bool_t
 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
 			        hb_user_data_key_t *key,
 			        void *              data,
-			        hb_destroy_func_t   destroy)
+			        hb_destroy_func_t   destroy,
+				hb_bool_t           replace)
 {
-  return hb_object_set_user_data (ufuncs, key, data, destroy);
+  return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
 }
 
 void *
diff --git a/src/hb-unicode.h b/src/hb-unicode.h
index 9aa97a6..13886df 100644
--- a/src/hb-unicode.h
+++ b/src/hb-unicode.h
@@ -66,7 +66,8 @@ hb_bool_t
 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
 			        hb_user_data_key_t *key,
 			        void *              data,
-			        hb_destroy_func_t   destroy);
+			        hb_destroy_func_t   destroy,
+				hb_bool_t           replace);
 
 
 void *
diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc
index fa29cde..b3653e7 100644
--- a/src/hb-uniscribe-shape.cc
+++ b/src/hb-uniscribe-shape.cc
@@ -129,10 +129,15 @@ _hb_uniscribe_face_get_data (hb_face_t *face)
     DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed");
 
   if (unlikely (!hb_face_set_user_data (face, &uniscribe_face_data_key, data,
-					(hb_destroy_func_t) _hb_uniscribe_face_data_destroy)))
+					(hb_destroy_func_t) _hb_uniscribe_face_data_destroy,
+					FALSE)))
   {
     _hb_uniscribe_face_data_destroy (data);
-    return &_hb_uniscribe_face_data_nil;
+    data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &uniscribe_face_data_key);
+    if (data)
+      return data;
+    else
+      return &_hb_uniscribe_face_data_nil;
   }
 
   return data;
@@ -183,10 +188,15 @@ _hb_uniscribe_font_get_data (hb_font_t *font)
   }
 
   if (unlikely (!hb_font_set_user_data (font, &uniscribe_font_data_key, data,
-					(hb_destroy_func_t) _hb_uniscribe_font_data_destroy)))
+					(hb_destroy_func_t) _hb_uniscribe_font_data_destroy,
+					FALSE)))
   {
     _hb_uniscribe_font_data_destroy (data);
-    return &_hb_uniscribe_font_data_nil;
+    data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &uniscribe_font_data_key);
+    if (data)
+      return data;
+    else
+      return &_hb_uniscribe_font_data_nil;
   }
 
   return data;
diff --git a/test/test-object.c b/test/test-object.c
index d0145c5..07cf158 100644
--- a/test/test-object.c
+++ b/test/test-object.c
@@ -116,7 +116,7 @@ create_unicode_funcs_inert (void)
 typedef void     *(*create_func_t)         (void);
 typedef void     *(*reference_func_t)      (void *obj);
 typedef void      (*destroy_func_t)        (void *obj);
-typedef hb_bool_t (*set_user_data_func_t)  (void *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy);
+typedef hb_bool_t (*set_user_data_func_t)  (void *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy, hb_bool_t replace);
 typedef void *    (*get_user_data_func_t)  (void *obj, hb_user_data_key_t *key);
 typedef void      (*make_immutable_func_t) (void *obj);
 typedef hb_bool_t (*is_immutable_func_t)   (void *obj);
@@ -247,7 +247,7 @@ test_object (void)
       if (o->is_immutable)
 	g_assert (!o->is_immutable (obj));
 
-      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0));
+      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
       g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
 
       if (o->is_immutable) {
@@ -256,38 +256,39 @@ test_object (void)
       }
 
       /* Should still work even if object is made immutable */
-      g_assert (o->set_user_data (obj, &key[1], &data[1], free_up1));
+      g_assert (o->set_user_data (obj, &key[1], &data[1], free_up1, TRUE));
       g_assert (o->get_user_data (obj, &key[1]) == &data[1]);
 
-      g_assert (!o->set_user_data (obj, NULL, &data[0], free_up0));
+      g_assert (!o->set_user_data (obj, NULL, &data[0], free_up0, TRUE));
       g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
-      g_assert (o->set_user_data (obj, &key[0], &data[1], NULL));
+      g_assert (o->set_user_data (obj, &key[0], &data[1], NULL, TRUE));
       g_assert (data[0].freed);
       g_assert (o->get_user_data (obj, &key[0]) == &data[1]);
       g_assert (!data[1].freed);
 
       data[0].freed = FALSE;
-      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0));
+      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
       g_assert (!data[0].freed);
-      g_assert (o->set_user_data (obj, &key[0], NULL, NULL));
+      g_assert (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
       g_assert (data[0].freed);
 
       data[0].freed = FALSE;
       global_data = 0;
-      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0));
+      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
+      g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, FALSE));
       g_assert_cmpuint (global_data, ==, 0);
-      g_assert (o->set_user_data (obj, &key[0], NULL, global_free_up));
+      g_assert (o->set_user_data (obj, &key[0], NULL, global_free_up, TRUE));
       g_assert_cmpuint (global_data, ==, 0);
-      g_assert (o->set_user_data (obj, &key[0], NULL, NULL));
+      g_assert (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
       g_assert_cmpuint (global_data, ==, 1);
 
       global_data = 0;
       for (j = 2; j < 1000; j++)
-	g_assert (o->set_user_data (obj, &key[j], &data[j], global_free_up));
+	g_assert (o->set_user_data (obj, &key[j], &data[j], global_free_up, TRUE));
       for (j = 2; j < 1000; j++)
 	g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
       for (j = 100; j < 1000; j++)
-	g_assert (o->set_user_data (obj, &key[j], NULL, NULL));
+	g_assert (o->set_user_data (obj, &key[j], NULL, NULL, TRUE));
       for (j = 2; j < 100; j++)
 	g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
       for (j = 100; j < 1000; j++)
@@ -298,8 +299,8 @@ test_object (void)
        * Make sure it doesn't deadlock or corrupt memory. */
       deadlock_test.klass = o;
       deadlock_test.object = obj;
-      g_assert (o->set_user_data (obj, &deadlock_test.key, &deadlock_test, free_deadlock_test));
-      g_assert (o->set_user_data (obj, &deadlock_test.key, NULL, NULL));
+      g_assert (o->set_user_data (obj, &deadlock_test.key, &deadlock_test, free_deadlock_test, TRUE));
+      g_assert (o->set_user_data (obj, &deadlock_test.key, NULL, NULL, TRUE));
 
       g_assert (!data[1].freed);
       o->destroy (obj);
@@ -321,7 +322,7 @@ test_object (void)
       if (o->is_immutable)
 	g_assert (o->is_immutable (obj));
 
-      g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0));
+      g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
       g_assert (!o->get_user_data (obj, &key[0]));
 
       o->destroy (obj);
@@ -349,7 +350,7 @@ test_object (void)
       if (o->is_immutable)
 	g_assert (o->is_immutable (obj));
 
-      g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0));
+      g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
       g_assert (!o->get_user_data (obj, &key[0]));
 
       o->destroy (obj);
commit 944b2ba1ce076385f985212bbdf2df96a8a995f0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Aug 9 00:23:58 2011 +0200

    [buffer] Make API take signed int length
    
    Since we already switched to accepting -1 as 'zero-terminated'.

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 53b3200..e0c86f5 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -776,9 +776,9 @@ hb_utf8_next (const uint8_t *text,
 void
 hb_buffer_add_utf8 (hb_buffer_t  *buffer,
 		    const char   *text,
-		    unsigned int  text_length HB_UNUSED,
+		    int           text_length,
 		    unsigned int  item_offset,
-		    unsigned int  item_length)
+		    int           item_length)
 {
 #define UTF_NEXT(S, E, U)	hb_utf8_next (S, E, &(U))
   ADD_UTF (uint8_t);
@@ -810,9 +810,9 @@ hb_utf16_next (const uint16_t *text,
 void
 hb_buffer_add_utf16 (hb_buffer_t    *buffer,
 		     const uint16_t *text,
-		     unsigned int    text_length HB_UNUSED,
+		     int             text_length,
 		     unsigned int    item_offset,
-		     unsigned int    item_length)
+		     int            item_length)
 {
 #define UTF_NEXT(S, E, U)	hb_utf16_next (S, E, &(U))
   ADD_UTF (uint16_t);
@@ -822,9 +822,9 @@ hb_buffer_add_utf16 (hb_buffer_t    *buffer,
 void
 hb_buffer_add_utf32 (hb_buffer_t    *buffer,
 		     const uint32_t *text,
-		     unsigned int    text_length HB_UNUSED,
+		     int             text_length,
 		     unsigned int    item_offset,
-		     unsigned int    item_length)
+		     int             item_length)
 {
 #define UTF_NEXT(S, E, U)	((U) = *(S), (S)+1)
   ADD_UTF (uint32_t);
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index 1c4a9a7..a43a8d1 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -147,23 +147,23 @@ hb_buffer_add (hb_buffer_t    *buffer,
 void
 hb_buffer_add_utf8 (hb_buffer_t  *buffer,
 		    const char   *text,
-		    unsigned int  text_length,
+		    int           text_length,
 		    unsigned int  item_offset,
-		    unsigned int  item_length);
+		    int           item_length);
 
 void
 hb_buffer_add_utf16 (hb_buffer_t    *buffer,
 		     const uint16_t *text,
-		     unsigned int    text_length,
+		     int             text_length,
 		     unsigned int    item_offset,
-		     unsigned int    item_length);
+		     int             item_length);
 
 void
 hb_buffer_add_utf32 (hb_buffer_t    *buffer,
 		     const uint32_t *text,
-		     unsigned int    text_length,
+		     int             text_length,
 		     unsigned int    item_offset,
-		     unsigned int    item_length);
+		     int             item_length);
 
 
 /* Clears any new items added at the end */
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index d5829b0..b05e494 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -26,8 +26,6 @@
  * Red Hat Author(s): Behdad Esfahbod
  */
 
-#define HB_OT_LAYOUT_CC
-
 #include "hb-ot-layout-private.hh"
 
 #include "hb-ot-layout-gdef-private.hh"
diff --git a/src/main.cc b/src/main.cc
index 6fd5e1e..e13a40d 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -24,7 +24,6 @@
  * Red Hat Author(s): Behdad Esfahbod
  */
 
-#define HB_OT_LAYOUT_CC
 #include "hb-mutex-private.hh"
 #include "hb-open-file-private.hh"
 #include "hb-ot-layout-gdef-private.hh"
commit de1e1cf9bccfd116d495804e230dc2e12b733a2d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Aug 9 00:19:38 2011 +0200

    [FT] Adapt to new face API

diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 953f0a6..7152805 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -293,6 +293,9 @@ hb_ft_face_create (FT_Face           ft_face,
     face = hb_face_create_for_tables (reference_table, ft_face, destroy);
   }
 
+  hb_face_set_index (face, ft_face->face_index);
+  hb_face_set_upem (face, ft_face->units_per_EM);
+
   return face;
 }
 
commit 458c89a85695220d43b69dbae36fc93e3fe78d89
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Aug 9 00:19:19 2011 +0200

    Minor

diff --git a/test/test-c.c b/test/test-c.c
index e72db27..7e7c502 100644
--- a/test/test-c.c
+++ b/test/test-c.c
@@ -31,23 +31,23 @@
 
 #include <hb.h>
 
-#if HAVE_GLIB
+#ifdef HAVE_GLIB
 #include <hb-glib.h>
 #endif
 
-#if HAVE_ICU
+#ifdef HAVE_ICU
 #include <hb-icu.h>
 #endif
 
-#if HAVE_FREETYPE
+#ifdef HAVE_FREETYPE
 #include <hb-ft.h>
 #endif
 
-#if HAVE_OT
+#ifdef HAVE_OT
 #include <hb-ot.h>
 #endif
 
-#if HAVE_UNISCRIBE
+#ifdef HAVE_UNISCRIBE
 #include <hb-uniscribe.h>
 #endif
 
commit bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Aug 9 00:13:24 2011 +0200

    [uniscribe] Cleanup backend

diff --git a/TODO b/TODO
index 917f131..81a0afb 100644
--- a/TODO
+++ b/TODO
@@ -29,6 +29,8 @@ API issues to fix before 1.0:
 API to add (maybe after 1.0):
 ============================
 
+- Add Uniscribe face / font get API
+
 - BCP 47 language handling / API (language_matches?)
 
 - Add hb_face_get_glyph_count()?
diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc
index 4315d34..fa29cde 100644
--- a/src/hb-uniscribe-shape.cc
+++ b/src/hb-uniscribe-shape.cc
@@ -91,6 +91,108 @@ populate_log_font (LOGFONTW  *lf,
   return TRUE;
 }
 
+
+static struct hb_uniscribe_face_data_t{
+  HANDLE fh;
+} _hb_uniscribe_face_data_nil = {0};
+
+static hb_user_data_key_t uniscribe_face_data_key;
+
+static void
+_hb_uniscribe_face_data_destroy (hb_uniscribe_face_data_t *data)
+{
+  if (data->fh)
+    RemoveFontMemResourceEx (data->fh);
+  free (data);
+}
+
+static hb_uniscribe_face_data_t *
+_hb_uniscribe_face_get_data (hb_face_t *face)
+{
+  hb_uniscribe_face_data_t *data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &uniscribe_face_data_key);
+  if (likely (data)) return data;
+
+  data = (hb_uniscribe_face_data_t *) calloc (1, sizeof (hb_uniscribe_face_data_t));
+  if (unlikely (!data))
+    return &_hb_uniscribe_face_data_nil;
+
+  hb_blob_t *blob = hb_face_reference_blob (face);
+  unsigned int blob_length;
+  const char *blob_data = hb_blob_get_data (blob, &blob_length);
+  if (unlikely (!blob_length))
+    DEBUG_MSG (UNISCRIBE, face, "Face has empty blob");
+
+  DWORD num_fonts_installed;
+  data->fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed);
+  hb_blob_destroy (blob);
+  if (unlikely (!data->fh))
+    DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed");
+
+  if (unlikely (!hb_face_set_user_data (face, &uniscribe_face_data_key, data,
+					(hb_destroy_func_t) _hb_uniscribe_face_data_destroy)))
+  {
+    _hb_uniscribe_face_data_destroy (data);
+    return &_hb_uniscribe_face_data_nil;
+  }
+
+  return data;
+}
+
+
+static struct hb_uniscribe_font_data_t {
+  HDC hdc;
+  HFONT hfont;
+  SCRIPT_CACHE script_cache;
+} _hb_uniscribe_font_data_nil = {NULL, NULL, NULL};
+
+static hb_user_data_key_t uniscribe_font_data_key;
+
+static void
+_hb_uniscribe_font_data_destroy (hb_uniscribe_font_data_t *data)
+{
+  if (data->hdc)
+    ReleaseDC (NULL, data->hdc);
+  if (data->hfont)
+    DeleteObject (data->hfont);
+  if (data->script_cache)
+    ScriptFreeCache (&data->script_cache);
+  free (data);
+}
+
+static hb_uniscribe_font_data_t *
+_hb_uniscribe_font_get_data (hb_font_t *font)
+{
+  hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &uniscribe_font_data_key);
+  if (likely (data)) return data;
+
+  data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t));
+  if (unlikely (!data))
+    return &_hb_uniscribe_font_data_nil;
+
+  data->hdc = GetDC (NULL);
+
+  LOGFONTW log_font;
+  if (unlikely (!populate_log_font (&log_font, data->hdc, font)))
+    DEBUG_MSG (UNISCRIBE, font, "Font populate_log_font() failed");
+  else {
+    data->hfont = CreateFontIndirectW (&log_font);
+    if (unlikely (!data->hfont))
+      DEBUG_MSG (UNISCRIBE, font, "Font CreateFontIndirectW() failed");
+    if (!SelectObject (data->hdc, data->hfont))
+      DEBUG_MSG (UNISCRIBE, font, "Font SelectObject() failed");
+  }
+
+  if (unlikely (!hb_font_set_user_data (font, &uniscribe_font_data_key, data,
+					(hb_destroy_func_t) _hb_uniscribe_font_data_destroy)))
+  {
+    _hb_uniscribe_font_data_destroy (data);
+    return &_hb_uniscribe_font_data_nil;
+  }
+
+  return data;
+}
+
+
 hb_bool_t
 hb_uniscribe_shape (hb_font_t          *font,
 		    hb_buffer_t        *buffer,
@@ -100,11 +202,25 @@ hb_uniscribe_shape (hb_font_t          *font,
 {
   buffer->guess_properties ();
 
-  HRESULT hr;
+#define FAIL(...) \
+  HB_STMT_START { \
+    DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \
+    return FALSE; \
+  } HB_STMT_END;
+
+  hb_uniscribe_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face);
+  if (unlikely (!face_data))
+    FAIL ("Couldn't get face data");
+
+  hb_uniscribe_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
+  if (unlikely (!font_data))
+    FAIL ("Couldn't get font font");
 
   if (unlikely (!buffer->len))
     return TRUE;
 
+  HRESULT hr;
+
 retry:
 
   unsigned int scratch_size;
@@ -152,13 +268,6 @@ retry:
   ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size);
 
 
-#define FAIL(...) \
-  HB_STMT_START { \
-    DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \
-    return FALSE; \
-  } HB_STMT_END;
-
-
 #define MAX_ITEMS 10
 
   SCRIPT_ITEM items[MAX_ITEMS + 1];
@@ -189,30 +298,6 @@ retry:
     /* XXX setup ranges */
   }
 
-  hb_blob_t *blob = hb_face_reference_blob (font->face);
-  unsigned int blob_length;
-  const char *blob_data = hb_blob_get_data (blob, &blob_length);
-  if (unlikely (!blob_length))
-    FAIL ("Empty font blob");
-
-  DWORD num_fonts_installed;
-  HANDLE fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed);
-  hb_blob_destroy (blob);
-  if (unlikely (!fh))
-    FAIL ("AddFontMemResourceEx() failed");
-
-  /* FREE stuff, specially when taking fallback... */
-
-  HDC hdc = GetDC (NULL); /* XXX The DC should be cached on the face I guess? */
-
-  LOGFONTW log_font;
-  if (unlikely (!populate_log_font (&log_font, hdc, font)))
-    FAIL ("populate_log_font() failed");
-
-  HFONT hfont = CreateFontIndirectW (&log_font);
-  SelectObject (hdc, hfont);
-
-  SCRIPT_CACHE script_cache = NULL;
   OPENTYPE_TAG language_tag = hb_ot_tag_from_language (buffer->props.language);
 
   unsigned int glyphs_offset = 0;
@@ -223,8 +308,8 @@ retry:
       unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset;
       OPENTYPE_TAG script_tag = script_tags[i]; /* XXX buffer->props.script */
 
-      hr = ScriptShapeOpenType (hdc,
-				&script_cache,
+      hr = ScriptShapeOpenType (font_data->hdc,
+				&font_data->script_cache,
 				&items[i].a,
 				script_tag,
 				language_tag,
@@ -255,8 +340,8 @@ retry:
       if (unlikely (FAILED (hr)))
 	FAIL ("ScriptShapeOpenType() failed: 0x%08xL", hr);
 
-      hr = ScriptPlaceOpenType (hdc,
-				&script_cache,
+      hr = ScriptPlaceOpenType (font_data->hdc,
+				&font_data->script_cache,
 				&items[i].a,
 				script_tag,
 				language_tag,
@@ -281,10 +366,6 @@ retry:
   }
   glyphs_len = glyphs_offset;
 
-  ReleaseDC (NULL, hdc);
-  DeleteObject (hfont);
-  RemoveFontMemResourceEx (fh);
-
   /* Ok, we've got everything we need, now compose output buffer,
    * very, *very*, carefully! */
 
commit f1f848e2e46ac54ff08aca7cd83390af31c7c9ef
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Aug 8 23:41:06 2011 +0200

    Fix build

diff --git a/test/Makefile.am b/test/Makefile.am
index b3c8cc2..9e22b1f 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -55,6 +55,11 @@ test_shape_complex_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS)
 test_shape_complex_LDADD = $(LDADD) $(FREETYPE_LIBS)
 endif
 
+if HAVE_FREETYPE
+test_object_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS)
+test_object_LDADD = $(LDADD) $(FREETYPE_LIBS)
+endif
+
 
 # Default test running environment
 TESTS = $(TEST_PROGS)
commit 3897335c7620c37e9a0224b0c42ade0dfdce4053
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Aug 8 23:37:41 2011 +0200

    [API] Sort out get_blob API
    
    hb_face_get_blob() renamed to hb_face_reference_blob(), returns a
    reference now.
    
    hb_face_[sg]et_index() added.
    
    hb_face_set_upem() added.

diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index 06a5bc4..d896e72 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -94,6 +94,7 @@ struct _hb_face_t {
 
   struct hb_ot_layout_t *ot_layout;
 
+  unsigned int index;
   unsigned int upem;
 };
 
@@ -154,7 +155,7 @@ struct _hb_font_t {
 
 
   private:
-  inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / this->face->upem; }
+  inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / hb_face_get_upem (this->face); }
 };
 
 
diff --git a/src/hb-font.cc b/src/hb-font.cc
index c795c8a..4be2a2e 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -31,6 +31,7 @@
 #include "hb-font-private.hh"
 #include "hb-blob.h"
 #include "hb-open-file-private.hh"
+#include "hb-ot-head-private.hh"
 
 #include <string.h>
 
@@ -538,7 +539,8 @@ static hb_face_t _hb_face_nil = {
 
   NULL, /* ot_layout */
 
-  1000
+  0,    /* index */
+  1000  /* upem */
 };
 
 
@@ -561,7 +563,7 @@ hb_face_create_for_tables (hb_reference_table_func_t  reference_table,
 
   face->ot_layout = _hb_ot_layout_create (face);
 
-  face->upem = _hb_ot_layout_get_upem (face);
+  face->upem = 0;
 
   return face;
 }
@@ -599,6 +601,9 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
 {
   hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data;
 
+  if (tag == HB_TAG_NONE)
+    return hb_blob_reference (data->blob);
+
   const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance (data->blob);
   const OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
 
@@ -613,6 +618,8 @@ hb_face_t *
 hb_face_create (hb_blob_t    *blob,
 		unsigned int  index)
 {
+  hb_face_t *face;
+
   if (unlikely (!blob || !hb_blob_get_length (blob)))
     return &_hb_face_nil;
 
@@ -621,9 +628,13 @@ hb_face_create (hb_blob_t    *blob,
   if (unlikely (!closure))
     return &_hb_face_nil;
 
-  return hb_face_create_for_tables (_hb_face_for_data_reference_table,
+  face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
 				    closure,
 				    (hb_destroy_func_t) _hb_face_for_data_closure_destroy);
+
+  hb_face_set_index (face, index);
+
+  return face;
 }
 
 hb_face_t *
@@ -685,16 +696,6 @@ hb_face_is_immutable (hb_face_t *face)
 
 
 hb_blob_t *
-hb_face_get_blob (hb_face_t *face)
-{
-  if (face->destroy != (hb_destroy_func_t) _hb_face_for_data_closure_destroy)
-    return hb_blob_get_empty ();
-
-  hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data;
-  return data->blob;
-}
-
-hb_blob_t *
 hb_face_reference_table (hb_face_t *face,
 			 hb_tag_t   tag)
 {
@@ -710,10 +711,48 @@ hb_face_reference_table (hb_face_t *face,
   return blob;
 }
 
+hb_blob_t *
+hb_face_reference_blob (hb_face_t *face)
+{
+  return hb_face_reference_table (face, HB_TAG_NONE);
+}
+
+void
+hb_face_set_index (hb_face_t    *face,
+		   unsigned int  index)
+{
+  if (hb_object_is_inert (face))
+    return;
+
+  face->index = 0;
+}
+
+unsigned int
+hb_face_get_index (hb_face_t    *face)
+{
+  return face->index;
+}
+
+void
+hb_face_set_upem (hb_face_t    *face,
+		  unsigned int  upem)
+{
+  if (hb_object_is_inert (face))
+    return;
+
+  face->upem = upem;
+}
+
 unsigned int
 hb_face_get_upem (hb_face_t *face)
 {
-  return _hb_ot_layout_get_upem (face);
+  if (unlikely (!face->upem)) {
+    hb_blob_t *head_blob = Sanitizer<head>::sanitize (hb_face_reference_table (face, HB_OT_TAG_head));
+    const head *head_table = Sanitizer<head>::lock_instance (head_blob);
+    face->upem = head_table->get_upem ();
+    hb_blob_destroy (head_blob);
+  }
+  return face->upem;
 }
 
 
diff --git a/src/hb-font.h b/src/hb-font.h
index 187c156..7f8cd5e 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -80,12 +80,23 @@ hb_face_is_immutable (hb_face_t *face);
 
 
 hb_blob_t *
-hb_face_get_blob (hb_face_t *face);
-
-hb_blob_t *
 hb_face_reference_table (hb_face_t *face,
 			 hb_tag_t   tag);
 
+hb_blob_t *
+hb_face_reference_blob (hb_face_t *face);
+
+void
+hb_face_set_index (hb_face_t    *face,
+		   unsigned int  index);
+
+unsigned int
+hb_face_get_index (hb_face_t    *face);
+
+void
+hb_face_set_upem (hb_face_t    *face,
+		  unsigned int  upem);
+
 unsigned int
 hb_face_get_upem (hb_face_t *face);
 
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index e757524..953f0a6 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -250,8 +250,7 @@ reference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
   FT_ULong  length = 0;
   FT_Error error;
 
-  if (unlikely (tag == HB_TAG_NONE))
-    return NULL;
+  /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */
 
   error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length);
   if (error)
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 1f6e20b..bf7e43b 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -70,13 +70,6 @@ _hb_ot_layout_skip_mark (hb_face_t    *face,
 			 unsigned int *property_out);
 
 
-/*
- * head
- */
-
-HB_INTERNAL unsigned int
-_hb_ot_layout_get_upem (hb_face_t    *face);
-
 
 /*
  * hb_ot_layout_t
@@ -87,12 +80,10 @@ struct hb_ot_layout_t
   hb_blob_t *gdef_blob;
   hb_blob_t *gsub_blob;
   hb_blob_t *gpos_blob;
-  hb_blob_t *head_blob;
 
   const struct GDEF *gdef;
   const struct GSUB *gsub;
   const struct GPOS *gpos;
-  const struct head *head;
 };
 
 
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index ceae824..d5829b0 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -33,7 +33,6 @@
 #include "hb-ot-layout-gdef-private.hh"
 #include "hb-ot-layout-gsub-private.hh"
 #include "hb-ot-layout-gpos-private.hh"
-#include "hb-ot-head-private.hh"
 #include "hb-ot-maxp-private.hh"
 
 
@@ -57,9 +56,6 @@ _hb_ot_layout_create (hb_face_t *face)
   layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GPOS));
   layout->gpos = Sanitizer<GPOS>::lock_instance (layout->gpos_blob);
 
-  layout->head_blob = Sanitizer<head>::sanitize (hb_face_reference_table (face, HB_OT_TAG_head));
-  layout->head = Sanitizer<head>::lock_instance (layout->head_blob);
-
   return layout;
 }
 
@@ -69,7 +65,6 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
   hb_blob_destroy (layout->gdef_blob);
   hb_blob_destroy (layout->gsub_blob);
   hb_blob_destroy (layout->gpos_blob);
-  hb_blob_destroy (layout->head_blob);
 
   free (layout);
 }
@@ -89,11 +84,6 @@ _get_gpos (hb_face_t *face)
 {
   return likely (face->ot_layout && face->ot_layout->gpos) ? *face->ot_layout->gpos : Null(GPOS);
 }
-static inline const head&
-_get_head (hb_face_t *face)
-{
-  return likely (face->ot_layout && face->ot_layout->head) ? *face->ot_layout->head : Null(head);
-}
 
 
 /*
@@ -505,14 +495,3 @@ hb_ot_layout_position_finish (hb_buffer_t  *buffer)
 }
 
 
-/*
- * head
- */
-
-unsigned int
-_hb_ot_layout_get_upem (hb_face_t *face)
-{
-  return _get_head (face).get_upem ();
-}
-
-
diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc
index 82ef648..4315d34 100644
--- a/src/hb-uniscribe-shape.cc
+++ b/src/hb-uniscribe-shape.cc
@@ -189,7 +189,7 @@ retry:
     /* XXX setup ranges */
   }
 
-  hb_blob_t *blob = hb_face_get_blob (font->face);
+  hb_blob_t *blob = hb_face_reference_blob (font->face);
   unsigned int blob_length;
   const char *blob_data = hb_blob_get_data (blob, &blob_length);
   if (unlikely (!blob_length))
@@ -197,6 +197,7 @@ retry:
 
   DWORD num_fonts_installed;
   HANDLE fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed);
+  hb_blob_destroy (blob);
   if (unlikely (!fh))
     FAIL ("AddFontMemResourceEx() failed");
 
commit e715784be35f0846c0e084b7c53c7556ce933a45
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Aug 8 21:42:02 2011 +0200

    Rename get_table to reference_table in all API

diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index 76024fd..06a5bc4 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -88,9 +88,9 @@ struct _hb_face_t {
 
   hb_bool_t immutable;
 
-  hb_get_table_func_t  get_table;
-  void                *user_data;
-  hb_destroy_func_t    destroy;
+  hb_reference_table_func_t  reference_table;
+  void                      *user_data;
+  hb_destroy_func_t          destroy;
 
   struct hb_ot_layout_t *ot_layout;
 
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 3c5e802..c795c8a 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -532,7 +532,7 @@ static hb_face_t _hb_face_nil = {
 
   TRUE, /* immutable */
 
-  NULL, /* get_table */
+  NULL, /* reference_table */
   NULL, /* user_data */
   NULL, /* destroy */
 
@@ -543,19 +543,19 @@ static hb_face_t _hb_face_nil = {
 
 
 hb_face_t *
-hb_face_create_for_tables (hb_get_table_func_t  get_table,
-			   void                *user_data,
-			   hb_destroy_func_t    destroy)
+hb_face_create_for_tables (hb_reference_table_func_t  reference_table,
+			   void                      *user_data,
+			   hb_destroy_func_t          destroy)
 {
   hb_face_t *face;
 
-  if (!get_table || !(face = hb_object_create<hb_face_t> ())) {
+  if (!reference_table || !(face = hb_object_create<hb_face_t> ())) {
     if (destroy)
       destroy (user_data);
     return &_hb_face_nil;
   }
 
-  face->get_table = get_table;
+  face->reference_table = reference_table;
   face->user_data = user_data;
   face->destroy = destroy;
 
@@ -595,7 +595,7 @@ _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
 }
 
 static hb_blob_t *
-_hb_face_for_data_get_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+_hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
 {
   hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data;
 
@@ -621,7 +621,7 @@ hb_face_create (hb_blob_t    *blob,
   if (unlikely (!closure))
     return &_hb_face_nil;
 
-  return hb_face_create_for_tables (_hb_face_for_data_get_table,
+  return hb_face_create_for_tables (_hb_face_for_data_reference_table,
 				    closure,
 				    (hb_destroy_func_t) _hb_face_for_data_closure_destroy);
 }
@@ -700,10 +700,10 @@ hb_face_reference_table (hb_face_t *face,
 {
   hb_blob_t *blob;
 
-  if (unlikely (!face || !face->get_table))
+  if (unlikely (!face || !face->reference_table))
     return hb_blob_get_empty ();
 
-  blob = face->get_table (face, tag, face->user_data);
+  blob = face->reference_table (face, tag, face->user_data);
   if (unlikely (!blob))
     return hb_blob_get_empty ();
 
diff --git a/src/hb-font.h b/src/hb-font.h
index 2675c6e..187c156 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -44,13 +44,13 @@ hb_face_t *
 hb_face_create (hb_blob_t    *blob,
 		unsigned int  index);
 
-typedef hb_blob_t * (*hb_get_table_func_t)  (hb_face_t *face, hb_tag_t tag, void *user_data);
+typedef hb_blob_t * (*hb_reference_table_func_t)  (hb_face_t *face, hb_tag_t tag, void *user_data);
 
 /* calls destroy() when not needing user_data anymore */
 hb_face_t *
-hb_face_create_for_tables (hb_get_table_func_t  get_table,
-			   void                *user_data,
-			   hb_destroy_func_t    destroy);
+hb_face_create_for_tables (hb_reference_table_func_t  reference_table,
+			   void                      *user_data,
+			   hb_destroy_func_t          destroy);
 
 hb_face_t *
 hb_face_get_empty (void);
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 7e0c19b..e757524 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -243,7 +243,7 @@ hb_ft_get_font_funcs (void)
 
 
 static hb_blob_t *
-get_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+reference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
 {
   FT_Face ft_face = (FT_Face) user_data;
   FT_Byte *buffer;
@@ -291,7 +291,7 @@ hb_ft_face_create (FT_Face           ft_face,
     face = hb_face_create (blob, ft_face->face_index);
     hb_blob_destroy (blob);
   } else {
-    face = hb_face_create_for_tables (get_table, ft_face, destroy);
+    face = hb_face_create_for_tables (reference_table, ft_face, destroy);
   }
 
   return face;
commit 670c873499f7f03fdfc07b8a0567b041628c6ab0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Aug 8 21:36:24 2011 +0200

    Fix shaper ordering logic

diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 02d29bd..4202302 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -45,8 +45,8 @@ typedef hb_bool_t (*hb_shape_func_t) (hb_font_t          *font,
 				      const char         *shaper_options);
 
 #define HB_SHAPER_IMPLEMENT(name) {#name, hb_##name##_shape}
-static const struct hb_shaper_pair_t {
-  const char name[16];
+static struct hb_shaper_pair_t {
+  char name[16];
   hb_shape_func_t func;
 } shapers[] = {
   /* v--- Add new shapers in the right place here */
@@ -65,49 +65,42 @@ static struct static_shaper_list_t
   static_shaper_list_t (void)
   {
     char *env = getenv ("HB_SHAPER_LIST");
-    shaper_list = NULL;
-    if (!env || !*env) {
-    fallback:
-      ASSERT_STATIC ((ARRAY_LENGTH (shapers) + 1) * sizeof (*shaper_list) <= sizeof (static_buffer));
-      shaper_list = (const char **) static_buffer;
-      unsigned int i;
-      for (i = 0; i < ARRAY_LENGTH (shapers); i++)
-        shaper_list[i] = shapers[i].name;
-      shaper_list[i] = NULL;
-      return;
+    if (env && *env)
+    {
+       /* Reorder shaper list to prefer requested shaper list. */
+      unsigned int i = 0;
+      char *end, *p = env;
+      for (;;) {
+        end = strchr (p, ',');
+        if (!end)
+          end = p + strlen (p);
+
+	for (unsigned int j = i; j < ARRAY_LENGTH (shapers); j++)
+	  if (end - p == strlen (shapers[j].name) &&
+	      0 == strncmp (shapers[j].name, p, end - p))
+	  {
+	    /* Reorder this shaper to position i */
+	   struct hb_shaper_pair_t t = shapers[j];
+	   memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
+	   shapers[i] = t;
+	   i++;
+	  }
+
+        if (!*end)
+          break;
+        else
+          p = end + 1;
+      }
     }
 
-    unsigned int count = 3; /* initial, fallback, null */
-    for (const char *p = env; (p = strchr (p, ',')) && p++; )
-      count++;
-
-    unsigned int len = strlen (env);
-
-    if (count > 100 || len > 1000)
-      goto fallback;
-
-    len += count * sizeof (*shaper_list) + 1;
-    char *buffer = len < sizeof (static_buffer) ? static_buffer : (char *) malloc (len);
-    shaper_list = (const char **) buffer;
-    buffer += count * sizeof (*shaper_list);
-    len -= count * sizeof (*shaper_list);
-    strncpy (buffer, env, len);
-
-    count = 0;
-    shaper_list[count++] = buffer;
-    for (char *p = buffer; (p = strchr (p, ',')) && (*p = '\0', TRUE) && p++; )
-      shaper_list[count++] = p;
-    shaper_list[count++] = "fallback";
-    shaper_list[count] = NULL;
-  }
-  ~static_shaper_list_t (void)
-  {
-    if ((char *) shaper_list != static_buffer)
-      free (shaper_list);
+    ASSERT_STATIC ((ARRAY_LENGTH (shapers) + 1) * sizeof (*shaper_list) <= sizeof (shaper_list));
+    unsigned int i;
+    for (i = 0; i < ARRAY_LENGTH (shapers); i++)
+      shaper_list[i] = shapers[i].name;
+    shaper_list[i] = NULL;
   }
 
-  const char **shaper_list;
-  char static_buffer[32];
+  const char *shaper_list[ARRAY_LENGTH (shapers) + 1];
 } static_shaper_list;
 
 const char **
@@ -124,11 +117,6 @@ hb_shape_full (hb_font_t           *font,
 	       const char          *shaper_options,
 	       const char         **shaper_list)
 {
-  /* TODO
-   * This function, and shaper_list handling need to be redone. */
-  if (likely (!shaper_list))
-    shaper_list = static_shaper_list.shaper_list;
-
   if (likely (!shaper_list)) {
     for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
       if (likely (shapers[i].func (font, buffer,
commit cc797e0d5368b2f5732d77eb3e3882283bd87cf7
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Aug 8 03:49:30 2011 +0200

    Minor

diff --git a/TODO b/TODO
index 577843f..917f131 100644
--- a/TODO
+++ b/TODO
@@ -41,8 +41,6 @@ API to add (maybe after 1.0):
 
 - SFNT api? get_num_faces? get_table_tags? (there's something in stash)
 
-- Full matrix instead of scale?
-
 - Add segmentation API
 
 - Add hb-fribidi?
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 7833a39..02d29bd 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -124,6 +124,8 @@ hb_shape_full (hb_font_t           *font,
 	       const char          *shaper_options,
 	       const char         **shaper_list)
 {
+  /* TODO
+   * This function, and shaper_list handling need to be redone. */
   if (likely (!shaper_list))
     shaper_list = static_shaper_list.shaper_list;
 



More information about the HarfBuzz mailing list