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

Behdad Esfahbod behdad at kemper.freedesktop.org
Wed Jun 6 00:39:36 PDT 2012


 configure.ac                       |   38 ++++++---
 src/Makefile.am                    |    3 
 src/hb-atomic-private.hh           |   39 ++++++++-
 src/hb-blob.cc                     |   61 +++++++-------
 src/hb-buffer-private.hh           |    4 
 src/hb-buffer.cc                   |   74 +++++++++--------
 src/hb-buffer.h                    |    4 
 src/hb-common.cc                   |   89 ++++++++++++++-------
 src/hb-fallback-shape.cc           |    2 
 src/hb-font-private.hh             |    3 
 src/hb-font.cc                     |   90 ++++++++++-----------
 src/hb-ft.cc                       |   83 +++++++++++--------
 src/hb-glib.cc                     |   22 ++---
 src/hb-graphite2.cc                |    8 -
 src/hb-icu.cc                      |   37 ++++----
 src/hb-mutex-private.hh            |   77 +++++++++++-------
 src/hb-object-private.hh           |   45 +++++++---
 src/hb-open-type-private.hh        |   32 ++++---
 src/hb-ot-layout.cc                |   28 +++---
 src/hb-ot-shape-complex-indic.cc   |   50 +++++++++--
 src/hb-ot-shape-complex-private.hh |    2 
 src/hb-ot-shape-normalize.cc       |   16 +--
 src/hb-ot-shape.cc                 |    4 
 src/hb-private.hh                  |   57 +++++++++----
 src/hb-set-private.hh              |    5 -
 src/hb-set.cc                      |   18 ++--
 src/hb-set.h                       |    2 
 src/hb-shape.cc                    |  156 ++++++++++++++++++++++++++-----------
 src/hb-tt-font.cc                  |   12 +-
 src/hb-unicode-private.hh          |    6 -
 src/hb-unicode.cc                  |   42 +++++----
 src/hb-uniscribe.cc                |   18 ++--
 src/hb-warning.cc                  |   14 +--
 src/indic.cc                       |    2 
 src/main.cc                        |    2 
 util/hb-shape.cc                   |    2 
 util/helper-cairo.cc               |   16 +--
 util/main-font-text.hh             |    2 
 util/options.cc                    |   58 ++++++-------
 util/options.hh                    |    2 
 util/view-cairo.hh                 |    4 
 41 files changed, 749 insertions(+), 480 deletions(-)

New commits:
commit 6220e5fc0dad728e67a92e838d3ac275d032f2c7
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Jun 6 03:30:09 2012 -0400

    Add ASSERT_POD for most objects

diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index f90f97e..3cc2d9d 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -48,6 +48,7 @@
 
 struct _hb_blob_t {
   hb_object_header_t header;
+  ASSERT_POD ();
 
   bool immutable;
 
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index fb1c801..b539f26 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -44,11 +44,13 @@ typedef struct _hb_segment_properties_t {
     hb_direction_t      direction;
     hb_script_t         script;
     hb_language_t       language;
+    ASSERT_POD ();
 } hb_segment_properties_t;
 
 
 struct _hb_buffer_t {
   hb_object_header_t header;
+  ASSERT_POD ();
 
   /* Information about how the text in the buffer should be treated */
 
diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index e10e105..91a4304 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -56,6 +56,7 @@
 
 struct _hb_font_funcs_t {
   hb_object_header_t header;
+  ASSERT_POD ();
 
   hb_bool_t immutable;
 
@@ -87,6 +88,7 @@ struct _hb_font_funcs_t {
 
 struct _hb_face_t {
   hb_object_header_t header;
+  ASSERT_POD ();
 
   hb_bool_t immutable;
 
@@ -107,6 +109,7 @@ struct _hb_face_t {
 
 struct _hb_font_t {
   hb_object_header_t header;
+  ASSERT_POD ();
 
   hb_bool_t immutable;
 
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index e86a38d..96d1bd3 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -173,6 +173,8 @@ struct hb_object_header_t
 	       this ? ref_count.ref_count : 0);
   }
 
+  private:
+  ASSERT_POD ();
 };
 
 
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 8f821f2..2ea0442 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -122,7 +122,7 @@ ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
 /* Check _assertion in a method environment */
 #define _ASSERT_POD1(_line) \
   inline void _static_assertion_on_line_##_line (void) const \
-  { _ASSERT_INSTANCE_POD1 (*this); /* Make sure it's POD. */ }
+  { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
 # define _ASSERT_POD0(_line) _ASSERT_POD1 (_line)
 # define ASSERT_POD() _ASSERT_POD0 (__LINE__)
 
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
index b8407e9..5cdf8a0 100644
--- a/src/hb-set-private.hh
+++ b/src/hb-set-private.hh
@@ -36,6 +36,9 @@
 
 struct _hb_set_t
 {
+  hb_object_header_t header;
+  ASSERT_POD ();
+
   inline void init (void) {
     header.init ();
     clear ();
@@ -158,7 +161,6 @@ struct _hb_set_t
   elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
   elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
 
-  hb_object_header_t header;
   elt_t elts[ELTS]; /* XXX 8kb */
 
   ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index 7f719c4..8a34174 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -63,6 +63,7 @@
 
 struct _hb_unicode_funcs_t {
   hb_object_header_t header;
+  ASSERT_POD ();
 
   hb_unicode_funcs_t *parent;
 
commit a00a63b5ef503fafa87e26b517732b2214e01719
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Jun 6 03:07:01 2012 -0400

    Add macros to check that types are POD

diff --git a/configure.ac b/configure.ac
index 2fb058f..51a3597 100644
--- a/configure.ac
+++ b/configure.ac
@@ -137,6 +137,7 @@ PKG_CHECK_MODULES(ICU, icu, have_icu=true, [
 		AC_SUBST(ICU_LIBS)
 	fi
 ])
+have_icu=false
 if $have_icu; then
 	AC_DEFINE(HAVE_ICU, 1, [Have ICU library])
 fi
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index f4a2ba9..5d90e5b 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -80,17 +80,25 @@ inline Type& StructAfter(TObject &X)
  */
 
 /* Check _assertion in a method environment */
-#define _DEFINE_SIZE_ASSERTION(_assertion) \
-  inline void _size_assertion (void) const \
-  { ASSERT_STATIC (_assertion); }
+#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
+  inline void _instance_assertion_on_line_##_line (void) const \
+  { \
+    ASSERT_STATIC (_assertion); \
+    ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
+  }
+# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
+# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
+
 /* Check that _code compiles in a method environment */
-#define _DEFINE_COMPILES_ASSERTION(_code) \
-  inline void _compiles_assertion (void) const \
+#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
+  inline void _compiles_assertion_on_line_##_line (void) const \
   { _code; }
+# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
+# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
 
 
 #define DEFINE_SIZE_STATIC(size) \
-  _DEFINE_SIZE_ASSERTION (sizeof (*this) == (size)); \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
   static const unsigned int static_size = (size); \
   static const unsigned int min_size = (size)
 
@@ -98,21 +106,21 @@ inline Type& StructAfter(TObject &X)
 #define VAR 1
 
 #define DEFINE_SIZE_UNION(size, _member) \
-  _DEFINE_SIZE_ASSERTION (this->u._member.static_size == (size)); \
+  DEFINE_INSTANCE_ASSERTION (this->u._member.static_size == (size)); \
   static const unsigned int min_size = (size)
 
 #define DEFINE_SIZE_MIN(size) \
-  _DEFINE_SIZE_ASSERTION (sizeof (*this) >= (size)); \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
   static const unsigned int min_size = (size)
 
 #define DEFINE_SIZE_ARRAY(size, array) \
-  _DEFINE_SIZE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
-  _DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
+  DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
   static const unsigned int min_size = (size)
 
 #define DEFINE_SIZE_ARRAY2(size, array1, array2) \
-  _DEFINE_SIZE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
-  _DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
+  DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
   static const unsigned int min_size = (size)
 
 
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 44b7314..8f821f2 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -104,6 +104,30 @@ ASSERT_STATIC (sizeof (hb_position_t) == 4);
 ASSERT_STATIC (sizeof (hb_mask_t) == 4);
 ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
 
+
+/* We like our types POD */
+
+#define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
+#define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type)
+#define ASSERT_TYPE_POD(_type) _ASSERT_TYPE_POD0 (__LINE__, _type)
+
+#ifdef __GNUC__
+# define _ASSERT_INSTANCE_POD1(_line, _instance) union _type_of_instance_on_line_##_line##_is_not_POD { __typeof__(_instance) instance; }
+#else
+# define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_on_line_##_line##_not_tested
+#endif
+# define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_line, _instance)
+# define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (__LINE__, _instance)
+
+/* Check _assertion in a method environment */
+#define _ASSERT_POD1(_line) \
+  inline void _static_assertion_on_line_##_line (void) const \
+  { _ASSERT_INSTANCE_POD1 (*this); /* Make sure it's POD. */ }
+# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line)
+# define ASSERT_POD() _ASSERT_POD0 (__LINE__)
+
+
+
 /* Misc */
 
 
commit 61eb60c129e865e92f6a5767a88c44a391f4d413
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 21:14:04 2012 -0400

    Don't link to libstdc++
    
    New try.

diff --git a/src/Makefile.am b/src/Makefile.am
index a50a199..344cc57 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -137,7 +137,8 @@ HBSOURCES += hb-uniscribe.cc hb-uniscribe-private.hh
 HBHEADERS += hb-uniscribe.h
 endif
 
-CXXLINK = $(LINK)
+# Use a C linker, not C++; Don't link to libstdc++
+libharfbuzz_la_LINK = $(LINK) $(libharfbuzz_la_LDFLAGS)
 libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS)
 nodist_libharfbuzz_la_SOURCES = $(nodist_HBSOURCES)
 libharfbuzz_la_CPPFLAGS = $(HBCFLAGS)
commit 81a4b9fd4eb8995c5930db1df3669db93661eb52
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 20:49:51 2012 -0400

    Remove unused hb_static_mutex_t

diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh
index a6d16e9..f9bd679 100644
--- a/src/hb-mutex-private.hh
+++ b/src/hb-mutex-private.hh
@@ -137,15 +137,4 @@ struct hb_mutex_t
 };
 
 
-struct hb_static_mutex_t : hb_mutex_t
-{
-  hb_static_mutex_t (void)  { this->init (); }
-  ~hb_static_mutex_t (void) { this->finish (); }
-
-  private:
-  NO_COPY (hb_static_mutex_t);
-};
-
-
-
 #endif /* HB_MUTEX_PRIVATE_HH */
commit 4a3a9897b3698dd09c3e880b3ddd4db24c6fb460
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 20:39:07 2012 -0400

    Disable Intel atomic ops on mingw32
    
    Apparently the configure test is not enough...

diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh
index 918852d..c543a8d 100644
--- a/src/hb-atomic-private.hh
+++ b/src/hb-atomic-private.hh
@@ -65,7 +65,7 @@ typedef int32_t hb_atomic_int_t;
 #define hb_atomic_ptr_cmpexch(P,O,N)	OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
 
 
-#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
+#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) && !defined(__MINGW32__)
 
 typedef int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	__sync_fetch_and_add (&(AI), (V))
commit 0594a2448440208efa0acac9a5d8d52d43108289
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 20:35:40 2012 -0400

    Cleanup TRUE/FALSE vs true/false

diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh
index 0e7ecae..918852d 100644
--- a/src/hb-atomic-private.hh
+++ b/src/hb-atomic-private.hh
@@ -94,7 +94,7 @@ typedef volatile int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
 
 #define hb_atomic_ptr_get(P)		((void *) *(P))
-#define hb_atomic_ptr_cmpexch(P,O,N)	(* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), TRUE) : FALSE)
+#define hb_atomic_ptr_cmpexch(P,O,N)	(* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
 
 
 #else /* HB_NO_MT */
@@ -103,7 +103,7 @@ typedef int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
 
 #define hb_atomic_ptr_get(P)		((void *) *(P))
-#define hb_atomic_ptr_cmpexch(P,O,N)	(* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), TRUE) : FALSE)
+#define hb_atomic_ptr_cmpexch(P,O,N)	(* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
 
 #endif
 
diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index 04de762..f90f97e 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -132,7 +132,7 @@ hb_blob_get_empty (void)
   static const hb_blob_t _hb_blob_nil = {
     HB_OBJECT_HEADER_STATIC,
 
-    TRUE, /* immutable */
+    true, /* immutable */
 
     NULL, /* data */
     0, /* length */
@@ -185,7 +185,7 @@ hb_blob_make_immutable (hb_blob_t *blob)
   if (hb_object_is_inert (blob))
     return;
 
-  blob->immutable = TRUE;
+  blob->immutable = true;
 }
 
 hb_bool_t
@@ -244,7 +244,7 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 
   if ((uintptr_t) -1L == pagesize) {
     DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno));
-    return FALSE;
+    return false;
   }
   DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize);
 
@@ -256,7 +256,7 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 		  addr, addr+length, (unsigned long) length);
   if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
     DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno));
-    return FALSE;
+    return false;
   }
 
   blob->mode = HB_MEMORY_MODE_WRITABLE;
@@ -264,9 +264,9 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
   DEBUG_MSG_FUNC (BLOB, blob,
 		  "successfully made [%p..%p] (%lu bytes) writable\n",
 		  addr, addr+length, (unsigned long) length);
-  return TRUE;
+  return true;
 #else
-  return FALSE;
+  return false;
 #endif
 }
 
@@ -276,29 +276,29 @@ _try_writable_inplace (hb_blob_t *blob)
   DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n");
 
   if (_try_make_writable_inplace_unix (blob))
-    return TRUE;
+    return true;
 
   DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n");
 
   /* Failed to make writable inplace, mark that */
   blob->mode = HB_MEMORY_MODE_READONLY;
-  return FALSE;
+  return false;
 }
 
 static bool
 _try_writable (hb_blob_t *blob)
 {
   if (blob->immutable)
-    return FALSE;
+    return false;
 
   if (blob->mode == HB_MEMORY_MODE_WRITABLE)
-    return TRUE;
+    return true;
 
   if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob))
-    return TRUE;
+    return true;
 
   if (blob->mode == HB_MEMORY_MODE_WRITABLE)
-    return TRUE;
+    return true;
 
 
   DEBUG_MSG_FUNC (BLOB, blob, "current data is -> %p\n", blob->data);
@@ -307,7 +307,7 @@ _try_writable (hb_blob_t *blob)
 
   new_data = (char *) malloc (blob->length);
   if (unlikely (!new_data))
-    return FALSE;
+    return false;
 
   DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data);
 
@@ -318,7 +318,7 @@ _try_writable (hb_blob_t *blob)
   blob->user_data = new_data;
   blob->destroy = free;
 
-  return TRUE;
+  return true;
 }
 
 
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index e9e0f82..fb1c801 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -149,7 +149,7 @@ struct _hb_buffer_t {
   HB_INTERNAL bool enlarge (unsigned int size);
 
   inline bool ensure (unsigned int size)
-  { return likely (size <= allocated) ? TRUE : enlarge (size); }
+  { return likely (size <= allocated) ? true : enlarge (size); }
 
   HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
 
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index c27cc15..e2c34f1 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -66,7 +66,7 @@ bool
 hb_buffer_t::enlarge (unsigned int size)
 {
   if (unlikely (in_error))
-    return FALSE;
+    return false;
 
   unsigned int new_allocated = allocated;
   hb_glyph_position_t *new_pos = NULL;
@@ -88,7 +88,7 @@ hb_buffer_t::enlarge (unsigned int size)
 
 done:
   if (unlikely (!new_pos || !new_info))
-    in_error = TRUE;
+    in_error = true;
 
   if (likely (new_pos))
     pos = new_pos;
@@ -107,7 +107,7 @@ bool
 hb_buffer_t::make_room_for (unsigned int num_in,
 			    unsigned int num_out)
 {
-  if (unlikely (!ensure (out_len + num_out))) return FALSE;
+  if (unlikely (!ensure (out_len + num_out))) return false;
 
   if (out_info == info &&
       out_len + num_out > idx + num_in)
@@ -118,14 +118,14 @@ hb_buffer_t::make_room_for (unsigned int num_in,
     memcpy (out_info, info, out_len * sizeof (out_info[0]));
   }
 
-  return TRUE;
+  return true;
 }
 
 void *
 hb_buffer_t::get_scratch_buffer (unsigned int *size)
 {
-  have_output = FALSE;
-  have_positions = FALSE;
+  have_output = false;
+  have_positions = false;
   out_len = 0;
   *size = allocated * sizeof (pos[0]);
   return pos;
@@ -146,9 +146,9 @@ hb_buffer_t::reset (void)
   hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT;
   props = default_props;
 
-  in_error = FALSE;
-  have_output = FALSE;
-  have_positions = FALSE;
+  in_error = false;
+  have_output = false;
+  have_positions = false;
 
   idx = 0;
   len = 0;
@@ -186,8 +186,8 @@ hb_buffer_t::clear_output (void)
   if (unlikely (hb_object_is_inert (this)))
     return;
 
-  have_output = TRUE;
-  have_positions = FALSE;
+  have_output = true;
+  have_positions = false;
 
   out_len = 0;
   out_info = info;
@@ -199,8 +199,8 @@ hb_buffer_t::clear_positions (void)
   if (unlikely (hb_object_is_inert (this)))
     return;
 
-  have_output = FALSE;
-  have_positions = TRUE;
+  have_output = false;
+  have_positions = true;
 
   memset (pos, 0, sizeof (pos[0]) * len);
 }
@@ -211,7 +211,7 @@ hb_buffer_t::swap_buffers (void)
   if (unlikely (in_error)) return;
 
   assert (have_output);
-  have_output = FALSE;
+  have_output = false;
 
   if (out_info != info)
   {
@@ -547,9 +547,9 @@ hb_buffer_get_empty (void)
     _HB_BUFFER_UNICODE_FUNCS_DEFAULT,
     _HB_BUFFER_PROPS_DEFAULT,
 
-    TRUE, /* in_error */
-    TRUE, /* have_output */
-    TRUE  /* have_positions */
+    true, /* in_error */
+    true, /* have_output */
+    true  /* have_positions */
   };
 
   return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
@@ -698,7 +698,7 @@ hb_buffer_set_length (hb_buffer_t  *buffer,
     return length == 0;
 
   if (!buffer->ensure (length))
-    return FALSE;
+    return false;
 
   /* Wipe the new space */
   if (length > buffer->len) {
@@ -708,7 +708,7 @@ hb_buffer_set_length (hb_buffer_t  *buffer,
   }
 
   buffer->len = length;
-  return TRUE;
+  return true;
 }
 
 unsigned int
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index ca1bbf4..fe53197 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -121,13 +121,13 @@ hb_buffer_get_language (hb_buffer_t *buffer);
 void
 hb_buffer_reset (hb_buffer_t *buffer);
 
-/* Returns FALSE if allocation failed */
+/* Returns false if allocation failed */
 hb_bool_t
 hb_buffer_pre_allocate (hb_buffer_t  *buffer,
 		        unsigned int  size);
 
 
-/* Returns FALSE if allocation has failed before */
+/* Returns false if allocation has failed before */
 hb_bool_t
 hb_buffer_allocation_successful (hb_buffer_t  *buffer);
 
diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc
index 20ea43e..5939887 100644
--- a/src/hb-fallback-shape.cc
+++ b/src/hb-fallback-shape.cc
@@ -57,5 +57,5 @@ _hb_fallback_shape (hb_font_t          *font,
   if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
     hb_buffer_reverse (buffer);
 
-  return TRUE;
+  return true;
 }
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 783a2b0..109caff 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -55,7 +55,7 @@ hb_font_get_glyph_nil (hb_font_t *font,
     return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph);
 
   *glyph = 0;
-  return FALSE;
+  return false;
 }
 
 static hb_position_t
@@ -98,7 +98,7 @@ hb_font_get_glyph_h_origin_nil (hb_font_t *font,
   }
 
   *x = *y = 0;
-  return FALSE;
+  return false;
 }
 
 static hb_bool_t
@@ -117,7 +117,7 @@ hb_font_get_glyph_v_origin_nil (hb_font_t *font,
   }
 
   *x = *y = 0;
-  return FALSE;
+  return false;
 }
 
 static hb_position_t
@@ -165,7 +165,7 @@ hb_font_get_glyph_extents_nil (hb_font_t *font,
   }
 
   memset (extents, 0, sizeof (*extents));
-  return FALSE;
+  return false;
 }
 
 static hb_bool_t
@@ -185,7 +185,7 @@ hb_font_get_glyph_contour_point_nil (hb_font_t *font,
   }
 
   *x = *y = 0;
-  return FALSE;
+  return false;
 }
 
 static hb_bool_t
@@ -199,7 +199,7 @@ hb_font_get_glyph_name_nil (hb_font_t *font,
     return hb_font_get_glyph_name (font->parent, glyph, name, size);
 
   snprintf (name, size, "gid%u", glyph);
-  return FALSE;
+  return false;
 }
 
 static hb_bool_t
@@ -213,14 +213,14 @@ hb_font_get_glyph_from_name_nil (hb_font_t *font,
     return hb_font_get_glyph_from_name (font->parent, name, len, glyph);
 
   *glyph = 0;
-  return FALSE;
+  return false;
 }
 
 
 static const hb_font_funcs_t _hb_font_funcs_nil = {
   HB_OBJECT_HEADER_STATIC,
 
-  TRUE, /* immutable */
+  true, /* immutable */
 
   {
 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
@@ -292,7 +292,7 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
   if (hb_object_is_inert (ffuncs))
     return;
 
-  ffuncs->immutable = TRUE;
+  ffuncs->immutable = true;
 }
 
 hb_bool_t
@@ -581,7 +581,7 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
 static const hb_face_t _hb_face_nil = {
   HB_OBJECT_HEADER_STATIC,
 
-  TRUE, /* immutable */
+  true, /* immutable */
 
   NULL, /* reference_table */
   NULL, /* user_data */
@@ -858,7 +858,7 @@ hb_font_get_empty (void)
   static const hb_font_t _hb_font_nil = {
     HB_OBJECT_HEADER_STATIC,
 
-    TRUE, /* immutable */
+    true, /* immutable */
 
     NULL, /* parent */
     const_cast<hb_face_t *> (&_hb_face_nil),
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 20fb32e..0589c9e 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -81,7 +81,7 @@ hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
   if (unlikely (variation_selector)) {
     *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
     if (*glyph)
-      return TRUE;
+      return true;
   }
 #endif
 
@@ -132,7 +132,7 @@ hb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
 			  void *user_data HB_UNUSED)
 {
   /* We always work in the horizontal coordinates. */
-  return TRUE;
+  return true;
 }
 
 static hb_bool_t
@@ -147,14 +147,14 @@ hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
   int load_flags = FT_LOAD_DEFAULT;
 
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
-    return FALSE;
+    return false;
 
   /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
    * have a Y growing upward.  Hence the extra negation. */
   *x = ft_face->glyph->metrics.horiBearingX -   ft_face->glyph->metrics.vertBearingX;
   *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
 
-  return TRUE;
+  return true;
 }
 
 static hb_position_t
@@ -195,13 +195,13 @@ hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
   int load_flags = FT_LOAD_DEFAULT;
 
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
-    return FALSE;
+    return false;
 
   extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
   extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
   extents->width = ft_face->glyph->metrics.width;
   extents->height = ft_face->glyph->metrics.height;
-  return TRUE;
+  return true;
 }
 
 static hb_bool_t
@@ -217,18 +217,18 @@ hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
   int load_flags = FT_LOAD_DEFAULT;
 
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
-      return FALSE;
+      return false;
 
   if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
-      return FALSE;
+      return false;
 
   if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
-      return FALSE;
+      return false;
 
   *x = ft_face->glyph->outline.points[point_index].x;
   *y = ft_face->glyph->outline.points[point_index].y;
 
-  return TRUE;
+  return true;
 }
 
 static hb_bool_t
@@ -277,7 +277,7 @@ _hb_ft_get_font_funcs (void)
   static const hb_font_funcs_t ft_ffuncs = {
     HB_OBJECT_HEADER_STATIC,
 
-    TRUE, /* immutable */
+    true, /* immutable */
 
     {
 #define HB_FONT_FUNC_IMPLEMENT(name) hb_ft_get_##name,
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 60f5259..6b655dd 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -251,7 +251,7 @@ hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
    * sees it and makes sure it's compilable. */
 
   if (!a || !b)
-    return FALSE;
+    return false;
 
   gchar utf8[12];
   gchar *normalized;
@@ -263,13 +263,13 @@ hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
   normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFC);
   len = g_utf8_strlen (normalized, -1);
   if (unlikely (!len))
-    return FALSE;
+    return false;
 
   if (len == 1) {
     *ab = g_utf8_get_char (normalized);
-    ret = TRUE;
+    ret = true;
   } else {
-    ret = FALSE;
+    ret = false;
   }
 
   g_free (normalized);
@@ -299,7 +299,7 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
   normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFD);
   len = g_utf8_strlen (normalized, -1);
   if (unlikely (!len))
-    return FALSE;
+    return false;
 
   if (len == 1) {
     *a = g_utf8_get_char (normalized);
@@ -318,7 +318,7 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
       *b = 0;
     }
     g_free (recomposed);
-    ret = TRUE;
+    ret = true;
   } else {
     /* If decomposed to more than two characters, take the last one,
      * and recompose the rest to get the first component. */
@@ -329,7 +329,7 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
     /* We expect that recomposed has exactly one character now. */
     *a = g_utf8_get_char (recomposed);
     g_free (recomposed);
-    ret = TRUE;
+    ret = true;
   }
 
   g_free (normalized);
@@ -342,7 +342,7 @@ const hb_unicode_funcs_t _hb_glib_unicode_funcs = {
   HB_OBJECT_HEADER_STATIC,
 
   NULL, /* parent */
-  TRUE, /* immutable */
+  true, /* immutable */
   {
 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc
index eab2eae..3fa9f79 100644
--- a/src/hb-graphite2.cc
+++ b/src/hb-graphite2.cc
@@ -159,7 +159,7 @@ _hb_gr_face_get_data (hb_face_t *face)
 
   if (unlikely (!hb_face_set_user_data (face, &hb_gr_data_key, data,
 					(hb_destroy_func_t) _hb_gr_face_data_destroy,
-					FALSE)))
+					false)))
   {
     _hb_gr_face_data_destroy (data);
     data = (hb_gr_face_data_t *) hb_face_get_user_data (face, &hb_gr_data_key);
@@ -198,7 +198,7 @@ _hb_gr_font_get_data (hb_font_t *font)
 
   if (unlikely (!hb_font_set_user_data (font, &hb_gr_data_key, data,
 					(hb_destroy_func_t) _hb_gr_font_data_destroy,
-					FALSE)))
+					false)))
   {
     _hb_gr_font_data_destroy (data);
     data = (hb_gr_font_data_t *) hb_font_get_user_data (font, &hb_gr_data_key);
@@ -225,14 +225,14 @@ _hb_graphite_shape (hb_font_t          *font,
    * is not graphite!  Shouldn't do. */
 
   hb_gr_font_data_t *data = _hb_gr_font_get_data (font);
-  if (!data->grface) return FALSE;
+  if (!data->grface) return false;
 
   unsigned int charlen;
   hb_glyph_info_t *bufferi = hb_buffer_get_glyph_infos (buffer, &charlen);
 
   int success = 0;
 
-  if (!charlen) return TRUE;
+  if (!charlen) return true;
 
   const char *lang = hb_language_to_string (hb_buffer_get_language (buffer));
   const char *lang_end = strchr (lang, '-');
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 01beb4a..aead6dd 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -172,7 +172,7 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
 			void               *user_data HB_UNUSED)
 {
   if (!a || !b)
-    return FALSE;
+    return false;
 
   UChar utf16[4], normalized[5];
   int len;
@@ -180,21 +180,21 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
   UErrorCode icu_err;
 
   len = 0;
-  err = FALSE;
+  err = false;
   U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err);
-  if (err) return FALSE;
+  if (err) return false;
   U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err);
-  if (err) return FALSE;
+  if (err) return false;
 
   icu_err = U_ZERO_ERROR;
   len = unorm_normalize (utf16, len, UNORM_NFC, 0, normalized, ARRAY_LENGTH (normalized), &icu_err);
   if (U_FAILURE (icu_err))
-    return FALSE;
+    return false;
   if (u_countChar32 (normalized, len) == 1) {
     U16_GET_UNSAFE (normalized, 0, *ab);
-    ret = TRUE;
+    ret = true;
   } else {
-    ret = FALSE;
+    ret = false;
   }
 
   return ret;
@@ -217,14 +217,14 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
   /* Watchout for the dragons.  Err, watchout for macros changing len. */
 
   len = 0;
-  err = FALSE;
+  err = false;
   U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err);
-  if (err) return FALSE;
+  if (err) return false;
 
   icu_err = U_ZERO_ERROR;
   len = unorm_normalize (utf16, len, UNORM_NFD, 0, normalized, ARRAY_LENGTH (normalized), &icu_err);
   if (U_FAILURE (icu_err))
-    return FALSE;
+    return false;
 
   len = u_countChar32 (normalized, len);
 
@@ -244,14 +244,14 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
     icu_err = U_ZERO_ERROR;
     unorm_normalize (normalized, len, UNORM_NFC, 0, recomposed, ARRAY_LENGTH (recomposed), &icu_err);
     if (U_FAILURE (icu_err))
-      return FALSE;
+      return false;
     hb_codepoint_t c;
     U16_GET_UNSAFE (recomposed, 0, c);
     if (c != *a && c != ab) {
       *a = c;
       *b = 0;
     }
-    ret = TRUE;
+    ret = true;
   } else {
     /* If decomposed to more than two characters, take the last one,
      * and recompose the rest to get the first component. */
@@ -260,10 +260,10 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
     icu_err = U_ZERO_ERROR;
     len = unorm_normalize (normalized, len, UNORM_NFC, 0, recomposed, ARRAY_LENGTH (recomposed), &icu_err);
     if (U_FAILURE (icu_err))
-      return FALSE;
+      return false;
     /* We expect that recomposed has exactly one character now. */
     U16_GET_UNSAFE (recomposed, 0, *a);
-    ret = TRUE;
+    ret = true;
   }
 
   return ret;
@@ -275,7 +275,7 @@ const hb_unicode_funcs_t _hb_icu_unicode_funcs = {
   HB_OBJECT_HEADER_STATIC,
 
   NULL, /* parent */
-  TRUE, /* immutable */
+  true, /* immutable */
   {
 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_icu_unicode_##name,
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index ded3dcc..0621f86 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -232,19 +232,19 @@ hb_ot_layout_table_find_script (hb_face_t    *face,
   const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
   if (g.find_script_index (script_tag, script_index))
-    return TRUE;
+    return true;
 
   /* try finding 'DFLT' */
   if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
-    return FALSE;
+    return false;
 
   /* try with 'dflt'; MS site has had typos and many fonts use it now :(.
    * including many versions of DejaVu Sans Mono! */
   if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
-    return FALSE;
+    return false;
 
   if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
-  return FALSE;
+  return false;
 }
 
 hb_bool_t
@@ -262,7 +262,7 @@ hb_ot_layout_table_choose_script (hb_face_t      *face,
     if (g.find_script_index (*script_tags, script_index)) {
       if (chosen_script)
         *chosen_script = *script_tags;
-      return TRUE;
+      return true;
     }
     script_tags++;
   }
@@ -271,14 +271,14 @@ hb_ot_layout_table_choose_script (hb_face_t      *face,
   if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) {
     if (chosen_script)
       *chosen_script = HB_OT_TAG_DEFAULT_SCRIPT;
-    return FALSE;
+    return false;
   }
 
   /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
   if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) {
     if (chosen_script)
       *chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE;
-    return FALSE;
+    return false;
   }
 
   /* try with 'latn'; some old fonts put their features there even though
@@ -287,13 +287,13 @@ hb_ot_layout_table_choose_script (hb_face_t      *face,
   if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) {
     if (chosen_script)
       *chosen_script = HB_OT_TAG_LATIN_SCRIPT;
-    return FALSE;
+    return false;
   }
 
   if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
   if (chosen_script)
     *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
-  return FALSE;
+  return false;
 }
 
 unsigned int
@@ -333,14 +333,14 @@ hb_ot_layout_script_find_language (hb_face_t    *face,
   const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
 
   if (s.find_lang_sys_index (language_tag, language_index))
-    return TRUE;
+    return true;
 
   /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
   if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
-    return FALSE;
+    return false;
 
   if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
-  return FALSE;
+  return false;
 }
 
 hb_bool_t
@@ -415,12 +415,12 @@ hb_ot_layout_language_find_feature (hb_face_t    *face,
 
     if (feature_tag == g.get_feature_tag (f_index)) {
       if (feature_index) *feature_index = f_index;
-      return TRUE;
+      return true;
     }
   }
 
   if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
-  return FALSE;
+  return false;
 }
 
 unsigned int
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index ba962b5..d2f7959 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -253,7 +253,7 @@ hb_ot_shape_complex_collect_features (hb_ot_complex_shaper_t shaper,
  *
  * Called during shape_execute().
  *
- * Shapers should return TRUE if it prefers decomposed (NFD) input rather than precomposed (NFC).
+ * Shapers should return true if it prefers decomposed (NFD) input rather than precomposed (NFC).
  */
 
 typedef hb_ot_shape_normalization_mode_t hb_ot_shape_complex_normalization_preference_func_t (void);
diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc
index a9019fb..562ba88 100644
--- a/src/hb-ot-shape-normalize.cc
+++ b/src/hb-ot-shape-normalize.cc
@@ -84,7 +84,7 @@ decompose (hb_font_t *font, hb_buffer_t *buffer,
 
   if (!hb_unicode_decompose (buffer->unicode, ab, &a, &b) ||
       (b && !hb_font_get_glyph (font, b, 0, &glyph)))
-    return FALSE;
+    return false;
 
   bool has_a = hb_font_get_glyph (font, a, 0, &glyph);
   if (shortest && has_a) {
@@ -92,23 +92,23 @@ decompose (hb_font_t *font, hb_buffer_t *buffer,
     output_glyph (buffer, a);
     if (b)
       output_glyph (buffer, b);
-    return TRUE;
+    return true;
   }
 
   if (decompose (font, buffer, shortest, a)) {
     if (b)
       output_glyph (buffer, b);
-    return TRUE;
+    return true;
   }
 
   if (has_a) {
     output_glyph (buffer, a);
     if (b)
       output_glyph (buffer, b);
-    return TRUE;
+    return true;
   }
 
-  return FALSE;
+  return false;
 }
 
 static void
@@ -149,7 +149,7 @@ decompose_multi_char_cluster (hb_font_t *font, hb_buffer_t *buffer,
     }
 
   while (buffer->idx < end)
-    decompose_current_glyph (font, buffer, FALSE);
+    decompose_current_glyph (font, buffer, false);
 }
 
 static int
@@ -166,7 +166,7 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
 			hb_ot_shape_normalization_mode_t mode)
 {
   bool recompose = mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED;
-  bool has_multichar_clusters = FALSE;
+  bool has_multichar_clusters = false;
   unsigned int count;
 
   /* We do a fairly straightforward yet custom normalization process in three
@@ -191,7 +191,7 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
       decompose_single_char_cluster (font, buffer, recompose);
     else {
       decompose_multi_char_cluster (font, buffer, end);
-      has_multichar_clusters = TRUE;
+      has_multichar_clusters = true;
     }
   }
   buffer->swap_buffers ();
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 8b1d670..19cf680 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -327,7 +327,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
 						   &c->buffer->pos[i].y_offset);
     }
 
-    c->applied_position_complex = TRUE;
+    c->applied_position_complex = true;
   }
 
   hb_ot_layout_position_finish (c->buffer);
@@ -490,7 +490,7 @@ _hb_ot_shape (hb_font_t          *font,
   hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_features);
   hb_ot_shape_execute (&plan, font, buffer, features, num_features);
 
-  return TRUE;
+  return true;
 }
 
 
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 4a61661..44b7314 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -61,12 +61,6 @@
 # define NULL ((void *) 0)
 #endif
 
-#undef FALSE
-#define FALSE 0
-
-#undef TRUE
-#define TRUE 1
-
 
 /* Basics */
 
@@ -601,9 +595,9 @@ _hb_debug_msg<0> (const char *what HB_UNUSED,
 		  const char *message HB_UNUSED,
 		  ...) {}
 
-#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...)	_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL,    TRUE, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
-#define DEBUG_MSG(WHAT, OBJ, ...) 				_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL,    FALSE, 0, 0, __VA_ARGS__)
-#define DEBUG_MSG_FUNC(WHAT, OBJ, ...)				_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, FALSE, 0, 0, __VA_ARGS__)
+#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...)	_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL,    true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
+#define DEBUG_MSG(WHAT, OBJ, ...) 				_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL,    false, 0, 0, __VA_ARGS__)
+#define DEBUG_MSG_FUNC(WHAT, OBJ, ...)				_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
 
 
 /*
@@ -623,14 +617,14 @@ struct hb_auto_trace_t {
 
     va_list ap;
     va_start (ap, message);
-    _hb_debug_msg_va<max_level> (what, obj, func, TRUE, plevel ? *plevel : 0, +1, message, ap);
+    _hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
     va_end (ap);
   }
   inline ~hb_auto_trace_t (void)
   {
     if (unlikely (!returned)) {
       fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN.  This is a bug, please report.  Level was %d.\n", plevel ? *plevel : -1);
-      _hb_debug_msg<max_level> (what, obj, NULL, TRUE, plevel ? *plevel : 1, -1, " ");
+      _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " ");
       return;
     }
 
@@ -644,7 +638,7 @@ struct hb_auto_trace_t {
       return v;
     }
 
-    _hb_debug_msg<max_level> (what, obj, NULL, TRUE, plevel ? *plevel : 1, -1, "return %s", v ? "true" : "false");
+    _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, "return %s", v ? "true" : "false");
     if (plevel) --*plevel;
     plevel = NULL;
     returned = true;
diff --git a/src/hb-set.cc b/src/hb-set.cc
index a044199..4225e3c 100644
--- a/src/hb-set.cc
+++ b/src/hb-set.cc
@@ -93,7 +93,7 @@ hb_set_get_user_data (hb_set_t        *set,
 hb_bool_t
 hb_set_allocation_successful (hb_set_t  *set HB_UNUSED)
 {
-  return TRUE;
+  return true;
 }
 
 void
diff --git a/src/hb-set.h b/src/hb-set.h
index 97e68e4..9f849cf 100644
--- a/src/hb-set.h
+++ b/src/hb-set.h
@@ -63,7 +63,7 @@ hb_set_get_user_data (hb_set_t           *set,
 		      hb_user_data_key_t *key);
 
 
-/* Returns FALSE if allocation has failed before */
+/* Returns false if allocation has failed before */
 hb_bool_t
 hb_set_allocation_successful (hb_set_t  *set);
 
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index a8d6d01..163a5bf 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -192,19 +192,19 @@ hb_shape_full (hb_font_t          *font,
     const hb_shaper_pair_t *shapers = get_shapers ();
     for (unsigned int i = 0; i < ARRAY_LENGTH (all_shapers); i++)
       if (likely (shapers[i].func (font, buffer, features, num_features)))
-        return TRUE;
+        return true;
   } else {
     while (*shaper_list) {
       for (unsigned int i = 0; i < ARRAY_LENGTH (all_shapers); i++)
 	if (0 == strcmp (*shaper_list, all_shapers[i].name)) {
 	  if (likely (all_shapers[i].func (font, buffer, features, num_features)))
-	    return TRUE;
+	    return true;
 	  break;
 	}
       shaper_list++;
     }
   }
-  return FALSE;
+  return false;
 }
 
 void
diff --git a/src/hb-tt-font.cc b/src/hb-tt-font.cc
index b2f24f6..0055ae9 100644
--- a/src/hb-tt-font.cc
+++ b/src/hb-tt-font.cc
@@ -88,7 +88,7 @@ hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
     return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph);
 
   *glyph = 0;
-  return FALSE;
+  return false;
 }
 
 static hb_position_t
@@ -133,7 +133,7 @@ hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
   }
 
   *x = *y = 0;
-  return FALSE;
+  return false;
 }
 
 static hb_bool_t
@@ -154,7 +154,7 @@ hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
   }
 
   *x = *y = 0;
-  return FALSE;
+  return false;
 }
 
 static hb_position_t
@@ -202,7 +202,7 @@ hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
   }
 
   memset (extents, 0, sizeof (*extents));
-  return FALSE;
+  return false;
 }
 
 static hb_bool_t
@@ -224,14 +224,14 @@ hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
   }
 
   *x = *y = 0;
-  return FALSE;
+  return false;
 }
 
 
 static hb_font_funcs_t _hb_font_funcs_nil = {
   HB_OBJECT_HEADER_STATIC,
 
-  TRUE, /* immutable */
+  true, /* immutable */
 
   {
 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index e96c0cf..1d6eacb 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -85,7 +85,7 @@ hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
 			hb_codepoint_t     *ab        HB_UNUSED,
 			void               *user_data HB_UNUSED)
 {
-  return FALSE;
+  return false;
 }
 
 static hb_bool_t
@@ -95,7 +95,7 @@ hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
 			  hb_codepoint_t     *b         HB_UNUSED,
 			  void               *user_data HB_UNUSED)
 {
-  return FALSE;
+  return false;
 }
 
 
@@ -136,7 +136,7 @@ const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
   HB_OBJECT_HEADER_STATIC,
 
   NULL, /* parent */
-  TRUE, /* immutable */
+  true, /* immutable */
   {
 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
@@ -195,7 +195,7 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
   if (hb_object_is_inert (ufuncs))
     return;
 
-  ufuncs->immutable = TRUE;
+  ufuncs->immutable = true;
 }
 
 hb_bool_t
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index 584d641..9f84a3c 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -77,18 +77,18 @@ populate_log_font (LOGFONTW  *lf,
 
   if (unlikely (!len)) {
     DEBUG_MSG (UNISCRIBE, NULL, "Didn't find English name table entry");
-    return FALSE;
+    return false;
   }
   if (unlikely (len >= LF_FACESIZE)) {
     DEBUG_MSG (UNISCRIBE, NULL, "Font name too long");
-    return FALSE;
+    return false;
   }
 
   for (unsigned int i = 0; i < len; i++)
     lf->lfFaceName[i] = hb_be_uint16 (lf->lfFaceName[i]);
   lf->lfFaceName[len] = 0;
 
-  return TRUE;
+  return true;
 }
 
 
@@ -133,7 +133,7 @@ _hb_uniscribe_face_get_data (hb_face_t *face)
 
   if (unlikely (!hb_face_set_user_data (face, &hb_uniscribe_data_key, data,
 					(hb_destroy_func_t) _hb_uniscribe_face_data_destroy,
-					FALSE)))
+					false)))
   {
     _hb_uniscribe_face_data_destroy (data);
     data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &hb_uniscribe_data_key);
@@ -190,7 +190,7 @@ _hb_uniscribe_font_get_data (hb_font_t *font)
 
   if (unlikely (!hb_font_set_user_data (font, &hb_uniscribe_data_key, data,
 					(hb_destroy_func_t) _hb_uniscribe_font_data_destroy,
-					FALSE)))
+					false)))
   {
     _hb_uniscribe_font_data_destroy (data);
     data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &hb_uniscribe_data_key);
@@ -233,7 +233,7 @@ _hb_uniscribe_shape (hb_font_t          *font,
 #define FAIL(...) \
   HB_STMT_START { \
     DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \
-    return FALSE; \
+    return false; \
   } HB_STMT_END;
 
   hb_uniscribe_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face);
@@ -245,7 +245,7 @@ _hb_uniscribe_shape (hb_font_t          *font,
     FAIL ("Couldn't get font font");
 
   if (unlikely (!buffer->len))
-    return TRUE;
+    return true;
 
   HRESULT hr;
 
@@ -305,7 +305,7 @@ retry:
   int item_count;
 
   /* MinGW32 doesn't define fMergeNeutralItems, so we bruteforce */
-  //bidi_control.fMergeNeutralItems = TRUE;
+  //bidi_control.fMergeNeutralItems = true;
   *(uint32_t*)&bidi_control |= 1<<24;
 
   bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
@@ -459,7 +459,7 @@ retry:
   }
 
   /* Wow, done! */
-  return TRUE;
+  return true;
 }
 
 
diff --git a/src/main.cc b/src/main.cc
index 03b6e6c..07d3d69 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -49,7 +49,7 @@ main (int argc, char **argv)
   int len = 0;
 
 #ifdef HAVE_GLIB
-  GMappedFile *mf = g_mapped_file_new (argv[1], FALSE, NULL);
+  GMappedFile *mf = g_mapped_file_new (argv[1], false, NULL);
   font_data = g_mapped_file_get_contents (mf);
   len = g_mapped_file_get_length (mf);
 #else
diff --git a/util/hb-shape.cc b/util/hb-shape.cc
index d459b89..b23519b 100644
--- a/util/hb-shape.cc
+++ b/util/hb-shape.cc
@@ -75,7 +75,7 @@ struct output_buffer_t
   void finish (const font_options_t *font_opts)
   {
     hb_font_destroy (font);
-    g_string_free (gs, TRUE);
+    g_string_free (gs, true);
     gs = NULL;
     font = NULL;
   }
diff --git a/util/helper-cairo.cc b/util/helper-cairo.cc
index 77fd1a6..0cdfd63 100644
--- a/util/helper-cairo.cc
+++ b/util/helper-cairo.cc
@@ -50,7 +50,7 @@ _cairo_eps_surface_create_for_stream (cairo_write_func_t  write_func,
   cairo_surface_t *surface;
 
   surface = cairo_ps_surface_create_for_stream (write_func, closure, width, height);
-  cairo_ps_surface_set_eps (surface, TRUE);
+  cairo_ps_surface_set_eps (surface, true);
 
   return surface;
 }
@@ -121,7 +121,7 @@ finalize_ansi (finalize_closure_t *closure)
 						      closure->write_func,
 						      closure->closure);
   if (status != CAIRO_STATUS_SUCCESS)
-    fail (FALSE, "Failed to write output: %s",
+    fail (false, "Failed to write output: %s",
 	  cairo_status_to_string (status));
 }
 
@@ -150,7 +150,7 @@ _cairo_ansi_surface_create_for_stream (cairo_write_func_t write_func,
   }
   cairo_status_t status = cairo_surface_status (surface);
   if (status != CAIRO_STATUS_SUCCESS)
-    fail (FALSE, "Failed to create cairo surface: %s",
+    fail (false, "Failed to create cairo surface: %s",
 	  cairo_status_to_string (status));
 
   finalize_closure_t *ansi_closure = g_new0 (finalize_closure_t, 1);
@@ -179,7 +179,7 @@ finalize_png (finalize_closure_t *closure)
 					      closure->write_func,
 					      closure->closure);
   if (status != CAIRO_STATUS_SUCCESS)
-    fail (FALSE, "Failed to write output: %s",
+    fail (false, "Failed to write output: %s",
 	  cairo_status_to_string (status));
 }
 
@@ -208,7 +208,7 @@ _cairo_png_surface_create_for_stream (cairo_write_func_t write_func,
   }
   cairo_status_t status = cairo_surface_status (surface);
   if (status != CAIRO_STATUS_SUCCESS)
-    fail (FALSE, "Failed to create cairo surface: %s",
+    fail (false, "Failed to create cairo surface: %s",
 	  cairo_status_to_string (status));
 
   finalize_closure_t *png_closure = g_new0 (finalize_closure_t, 1);
@@ -240,7 +240,7 @@ stdio_write_func (void                *closure,
     size -= ret;
     data += ret;
     if (size && ferror (fp))
-      fail (FALSE, "Failed to write output: %s", strerror (errno));
+      fail (false, "Failed to write output: %s", strerror (errno));
   }
 
   return CAIRO_STATUS_SUCCESS;
@@ -317,7 +317,7 @@ helper_cairo_create_context (double w, double h,
   else if (constructor2)
     surface = constructor2 (stdio_write_func, f, w, h, content);
   else
-    fail (FALSE, "Unknown output format `%s'", extension);
+    fail (false, "Unknown output format `%s'", extension);
 
   cairo_t *cr = cairo_create (surface);
   content = cairo_surface_get_content (surface);
@@ -356,7 +356,7 @@ helper_cairo_destroy_context (cairo_t *cr)
 
   cairo_status_t status = cairo_status (cr);
   if (status != CAIRO_STATUS_SUCCESS)
-    fail (FALSE, "Failed: %s",
+    fail (false, "Failed: %s",
 	  cairo_status_to_string (status));
   cairo_destroy (cr);
 }
diff --git a/util/main-font-text.hh b/util/main-font-text.hh
index 1dbaaff..44e3bfb 100644
--- a/util/main-font-text.hh
+++ b/util/main-font-text.hh
@@ -49,7 +49,7 @@ struct main_font_text_t
     if (argc && !font_opts.font_file) font_opts.font_file = argv[0], argc--, argv++;
     if (argc && !input.text && !input.text_file) input.text = argv[0], argc--, argv++;
     if (argc)
-      fail (TRUE, "Too many arguments on the command line");
+      fail (true, "Too many arguments on the command line");
     if (!font_opts.font_file)
       options.usage ();
     if (!input.text && !input.text_file)
diff --git a/util/options.cc b/util/options.cc
index 785222b..db1b244 100644
--- a/util/options.cc
+++ b/util/options.cc
@@ -48,7 +48,7 @@ fail (hb_bool_t suggest_help, const char *format, ...)
 }
 
 
-hb_bool_t debug = FALSE;
+hb_bool_t debug = false;
 
 static gchar *
 shapers_to_string (void)
@@ -62,7 +62,7 @@ shapers_to_string (void)
   }
   g_string_truncate (shapers, MAX (0, (gint)shapers->len - 1));
 
-  return g_string_free (shapers, FALSE);
+  return g_string_free (shapers, false);
 }
 
 static G_GNUC_NORETURN gboolean
@@ -141,10 +141,10 @@ option_parser_t::parse (int *argc, char ***argv)
   if (!g_option_context_parse (context, argc, argv, &parse_error))
   {
     if (parse_error != NULL) {
-      fail (TRUE, "%s", parse_error->message);
+      fail (true, "%s", parse_error->message);
       //g_error_free (parse_error);
     } else
-      fail (TRUE, "Option parse error");
+      fail (true, "Option parse error");
   }
 }
 
@@ -161,12 +161,12 @@ parse_margin (const char *name G_GNUC_UNUSED,
     case 1: m.r = m.t;
     case 2: m.b = m.t;
     case 3: m.l = m.r;
-    case 4: return TRUE;
+    case 4: return true;
     default:
       g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
 		   "%s argument should be one to four space-separated numbers",
 		   name);
-      return FALSE;
+      return false;
   }
 }
 
@@ -180,7 +180,7 @@ parse_shapers (const char *name G_GNUC_UNUSED,
   shape_options_t *shape_opts = (shape_options_t *) data;
   g_free (shape_opts->shapers);
   shape_opts->shapers = g_strsplit (arg, ",", 0);
-  return TRUE;
+  return true;
 }
 
 static G_GNUC_NORETURN gboolean
@@ -213,10 +213,10 @@ parse_char (char **pp, char c)
   parse_space (pp);
 
   if (**pp != c)
-    return FALSE;
+    return false;
 
   (*pp)++;
-  return TRUE;
+  return true;
 }
 
 static hb_bool_t
@@ -228,10 +228,10 @@ parse_uint (char **pp, unsigned int *pv)
   v = strtol (p, pp, 0);
 
   if (p == *pp)
-    return FALSE;
+    return false;
 
   *pv = v;
-  return TRUE;
+  return true;
 }
 
 
@@ -245,7 +245,7 @@ parse_feature_value_prefix (char **pp, hb_feature_t *feature)
     feature->value = 1;
   }
 
-  return TRUE;
+  return true;
 }
 
 static hb_bool_t
@@ -261,10 +261,10 @@ parse_feature_tag (char **pp, hb_feature_t *feature)
 #undef ISALNUM
 
   if (p == *pp)
-    return FALSE;
+    return false;
 
   feature->tag = hb_tag_from_string (p, *pp - p);
-  return TRUE;
+  return true;
 }
 
 static hb_bool_t
@@ -278,7 +278,7 @@ parse_feature_indices (char **pp, hb_feature_t *feature)
   feature->end = (unsigned int) -1;
 
   if (!parse_char (pp, '['))
-    return TRUE;
+    return true;
 
   has_start = parse_uint (pp, &feature->start);
 
@@ -335,7 +335,7 @@ parse_features (const char *name G_GNUC_UNUSED,
   shape_opts->features = NULL;
 
   if (!*s)
-    return TRUE;
+    return true;
 
   /* count the features first, so we can allocate memory */
   p = s;
@@ -358,7 +358,7 @@ parse_features (const char *name G_GNUC_UNUSED,
       skip_one_feature (&p);
   }
 
-  return TRUE;
+  return true;
 }
 
 
@@ -518,7 +518,7 @@ font_options_t::get_font (void) const
 
     /* This is a hell of a lot of code for just reading a file! */
     if (!font_file)
-      fail (TRUE, "No font file set");
+      fail (true, "No font file set");
 
     if (0 == strcmp (font_file, "-")) {
       /* read it */
@@ -530,18 +530,18 @@ font_options_t::get_font (void) const
       while (!feof (stdin)) {
 	size_t ret = fread (buf, 1, sizeof (buf), stdin);
 	if (ferror (stdin))
-	  fail (FALSE, "Failed reading font from standard input: %s",
+	  fail (false, "Failed reading font from standard input: %s",
 		strerror (errno));
 	g_string_append_len (gs, buf, ret);
       }
       len = gs->len;
-      font_data = g_string_free (gs, FALSE);
+      font_data = g_string_free (gs, false);
       user_data = font_data;
       destroy = (hb_destroy_func_t) g_free;
       mm = HB_MEMORY_MODE_WRITABLE;
     } else {
       GError *error = NULL;
-      GMappedFile *mf = g_mapped_file_new (font_file, FALSE, &error);
+      GMappedFile *mf = g_mapped_file_new (font_file, false, &error);
       if (mf) {
 	font_data = g_mapped_file_get_contents (mf);
 	len = g_mapped_file_get_length (mf);
@@ -552,7 +552,7 @@ font_options_t::get_font (void) const
 	} else
 	  g_mapped_file_unref (mf);
       } else {
-	fail (FALSE, "%s", error->message);
+	fail (false, "%s", error->message);
 	//g_error_free (error);
       }
       if (!len) {
@@ -567,7 +567,7 @@ font_options_t::get_font (void) const
 	  user_data = (void *) font_data;
 	  mm = HB_MEMORY_MODE_WRITABLE;
 	} else {
-	  fail (FALSE, "%s", error->message);
+	  fail (false, "%s", error->message);
 	  //g_error_free (error);
 	}
       }
@@ -626,7 +626,7 @@ text_options_t::get_line (unsigned int *len)
 
   if (!fp) {
     if (!text_file)
-      fail (TRUE, "At least one of text or text-file must be set");
+      fail (true, "At least one of text or text-file must be set");
 
     if (0 != strcmp (text_file, "-"))
       fp = fopen (text_file, "r");
@@ -634,7 +634,7 @@ text_options_t::get_line (unsigned int *len)
       fp = stdin;
 
     if (!fp)
-      fail (FALSE, "Failed opening text file `%s': %s",
+      fail (false, "Failed opening text file `%s': %s",
 	    text_file, strerror (errno));
 
     gs = g_string_new (NULL);
@@ -652,7 +652,7 @@ text_options_t::get_line (unsigned int *len)
       g_string_append_len (gs, buf, bytes);
   }
   if (ferror (fp))
-    fail (FALSE, "Failed reading text: %s",
+    fail (false, "Failed reading text: %s",
 	  strerror (errno));
   *len = gs->len;
   return !*len && feof (fp) ? NULL : gs->str;
@@ -674,7 +674,7 @@ output_options_t::get_file_handle (void)
     fp = stdout;
   }
   if (!fp)
-    fail (FALSE, "Cannot open output file `%s': %s",
+    fail (false, "Cannot open output file `%s': %s",
 	  g_filename_display_name (output_file), strerror (errno));
 
   return fp;
@@ -687,8 +687,8 @@ parse_verbose (const char *name G_GNUC_UNUSED,
 	       GError    **error G_GNUC_UNUSED)
 {
   format_options_t *format_opts = (format_options_t *) data;
-  format_opts->show_text = format_opts->show_unicode = format_opts->show_line_num = TRUE;
-  return TRUE;
+  format_opts->show_text = format_opts->show_unicode = format_opts->show_line_num = true;
+  return true;
 }
 
 void
diff --git a/util/options.hh b/util/options.hh
index 6e73a1c..9b7baa7 100644
--- a/util/options.hh
+++ b/util/options.hh
@@ -251,7 +251,7 @@ struct text_options_t : option_group_t
   }
   ~text_options_t (void) {
     if (gs)
-      g_string_free (gs, TRUE);
+      g_string_free (gs, true);
     if (fp)
       fclose (fp);
   }
diff --git a/util/view-cairo.hh b/util/view-cairo.hh
index 9b000b5..c621984 100644
--- a/util/view-cairo.hh
+++ b/util/view-cairo.hh
@@ -42,7 +42,7 @@ struct view_cairo_t {
 
   void init (const font_options_t *font_opts)
   {
-    lines = g_array_new (FALSE, FALSE, sizeof (helper_cairo_line_t));
+    lines = g_array_new (false, false, sizeof (helper_cairo_line_t));
     scale = double (view_options.font_size) / hb_face_get_upem (hb_font_get_face (font_opts->get_font ()));
   }
   void new_line (void)
commit e1ac38f8dd04c29d2d4140f5a492cdaf25d72901
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 20:31:49 2012 -0400

    Fix inert buffer set_length() with zero
    
    Oops!

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 20de022..c27cc15 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -694,6 +694,9 @@ hb_bool_t
 hb_buffer_set_length (hb_buffer_t  *buffer,
 		      unsigned int  length)
 {
+  if (unlikely (hb_object_is_inert (buffer)))
+    return length == 0;
+
   if (!buffer->ensure (length))
     return FALSE;
 
commit 04bc1eebe7a304c0e6f86ab6814c65889f152602
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 20:16:56 2012 -0400

    Add configure tests for Intel atomic intrinsics

diff --git a/configure.ac b/configure.ac
index d126b16..2fb058f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -177,6 +177,23 @@ if $have_uniscribe; then
 fi
 AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe)
 
+dnl ===========================================================================
+
+AC_CACHE_CHECK([for Intel atomic primitives], hb_cv_have_intel_atomic_primitives, [
+	hb_cv_have_intel_atomic_primitives=false
+	AC_TRY_LINK([], [
+		void memory_barrier (void) { __sync_synchronize (); }
+		int atomic_add (int i) { return __sync_fetch_and_add (&i, 1); }
+		int atomic_cmpxchg (int *i, int *j, int *k) { return __sync_bool_compare_and_swap (&i, j, k); }
+		], hb_cv_have_intel_atomic_primitives=true
+	)
+])
+if $hb_cv_have_intel_atomic_primitives; then
+	AC_DEFINE(HAVE_INTEL_ATOMIC_PRIMITIVES, 1, [Have Intel __sync_* atomic primitives])
+fi
+
+dnl ===========================================================================
+
 AC_CONFIG_FILES([
 Makefile
 harfbuzz.pc
diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh
index c1b25bd..0e7ecae 100644
--- a/src/hb-atomic-private.hh
+++ b/src/hb-atomic-private.hh
@@ -51,7 +51,7 @@ typedef long hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	_InterlockedExchangeAdd (&(AI), (V))
 
 #define hb_atomic_ptr_get(P)		(MemoryBarrier (), (void *) *(P))
-#define hb_atomic_ptr_cmpexch(P,O,N)	(_InterlockedCompareExchangePointer ((void * volatile *) (P), (N), (O)) == (O))
+#define hb_atomic_ptr_cmpexch(P,O,N)	(_InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
 
 
 #elif !defined(HB_NO_MT) && defined(__APPLE__)
@@ -62,10 +62,10 @@ typedef int32_t hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(OSAtomicAdd32Barrier ((V), &(AI)) - (V))
 
 #define hb_atomic_ptr_get(P)		(OSMemoryBarrier (), (void *) *(P))
-#define hb_atomic_ptr_cmpexch(P,O,N)	OSAtomicCompareAndSwapPtrBarrier ((O), (N), (void * volatile *) (P))
+#define hb_atomic_ptr_cmpexch(P,O,N)	OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
 
 
-#elif !defined(HB_NO_MT) && defined(__GNUC__)
+#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
 
 typedef int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	__sync_fetch_and_add (&(AI), (V))
@@ -84,7 +84,7 @@ typedef int hb_atomic_int_t;
 #endif
 
 #define hb_atomic_ptr_get(P)		g_atomic_pointer_get (P)
-#define hb_atomic_ptr_cmpexch(P,O,N)	g_atomic_pointer_compare_and_exchange ((void * volatile *) (P), (O), (N))
+#define hb_atomic_ptr_cmpexch(P,O,N)	g_atomic_pointer_compare_and_exchange ((void **) (P), (void *) (O), (void *) (N))
 
 
 #elif !defined(HB_NO_MT)
@@ -94,7 +94,7 @@ typedef volatile int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
 
 #define hb_atomic_ptr_get(P)		((void *) *(P))
-#define hb_atomic_ptr_cmpexch(P,O,N)	(*(P) == (O) ? (*(P) = (N), TRUE) : FALSE)
+#define hb_atomic_ptr_cmpexch(P,O,N)	(* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), TRUE) : FALSE)
 
 
 #else /* HB_NO_MT */
@@ -103,7 +103,7 @@ typedef int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
 
 #define hb_atomic_ptr_get(P)		((void *) *(P))
-#define hb_atomic_ptr_cmpexch(P,O,N)	*(P)
+#define hb_atomic_ptr_cmpexch(P,O,N)	(* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), TRUE) : FALSE)
 
 #endif
 
diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh
index 9278643..a6d16e9 100644
--- a/src/hb-mutex-private.hh
+++ b/src/hb-mutex-private.hh
@@ -75,7 +75,7 @@ typedef GStaticMutex hb_mutex_impl_t;
 #define hb_mutex_impl_finish(M)	g_static_mutex_free (M)
 
 
-#elif !defined(HB_NO_MT) && defined(__GNUC__)
+#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
 
 #if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
 # include <sched.h>
commit 68c75b46977beb57e35082db26be712b3cd65678
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 19:55:46 2012 -0400

    Shuffle

diff --git a/configure.ac b/configure.ac
index edb8820..d126b16 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,14 @@ fi
 
 dnl ==========================================================================
 
+have_ot=true
+if $have_ot; then
+	AC_DEFINE(HAVE_OT, 1, [Have native OpenType Layout backend])
+fi
+AM_CONDITIONAL(HAVE_OT, $have_ot)
+
+dnl ===========================================================================
+
 PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, have_glib=true, have_glib=false)
 if $have_glib; then
 	AC_DEFINE(HAVE_GLIB, 1, [Have glib2 library])
@@ -159,14 +167,6 @@ AM_CONDITIONAL(HAVE_FREETYPE, $have_freetype)
 
 dnl ===========================================================================
 
-have_ot=true
-if $have_ot; then
-	AC_DEFINE(HAVE_OT, 1, [Have native OpenType Layout backend])
-fi
-AM_CONDITIONAL(HAVE_OT, $have_ot)
-
-dnl ===========================================================================
-
 AC_CHECK_HEADERS(usp10.h windows.h, have_uniscribe=true, have_uniscribe=false)
 if $have_uniscribe; then
 	UNISCRIBE_CFLAGS=
commit f64b2ebf82c5f355cd95806478cd30c00b1a2731
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 19:23:29 2012 -0400

    Remove last static initializer
    
    We're free!  Lazy or immediate...

diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index ce68ca7..20fb32e 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -398,6 +398,8 @@ hb_ft_font_create (FT_Face           ft_face,
 }
 
 
+/* Thread-safe, lock-free, FT_Library */
+
 static FT_Library ft_library;
 
 static
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index d97028e..a8d6d01 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -47,10 +47,10 @@ typedef hb_bool_t (*hb_shape_func_t) (hb_font_t          *font,
 				      unsigned int        num_features);
 
 #define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape}
-static struct hb_shaper_pair_t {
+static const struct hb_shaper_pair_t {
   char name[16];
   hb_shape_func_t func;
-} shapers[] = {
+} all_shapers[] = {
   /* v--- Add new shapers in the right place here */
 #ifdef HAVE_GRAPHITE
   HB_SHAPER_IMPLEMENT (graphite2),
@@ -65,55 +65,120 @@ static struct hb_shaper_pair_t {
 };
 #undef HB_SHAPER_IMPLEMENT
 
-static struct static_shaper_list_t
+
+/* Thread-safe, lock-free, shapers */
+
+static hb_shaper_pair_t *static_shapers;
+
+static
+void free_static_shapers (void)
+{
+  if (unlikely (static_shapers != all_shapers))
+    free (static_shapers);
+}
+
+static const hb_shaper_pair_t *
+get_shapers (void)
 {
-  static_shaper_list_t (void)
+retry:
+  hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
+
+  if (unlikely (!shapers))
   {
     char *env = getenv ("HB_SHAPER_LIST");
-    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 == (int) 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;
-      }
+    if (!env || !*env) {
+      hb_atomic_ptr_cmpexch (&static_shapers, NULL, (const hb_shaper_pair_t *) all_shapers);
+      return (const hb_shaper_pair_t *) all_shapers;
     }
 
-    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;
+    /* Not found; allocate one. */
+    shapers = (hb_shaper_pair_t *) malloc (sizeof (all_shapers));
+    if (unlikely (!shapers))
+      return (const hb_shaper_pair_t *) all_shapers;
+     memcpy (shapers, all_shapers, sizeof (all_shapers));
+
+     /* Reorder shaper list to prefer requested shapers. */
+    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 (all_shapers); j++)
+	if (end - p == (int) 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;
+    }
+
+    if (!hb_atomic_ptr_cmpexch (&static_shapers, NULL, shapers)) {
+      free (shapers);
+      goto retry;
+    }
+
+#ifdef HAVE_ATEXIT
+    atexit (free_static_shapers); /* First person registers atexit() callback. */
+#endif
   }
 
-  const char *shaper_list[ARRAY_LENGTH (shapers) + 1];
-} static_shaper_list;
+  return shapers;
+}
+
+
+static const char **static_shaper_list;
+
+static
+void free_static_shaper_list (void)
+{
+  free (static_shaper_list);
+}
 
 const char **
 hb_shape_list_shapers (void)
 {
-  return static_shaper_list.shaper_list;
+retry:
+  const char **shaper_list = (const char **) hb_atomic_ptr_get (&static_shaper_list);
+
+  if (unlikely (!shaper_list))
+  {
+    /* Not found; allocate one. */
+    shaper_list = (const char **) calloc (1 + ARRAY_LENGTH (all_shapers), sizeof (const char *));
+    if (unlikely (!shaper_list)) {
+      static const char *nil_shaper_list[] = {NULL};
+      return nil_shaper_list;
+    }
+
+    const hb_shaper_pair_t *shapers = get_shapers ();
+    unsigned int i;
+    for (i = 0; i < ARRAY_LENGTH (all_shapers); i++)
+      shaper_list[i] = shapers[i].name;
+    shaper_list[i] = NULL;
+
+    if (!hb_atomic_ptr_cmpexch (&static_shaper_list, NULL, shaper_list)) {
+      free (shaper_list);
+      goto retry;
+    }
+
+#ifdef HAVE_ATEXIT
+    atexit (free_static_shaper_list); /* First person registers atexit() callback. */
+#endif
+  }
+
+  return shaper_list;
 }
 
+
 hb_bool_t
 hb_shape_full (hb_font_t          *font,
 	       hb_buffer_t        *buffer,
@@ -124,14 +189,15 @@ hb_shape_full (hb_font_t          *font,
   hb_font_make_immutable (font); /* So we can safely cache stuff on it */
 
   if (likely (!shaper_list)) {
-    for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
+    const hb_shaper_pair_t *shapers = get_shapers ();
+    for (unsigned int i = 0; i < ARRAY_LENGTH (all_shapers); i++)
       if (likely (shapers[i].func (font, buffer, features, num_features)))
         return TRUE;
   } else {
     while (*shaper_list) {
-      for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
-	if (0 == strcmp (*shaper_list, shapers[i].name)) {
-	  if (likely (shapers[i].func (font, buffer, features, num_features)))
+      for (unsigned int i = 0; i < ARRAY_LENGTH (all_shapers); i++)
+	if (0 == strcmp (*shaper_list, all_shapers[i].name)) {
+	  if (likely (all_shapers[i].func (font, buffer, features, num_features)))
 	    return TRUE;
 	  break;
 	}
commit 4a8a529068fc380298bb05b9d878bede3e9f4da1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 19:17:02 2012 -0400

    Make hb-view err if all shapers failed

diff --git a/util/view-cairo.hh b/util/view-cairo.hh
index 31c7ade..9b000b5 100644
--- a/util/view-cairo.hh
+++ b/util/view-cairo.hh
@@ -59,7 +59,7 @@ struct view_cairo_t {
 		     unsigned int  text_len,
 		     hb_bool_t     utf8_clusters)
   {
-    consume_glyphs (buffer, text, text_len, utf8_clusters);
+    fail (false, "all shapers failed");
   }
   void consume_glyphs (hb_buffer_t  *buffer,
 		       const char   *text,
commit 04aed572f112b96a6033cd6c3df7bdba5e29e93c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 18:30:19 2012 -0400

    Make hb-ft static-initializer free

diff --git a/src/hb-common.cc b/src/hb-common.cc
index 6972aa5..331d255 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -182,7 +182,6 @@ void free_langs (void)
 static hb_language_item_t *
 lang_find_or_insert (const char *key)
 {
-
 retry:
   hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
 
@@ -203,8 +202,8 @@ retry:
   }
 
 #ifdef HAVE_ATEXIT
-  if (!first_lang) /* First person registers atexit() callback. */
-    atexit (free_langs);
+  if (!first_lang)
+    atexit (free_langs); /* First person registers atexit() callback. */
 #endif
 
   return lang;
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index aa09bd7..ce68ca7 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -398,21 +398,37 @@ hb_ft_font_create (FT_Face           ft_face,
 }
 
 
+static FT_Library ft_library;
+
+static
+void free_ft_library (void)
+{
+  FT_Done_FreeType (ft_library);
+}
+
 static FT_Library
-_get_ft_library (void)
+get_ft_library (void)
 {
-  static struct ft_library_singleton
+retry:
+  FT_Library library = (FT_Library) hb_atomic_ptr_get (&ft_library);
+
+  if (unlikely (!library))
   {
-    ft_library_singleton (void) {
-      FT_Init_FreeType (&ft_library);
-    }
-    ~ft_library_singleton (void) {
-      FT_Done_FreeType (ft_library);
+    /* Not found; allocate one. */
+    if (FT_Init_FreeType (&library))
+      return NULL;
+
+    if (!hb_atomic_ptr_cmpexch (&ft_library, NULL, library)) {
+      FT_Done_FreeType (library);
+      goto retry;
     }
-    FT_Library ft_library;
-  } ft_library_singleton;
 
-  return ft_library_singleton.ft_library;
+#ifdef HAVE_ATEXIT
+    atexit (free_ft_library); /* First person registers atexit() callback. */
+#endif
+  }
+
+  return library;
 }
 
 static void
@@ -431,7 +447,7 @@ hb_ft_font_set_funcs (hb_font_t *font)
     DEBUG_MSG (FT, font, "Font face has empty blob");
 
   FT_Face ft_face = NULL;
-  FT_Error err = FT_New_Memory_Face (_get_ft_library (),
+  FT_Error err = FT_New_Memory_Face (get_ft_library (),
 				     (const FT_Byte *) blob_data,
 				     blob_length,
 				     hb_face_get_index (font->face),
commit be4560a3b5e8599cbe2b29a01a60c21c9e2b194f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 18:14:03 2012 -0400

    Undo default unicode-funcs to avoid static initializer again

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 144a68c..20de022 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -37,7 +37,7 @@
 #define HB_DEBUG_BUFFER (HB_DEBUG+0)
 #endif
 
-#define _HB_BUFFER_UNICODE_FUNCS_DEFAULT _hb_unicode_funcs_default
+#define _HB_BUFFER_UNICODE_FUNCS_DEFAULT (const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_default))
 #define _HB_BUFFER_PROPS_DEFAULT { HB_DIRECTION_INVALID, HB_SCRIPT_INVALID, HB_LANGUAGE_INVALID }
 
 /* Here is how the buffer works internally:
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 33369b2..60f5259 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -337,21 +337,22 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
 }
 
 
-hb_unicode_funcs_t *
-hb_glib_get_unicode_funcs (void)
-{
-  static const hb_unicode_funcs_t _hb_glib_unicode_funcs = {
-    HB_OBJECT_HEADER_STATIC,
+extern HB_INTERNAL const hb_unicode_funcs_t _hb_glib_unicode_funcs;
+const hb_unicode_funcs_t _hb_glib_unicode_funcs = {
+  HB_OBJECT_HEADER_STATIC,
 
-    NULL, /* parent */
-    TRUE, /* immutable */
-    {
+  NULL, /* parent */
+  TRUE, /* immutable */
+  {
 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
-      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
-    }
-  };
+  }
+};
 
+hb_unicode_funcs_t *
+hb_glib_get_unicode_funcs (void)
+{
   return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs);
 }
 
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 78cbc1a..01beb4a 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -269,21 +269,23 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
   return ret;
 }
 
-hb_unicode_funcs_t *
-hb_icu_get_unicode_funcs (void)
-{
-  static const hb_unicode_funcs_t _hb_icu_unicode_funcs = {
-    HB_OBJECT_HEADER_STATIC,
 
-    NULL, /* parent */
-    TRUE, /* immutable */
-    {
+extern HB_INTERNAL const hb_unicode_funcs_t _hb_icu_unicode_funcs;
+const hb_unicode_funcs_t _hb_icu_unicode_funcs = {
+  HB_OBJECT_HEADER_STATIC,
+
+  NULL, /* parent */
+  TRUE, /* immutable */
+  {
 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_icu_unicode_##name,
-      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
-    }
-  };
+  }
+};
 
+hb_unicode_funcs_t *
+hb_icu_get_unicode_funcs (void)
+{
   return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs);
 }
 
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index 9a900f5..7f719c4 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -91,14 +91,14 @@ struct _hb_unicode_funcs_t {
 
 
 #ifdef HAVE_GLIB
-extern "C" hb_unicode_funcs_t * hb_glib_get_unicode_funcs (void);
-#define _hb_unicode_funcs_default hb_glib_get_unicode_funcs ()
+extern HB_INTERNAL const hb_unicode_funcs_t _hb_glib_unicode_funcs;
+#define _hb_unicode_funcs_default _hb_glib_unicode_funcs
 #elif defined(HAVE_ICU)
-extern "C" hb_unicode_funcs_t * hb_icu_get_unicode_funcs (void);
-#define _hb_unicode_funcs_default hb_icu_get_unicode_funcs ()
+extern HB_INTERNAL const hb_unicode_funcs_t _hb_icu_unicode_funcs;
+#define _hb_unicode_funcs_default _hb_icu_unicode_funcs
 #else
 #define HB_UNICODE_FUNCS_NIL 1
-#define _hb_unicode_funcs_default hb_unicode_funcs_get_empty ()
+#define _hb_unicode_funcs_default _hb_unicode_funcs_nil
 #endif
 
 
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index b7a5f8d..e96c0cf 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -103,7 +103,7 @@ hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
 hb_unicode_funcs_t *
 hb_unicode_funcs_get_default (void)
 {
-  return _hb_unicode_funcs_default;
+  return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_default);
 }
 
 hb_unicode_funcs_t *
@@ -130,21 +130,23 @@ hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
   return ufuncs;
 }
 
-hb_unicode_funcs_t *
-hb_unicode_funcs_get_empty (void)
-{
-  static const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
-    HB_OBJECT_HEADER_STATIC,
 
-    NULL, /* parent */
-    TRUE, /* immutable */
-    {
+extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
+const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
+  HB_OBJECT_HEADER_STATIC,
+
+  NULL, /* parent */
+  TRUE, /* immutable */
+  {
 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
-      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
-    }
-  };
+  }
+};
 
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_empty (void)
+{
   return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
 }
 
commit 093171cceca63e48e735bbf05a2c11b1b7e95ef1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 18:00:45 2012 -0400

    Implement lock-free hb_language_t
    
    Another static-initialization down.  One more to go.

diff --git a/src/hb-common.cc b/src/hb-common.cc
index c7ee9af..6972aa5 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -114,18 +114,16 @@ static const char canon_map[256] = {
 };
 
 static hb_bool_t
-lang_equal (const void *v1,
-	    const void *v2)
+lang_equal (hb_language_t  v1,
+	    const void    *v2)
 {
   const unsigned char *p1 = (const unsigned char *) v1;
   const unsigned char *p2 = (const unsigned char *) v2;
 
-  while (canon_map[*p1] && canon_map[*p1] == canon_map[*p2])
-    {
-      p1++, p2++;
-    }
+  while (*p1 && *p1 == canon_map[*p2])
+    p1++, p2++;
 
-  return (canon_map[*p1] == canon_map[*p2]);
+  return *p1 == canon_map[*p2];
 }
 
 #if 0
@@ -147,6 +145,7 @@ lang_hash (const void *key)
 
 struct hb_language_item_t {
 
+  struct hb_language_item_t *next;
   hb_language_t lang;
 
   inline bool operator == (const char *s) const {
@@ -164,10 +163,53 @@ struct hb_language_item_t {
   void finish (void) { free (lang); }
 };
 
-static struct hb_static_lang_set_t : hb_lockable_set_t<hb_language_item_t, hb_static_mutex_t> {
-  ~hb_static_lang_set_t (void) { this->finish (lock); }
-  hb_static_mutex_t lock;
-} langs;
+
+/* Thread-safe lock-free language list */
+
+static hb_language_item_t *langs;
+
+static
+void free_langs (void)
+{
+  while (langs) {
+    hb_language_item_t *next = langs->next;
+    langs->finish ();
+    free (langs);
+    langs = next;
+  }
+}
+
+static hb_language_item_t *
+lang_find_or_insert (const char *key)
+{
+
+retry:
+  hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
+
+  for (hb_language_item_t *lang = first_lang; lang; lang = lang->next)
+    if (*lang == key)
+      return lang;
+
+  /* Not found; allocate one. */
+  hb_language_item_t *lang = (hb_language_item_t *) calloc (1, sizeof (hb_language_item_t));
+  if (unlikely (!lang))
+    return NULL;
+  lang->next = first_lang;
+  *lang = key;
+
+  if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
+    free (lang);
+    goto retry;
+  }
+
+#ifdef HAVE_ATEXIT
+  if (!first_lang) /* First person registers atexit() callback. */
+    atexit (free_langs);
+#endif
+
+  return lang;
+}
+
 
 hb_language_t
 hb_language_from_string (const char *str, int len)
@@ -182,7 +224,7 @@ hb_language_from_string (const char *str, int len)
     strbuf[len] = '\0';
   }
 
-  hb_language_item_t *item = langs.find_or_insert (str, langs.lock);
+  hb_language_item_t *item = lang_find_or_insert (str);
 
   return likely (item) ? item->lang : HB_LANGUAGE_INVALID;
 }
commit 6843ce01be0df501ef3149a2c1c54cdfb693195d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 17:27:20 2012 -0400

    Add atomic-pointer functions
    
    Gonig to use these for lock-free linked-lists, to be used for
    hb_language_t among other things.

diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh
index 3394afc..c1b25bd 100644
--- a/src/hb-atomic-private.hh
+++ b/src/hb-atomic-private.hh
@@ -45,22 +45,34 @@
 #elif !defined(HB_NO_MT) && defined(_MSC_VER) && _MSC_VER >= 1600
 
 #include <intrin.h>
+#pragma intrinsic(_InterlockedExchangeAdd, _InterlockedCompareExchangePointer)
+
 typedef long hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	_InterlockedExchangeAdd (&(AI), (V))
 
+#define hb_atomic_ptr_get(P)		(MemoryBarrier (), (void *) *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N)	(_InterlockedCompareExchangePointer ((void * volatile *) (P), (N), (O)) == (O))
+
 
 #elif !defined(HB_NO_MT) && defined(__APPLE__)
 
 #include <libkern/OSAtomic.h>
+
 typedef int32_t hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(OSAtomicAdd32Barrier ((V), &(AI)) - (V))
 
+#define hb_atomic_ptr_get(P)		(OSMemoryBarrier (), (void *) *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N)	OSAtomicCompareAndSwapPtrBarrier ((O), (N), (void * volatile *) (P))
+
 
 #elif !defined(HB_NO_MT) && defined(__GNUC__)
 
 typedef int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	__sync_fetch_and_add (&(AI), (V))
 
+#define hb_atomic_ptr_get(P)		(void *) (__sync_synchronize (), *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N)	__sync_bool_compare_and_swap ((P), (O), (N))
+
 #elif !defined(HB_NO_MT) && defined(HAVE_GLIB)
 
 #include <glib.h>
@@ -71,6 +83,9 @@ typedef int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	g_atomic_int_exchange_and_add (&(AI), (V))
 #endif
 
+#define hb_atomic_ptr_get(P)		g_atomic_pointer_get (P)
+#define hb_atomic_ptr_cmpexch(P,O,N)	g_atomic_pointer_compare_and_exchange ((void * volatile *) (P), (O), (N))
+
 
 #elif !defined(HB_NO_MT)
 
@@ -78,12 +93,18 @@ typedef int hb_atomic_int_t;
 typedef volatile int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
 
+#define hb_atomic_ptr_get(P)		((void *) *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N)	(*(P) == (O) ? (*(P) = (N), TRUE) : FALSE)
+
 
 #else /* HB_NO_MT */
 
 typedef int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
 
+#define hb_atomic_ptr_get(P)		((void *) *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N)	*(P)
+
 #endif
 
 /* TODO Add tracing. */
commit cdafe3a7d8483ac586e2c16487e2a09164e0f65c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 16:34:49 2012 -0400

    Add gcc intrinsics implementations for atomic and mutex

diff --git a/configure.ac b/configure.ac
index 44b0df4..edb8820 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,8 +52,8 @@ AC_SUBST(HB_LIBTOOL_VERSION_INFO)
 dnl GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
 
 # Functions and headers
-AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap _setmode isatty)
-AC_CHECK_HEADERS(unistd.h sys/mman.h io.h)
+AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize sched_yield mmap _setmode isatty)
+AC_CHECK_HEADERS(unistd.h sys/mman.h sched.h io.h)
 
 # Compiler flags
 AC_CANONICAL_HOST
diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh
index 29e4146..3394afc 100644
--- a/src/hb-atomic-private.hh
+++ b/src/hb-atomic-private.hh
@@ -72,13 +72,20 @@ typedef int hb_atomic_int_t;
 #endif
 
 
-#else
+#elif !defined(HB_NO_MT)
+
+#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
+typedef volatile int hb_atomic_int_t;
+#define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
+
+
+#else /* HB_NO_MT */
 
-#define HB_ATOMIC_INT_NIL 1
 typedef int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
 
 #endif
 
+/* TODO Add tracing. */
 
 #endif /* HB_ATOMIC_PRIVATE_HH */
diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh
index 9e061b9..9278643 100644
--- a/src/hb-mutex-private.hh
+++ b/src/hb-mutex-private.hh
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2007  Chris Wilson
  * Copyright © 2009,2010  Red Hat, Inc.
- * Copyright © 2011  Google, Inc.
+ * Copyright © 2011,2012  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -53,7 +53,7 @@ typedef CRITICAL_SECTION hb_mutex_impl_t;
 #define hb_mutex_impl_finish(M)	DeleteCriticalSection (M)
 
 
-#elif !defined(HB_NO_MT) && defined(__APPLE__)
+#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
 
 #include <pthread.h>
 typedef pthread_mutex_t hb_mutex_impl_t;
@@ -75,15 +75,50 @@ typedef GStaticMutex hb_mutex_impl_t;
 #define hb_mutex_impl_finish(M)	g_static_mutex_free (M)
 
 
+#elif !defined(HB_NO_MT) && defined(__GNUC__)
+
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
+# include <sched.h>
+# define HB_SCHED_YIELD() sched_yield ()
 #else
+# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
+#endif
 
-#define HB_MUTEX_IMPL_NIL 1
+/* This actually is not a totally awful implementation. */
 typedef volatile int hb_mutex_impl_t;
 #define HB_MUTEX_IMPL_INIT	0
-#define hb_mutex_impl_init(M)	((void) (*(M) = 0))
-#define hb_mutex_impl_lock(M)	((void) (*(M) = 1))
-#define hb_mutex_impl_unlock(M)	((void) (*(M) = 0))
-#define hb_mutex_impl_finish(M)	((void) (*(M) = 2))
+#define hb_mutex_impl_init(M)	*(M) = 0
+#define hb_mutex_impl_lock(M)	HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END
+#define hb_mutex_impl_unlock(M)	__sync_lock_release (M)
+#define hb_mutex_impl_finish(M)	HB_STMT_START {} HB_STMT_END
+
+
+#elif !defined(HB_NO_MT)
+
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
+# include <sched.h>
+# define HB_SCHED_YIELD() sched_yield ()
+#else
+# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
+#endif
+
+#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */
+typedef volatile int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT	0
+#define hb_mutex_impl_init(M)	*(M) = 0
+#define hb_mutex_impl_lock(M)	HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
+#define hb_mutex_impl_unlock(M)	(*(M))--;
+#define hb_mutex_impl_finish(M)	HB_STMT_START {} HB_STMT_END
+
+
+#else /* HB_NO_MT */
+
+typedef int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT	0
+#define hb_mutex_impl_init(M)	HB_STMT_START {} HB_STMT_END
+#define hb_mutex_impl_lock(M)	HB_STMT_START {} HB_STMT_END
+#define hb_mutex_impl_unlock(M)	HB_STMT_START {} HB_STMT_END
+#define hb_mutex_impl_finish(M)	HB_STMT_START {} HB_STMT_END
 
 #endif
 
@@ -91,6 +126,8 @@ typedef volatile int hb_mutex_impl_t;
 #define HB_MUTEX_INIT		{HB_MUTEX_IMPL_INIT}
 struct hb_mutex_t
 {
+  /* TODO Add tracing. */
+
   hb_mutex_impl_t m;
 
   inline void init   (void) { hb_mutex_impl_init   (&m); }
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index cad4426..e86a38d 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2007  Chris Wilson
  * Copyright © 2009,2010  Red Hat, Inc.
- * Copyright © 2011  Google, Inc.
+ * Copyright © 2011,2012  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -68,6 +68,8 @@ struct hb_reference_count_t
 #define HB_USER_DATA_ARRAY_INIT {HB_LOCKABLE_SET_INIT}
 struct hb_user_data_array_t
 {
+  /* TODO Add tracing. */
+
   struct hb_user_data_item_t {
     hb_user_data_key_t *key;
     void *data;
diff --git a/src/hb-warning.cc b/src/hb-warning.cc
index c13731b..4f1f65f 100644
--- a/src/hb-warning.cc
+++ b/src/hb-warning.cc
@@ -28,23 +28,23 @@
 #include "hb-mutex-private.hh"
 
 
-#if !defined(HB_NO_MT) && defined(HB_ATOMIC_INT_NIL)
+#if defined(HB_ATOMIC_INT_NIL)
 #ifdef _MSC_VER
-#pragma message("Could not find any system to define atomic_int macros, library will NOT be thread-safe")
+#pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe")
 #else
-#warning "Could not find any system to define atomic_int macros, library will NOT be thread-safe"
+#warning "Could not find any system to define atomic_int macros, library may NOT be thread-safe"
 #endif
 #endif
 
-#if !defined(HB_NO_MT) && defined(HB_MUTEX_IMPL_NIL)
+#if defined(HB_MUTEX_IMPL_NIL)
 #ifdef _MSC_VER
-#pragma message("Could not find any system to define mutex macros, library will NOT be thread-safe")
+#pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe")
 #else
-#warning "Could not find any system to define mutex macros, library will NOT be thread-safe"
+#warning "Could not find any system to define mutex macros, library may NOT be thread-safe"
 #endif
 #endif
 
-#if !defined(HB_NO_MT) && (defined(HB_ATOMIC_INT_NIL) || defined(HB_MUTEX_IMPL_NIL))
+#if defined(HB_ATOMIC_INT_NIL) || defined(HB_MUTEX_IMPL_NIL)
 #ifdef _MSC_VER
 #pragma message("To suppress these warnings, define HB_NO_MT")
 #else
commit d970d2899b36a2fbd002b224b8bd37b0906fdd5f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 16:06:28 2012 -0400

    Add gcc implementation for atomic ops

diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh
index d6bd1c9..29e4146 100644
--- a/src/hb-atomic-private.hh
+++ b/src/hb-atomic-private.hh
@@ -56,10 +56,15 @@ typedef int32_t hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(OSAtomicAdd32Barrier ((V), &(AI)) - (V))
 
 
+#elif !defined(HB_NO_MT) && defined(__GNUC__)
+
+typedef int hb_atomic_int_t;
+#define hb_atomic_int_add(AI, V)	__sync_fetch_and_add (&(AI), (V))
+
 #elif !defined(HB_NO_MT) && defined(HAVE_GLIB)
 
 #include <glib.h>
-typedef volatile int hb_atomic_int_t;
+typedef int hb_atomic_int_t;
 #if GLIB_CHECK_VERSION(2,29,5)
 #define hb_atomic_int_add(AI, V)	g_atomic_int_add (&(AI), (V))
 #else
@@ -70,7 +75,7 @@ typedef volatile int hb_atomic_int_t;
 #else
 
 #define HB_ATOMIC_INT_NIL 1
-typedef volatile int hb_atomic_int_t;
+typedef int hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
 
 #endif
commit 0e253e97af71e2a7ead153589f61fd579a247502
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 15:37:19 2012 -0400

    Add a mutex to object header
    
    Removes one more static-initialization.  A few more to go.

diff --git a/src/hb-common.cc b/src/hb-common.cc
index bfbba65..c7ee9af 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -314,47 +314,41 @@ hb_script_get_horizontal_direction (hb_script_t script)
 
 /* hb_user_data_array_t */
 
-
-/* NOTE: Currently we use a global lock for user_data access
- * threadsafety.  If one day we add a mutex to any object, we
- * should switch to using that insted for these too.
- */
-
-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_bool_t           replace)
+			   hb_bool_t           replace,
+			   hb_mutex_t         &lock)
 {
   if (!key)
     return false;
 
   if (replace) {
     if (!data && !destroy) {
-      items.remove (key, user_data_lock);
+      items.remove (key, lock);
       return true;
     }
   }
   hb_user_data_item_t item = {key, data, destroy};
-  bool ret = !!items.replace_or_insert (item, user_data_lock, replace);
+  bool ret = !!items.replace_or_insert (item, lock, replace);
 
   return ret;
 }
 
 void *
-hb_user_data_array_t::get (hb_user_data_key_t *key)
+hb_user_data_array_t::get (hb_user_data_key_t *key,
+			   hb_mutex_t         &lock)
 {
   hb_user_data_item_t item = {NULL };
 
-  return items.find (key, &item, user_data_lock) ? item.data : NULL;
+  return items.find (key, &item, lock) ? item.data : NULL;
 }
 
 void
-hb_user_data_array_t::finish (void)
+hb_user_data_array_t::finish (hb_mutex_t &lock)
 {
-  items.finish (user_data_lock);
+  items.finish (lock);
 }
 
 
diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh
index 44b48df..9e061b9 100644
--- a/src/hb-mutex-private.hh
+++ b/src/hb-mutex-private.hh
@@ -50,7 +50,7 @@ typedef CRITICAL_SECTION hb_mutex_impl_t;
 #define hb_mutex_impl_init(M)	InitializeCriticalSection (M)
 #define hb_mutex_impl_lock(M)	EnterCriticalSection (M)
 #define hb_mutex_impl_unlock(M)	LeaveCriticalSection (M)
-#define hb_mutex_impl_free(M)	DeleteCriticalSection (M)
+#define hb_mutex_impl_finish(M)	DeleteCriticalSection (M)
 
 
 #elif !defined(HB_NO_MT) && defined(__APPLE__)
@@ -61,7 +61,7 @@ typedef pthread_mutex_t hb_mutex_impl_t;
 #define hb_mutex_impl_init(M)	pthread_mutex_init (M, NULL)
 #define hb_mutex_impl_lock(M)	pthread_mutex_lock (M)
 #define hb_mutex_impl_unlock(M)	pthread_mutex_unlock (M)
-#define hb_mutex_impl_free(M)	pthread_mutex_destroy (M)
+#define hb_mutex_impl_finish(M)	pthread_mutex_destroy (M)
 
 
 #elif !defined(HB_NO_MT) && defined(HAVE_GLIB)
@@ -72,7 +72,7 @@ typedef GStaticMutex hb_mutex_impl_t;
 #define hb_mutex_impl_init(M)	g_static_mutex_init (M)
 #define hb_mutex_impl_lock(M)	g_static_mutex_lock (M)
 #define hb_mutex_impl_unlock(M)	g_static_mutex_unlock (M)
-#define hb_mutex_impl_free(M)	g_static_mutex_free (M)
+#define hb_mutex_impl_finish(M)	g_static_mutex_free (M)
 
 
 #else
@@ -83,11 +83,12 @@ typedef volatile int hb_mutex_impl_t;
 #define hb_mutex_impl_init(M)	((void) (*(M) = 0))
 #define hb_mutex_impl_lock(M)	((void) (*(M) = 1))
 #define hb_mutex_impl_unlock(M)	((void) (*(M) = 0))
-#define hb_mutex_impl_free(M)	((void) (*(M) = 2))
+#define hb_mutex_impl_finish(M)	((void) (*(M) = 2))
 
 #endif
 
 
+#define HB_MUTEX_INIT		{HB_MUTEX_IMPL_INIT}
 struct hb_mutex_t
 {
   hb_mutex_impl_t m;
@@ -95,20 +96,14 @@ struct hb_mutex_t
   inline void init   (void) { hb_mutex_impl_init   (&m); }
   inline void lock   (void) { hb_mutex_impl_lock   (&m); }
   inline void unlock (void) { hb_mutex_impl_unlock (&m); }
-  inline void free   (void) { hb_mutex_impl_free   (&m); }
+  inline void finish (void) { hb_mutex_impl_finish (&m); }
 };
 
-#define HB_MUTEX_INIT		{HB_MUTEX_IMPL_INIT}
-#define hb_mutex_init(M)	(M)->init ()
-#define hb_mutex_lock(M)	(M)->lock ()
-#define hb_mutex_unlock(M)	(M)->unlock ()
-#define hb_mutex_free(M)	(M)->free ()
-
 
 struct hb_static_mutex_t : hb_mutex_t
 {
   hb_static_mutex_t (void)  { this->init (); }
-  ~hb_static_mutex_t (void) { this->free (); }
+  ~hb_static_mutex_t (void) { this->finish (); }
 
   private:
   NO_COPY (hb_static_mutex_t);
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 8a2cdb6..cad4426 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -47,16 +47,16 @@
 
 /* reference_count */
 
+#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
+#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
 struct hb_reference_count_t
 {
   hb_atomic_int_t ref_count;
 
-#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
-#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
-
-  inline void init (int v) { const_cast<hb_atomic_int_t &> (ref_count) = v; }
+  inline void init (int v) { ref_count = v; }
   inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count),  1); }
   inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), -1); }
+  inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; }
 
   inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; }
 
@@ -65,6 +65,7 @@ struct hb_reference_count_t
 
 /* user_data */
 
+#define HB_USER_DATA_ARRAY_INIT {HB_LOCKABLE_SET_INIT}
 struct hb_user_data_array_t
 {
   struct hb_user_data_item_t {
@@ -78,18 +79,20 @@ struct hb_user_data_array_t
     void finish (void) { if (destroy) destroy (data); }
   };
 
-  hb_lockable_set_t<hb_user_data_item_t, hb_static_mutex_t> items;
+  hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
 
   inline void init (void) { items.init (); }
 
   HB_INTERNAL bool set (hb_user_data_key_t *key,
 			void *              data,
 			hb_destroy_func_t   destroy,
-			hb_bool_t           replace);
+			hb_bool_t           replace,
+			hb_mutex_t         &lock);
 
-  HB_INTERNAL void *get (hb_user_data_key_t *key);
+  HB_INTERNAL void *get (hb_user_data_key_t *key,
+			hb_mutex_t          &lock);
 
-  HB_INTERNAL void finish (void);
+  HB_INTERNAL void finish (hb_mutex_t &lock);
 };
 
 
@@ -98,9 +101,10 @@ struct hb_user_data_array_t
 struct hb_object_header_t
 {
   hb_reference_count_t ref_count;
+  hb_mutex_t lock;
   hb_user_data_array_t user_data;
 
-#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID}
+#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_MUTEX_INIT, HB_USER_DATA_ARRAY_INIT}
 
   static inline void *create (unsigned int size) {
     hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size);
@@ -113,6 +117,7 @@ struct hb_object_header_t
 
   inline void init (void) {
     ref_count.init (1);
+    lock.init ();
     user_data.init ();
   }
 
@@ -132,9 +137,9 @@ struct hb_object_header_t
     if (ref_count.dec () != 1)
       return false;
 
-    ref_count.init (HB_REFERENCE_COUNT_INVALID_VALUE);
-
-    user_data.finish ();
+    ref_count.finish (); /* Do this before user_data */
+    user_data.finish (lock);
+    lock.finish ();
 
     return true;
   }
@@ -146,11 +151,14 @@ struct hb_object_header_t
     if (unlikely (!this || this->is_inert ()))
       return false;
 
-    return user_data.set (key, data, destroy_func, replace);
+    return user_data.set (key, data, destroy_func, replace, lock);
   }
 
   inline void *get_user_data (hb_user_data_key_t *key) {
-    return user_data.get (key);
+    if (unlikely (!this || this->is_inert ()))
+      return NULL;
+
+    return user_data.get (key, lock);
   }
 
   inline void trace (const char *function) const {
diff --git a/src/hb-private.hh b/src/hb-private.hh
index d18b8fb..4a61661 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -239,9 +239,10 @@ typedef int (*hb_compare_func_t) (const void *, const void *);
 /* arrays and maps */
 
 
+#define HB_PREALLOCED_ARRAY_INIT {0}
 template <typename Type, unsigned int StaticSize>
-struct hb_prealloced_array_t {
-
+struct hb_prealloced_array_t
+{
   unsigned int len;
   unsigned int allocated;
   Type *array;
@@ -342,14 +343,12 @@ struct hb_prealloced_array_t {
   }
 };
 
-template <typename Type>
-struct hb_array_t : hb_prealloced_array_t<Type, 2> {};
-
 
+#define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
 template <typename item_t, typename lock_t>
 struct hb_lockable_set_t
 {
-  hb_array_t <item_t> items;
+  hb_prealloced_array_t <item_t, 2> items;
 
   inline void init (void) { items.init (); }
 
commit a2b471df821b32625d127f83b2f90e6d6a967e7e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 15:17:44 2012 -0400

    Remove static initializers from indic

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 53ce263..f168fe1 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -27,16 +27,44 @@
 #include "hb-ot-shape-complex-indic-private.hh"
 #include "hb-ot-shape-private.hh"
 
-static const struct indic_options_t
+struct indic_options_t
 {
-  indic_options_t (void)
-  {
-    char *c = getenv ("HB_OT_INDIC_OPTIONS");
-    uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
+  int initialized : 1;
+  int uniscribe_bug_compatible : 1;
+};
+
+union indic_options_union_t {
+  int i;
+  indic_options_t opts;
+};
+ASSERT_STATIC (sizeof (int) == sizeof (indic_options_union_t));
+
+static indic_options_union_t
+indic_options_init (void)
+{
+  indic_options_union_t u;
+  u.i = 0;
+  u.opts.initialized = 1;
+
+  char *c = getenv ("HB_OT_INDIC_OPTIONS");
+  u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
+
+  return u;
+}
+
+inline indic_options_t
+indic_options (void)
+{
+  static indic_options_union_t options;
+
+  if (unlikely (!options.i)) {
+    /* This is idempotent and threadsafe. */
+    options = indic_options_init ();
   }
 
-  bool uniscribe_bug_compatible;
-} options;
+  return options.opts;
+}
+
 
 static int
 compare_codepoint (const void *pa, const void *pb)
@@ -390,7 +418,7 @@ initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buff
   }
 
   /* Attach ZWJ, ZWNJ, nukta, and halant to previous char to move with them. */
-  if (!options.uniscribe_bug_compatible)
+  if (!indic_options ().uniscribe_bug_compatible)
   {
     /* Please update the Uniscribe branch when touching this! */
     for (unsigned int i = start + 1; i < end; i++)
@@ -487,7 +515,7 @@ initial_reordering_standalone_cluster (const hb_ot_map_t *map,
   /* We treat NBSP/dotted-circle as if they are consonants, so we should just chain.
    * Only if not in compatibility mode that is... */
 
-  if (options.uniscribe_bug_compatible)
+  if (indic_options ().uniscribe_bug_compatible)
   {
     /* For dotted-circle, this is what Uniscribe does:
      * If dotted-circle is the last glyph, it just does nothing.
@@ -732,7 +760,7 @@ final_reordering_syllable (hb_buffer_t *buffer, hb_mask_t *mask_array,
        * Uniscribe doesn't do this.
        * TEST: U+0930,U+094D,U+0915,U+094B,U+094D
        */
-      if (!options.uniscribe_bug_compatible &&
+      if (!indic_options ().uniscribe_bug_compatible &&
 	  unlikely (info[new_reph_pos].indic_category() == OT_H)) {
 	for (unsigned int i = base + 1; i < new_reph_pos; i++)
 	  if (info[i].indic_category() == OT_M) {
@@ -792,7 +820,7 @@ final_reordering_syllable (hb_buffer_t *buffer, hb_mask_t *mask_array,
 
   /* Finish off the clusters and go home! */
 
-  if (!options.uniscribe_bug_compatible)
+  if (!indic_options ().uniscribe_bug_compatible)
   {
     /* This is what Uniscribe does.  Ie. add cluster boundaries after Halant,ZWNJ.
      * This means, half forms are submerged into the main consonants cluster.
commit f06ab8a4262c759b4723614fd28f55ee77aa8466
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 12:31:51 2012 -0400

    Better hide nil objects and make them const

diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index ee997ad..04de762 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -59,19 +59,6 @@ struct _hb_blob_t {
   hb_destroy_func_t destroy;
 };
 
-static hb_blob_t _hb_blob_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  TRUE, /* immutable */
-
-  NULL, /* data */
-  0, /* length */
-  HB_MEMORY_MODE_READONLY, /* mode */
-
-  NULL, /* user_data */
-  NULL  /* destroy */
-};
-
 
 static bool _try_writable (hb_blob_t *blob);
 
@@ -97,7 +84,7 @@ hb_blob_create (const char        *data,
   if (!length || !(blob = hb_object_create<hb_blob_t> ())) {
     if (destroy)
       destroy (user_data);
-    return &_hb_blob_nil;
+    return hb_blob_get_empty ();
   }
 
   blob->data = data;
@@ -111,7 +98,7 @@ hb_blob_create (const char        *data,
     blob->mode = HB_MEMORY_MODE_READONLY;
     if (!_try_writable (blob)) {
       hb_blob_destroy (blob);
-      return &_hb_blob_nil;
+      return hb_blob_get_empty ();
     }
   }
 
@@ -126,7 +113,7 @@ hb_blob_create_sub_blob (hb_blob_t    *parent,
   hb_blob_t *blob;
 
   if (!length || offset >= parent->length)
-    return &_hb_blob_nil;
+    return hb_blob_get_empty ();
 
   hb_blob_make_immutable (parent);
 
@@ -142,7 +129,20 @@ hb_blob_create_sub_blob (hb_blob_t    *parent,
 hb_blob_t *
 hb_blob_get_empty (void)
 {
-  return &_hb_blob_nil;
+  static const hb_blob_t _hb_blob_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    TRUE, /* immutable */
+
+    NULL, /* data */
+    0, /* length */
+    HB_MEMORY_MODE_READONLY, /* mode */
+
+    NULL, /* user_data */
+    NULL  /* destroy */
+  };
+
+  return const_cast<hb_blob_t *> (&_hb_blob_nil);
 }
 
 hb_blob_t *
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index c566a4a..144a68c 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -37,21 +37,8 @@
 #define HB_DEBUG_BUFFER (HB_DEBUG+0)
 #endif
 
-
-static hb_buffer_t _hb_buffer_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  &_hb_unicode_funcs_default,
-  {
-    HB_DIRECTION_INVALID,
-    HB_SCRIPT_INVALID,
-    NULL,
-  },
-
-  TRUE, /* in_error */
-  TRUE, /* have_output */
-  TRUE  /* have_positions */
-};
+#define _HB_BUFFER_UNICODE_FUNCS_DEFAULT _hb_unicode_funcs_default
+#define _HB_BUFFER_PROPS_DEFAULT { HB_DIRECTION_INVALID, HB_SCRIPT_INVALID, HB_LANGUAGE_INVALID }
 
 /* Here is how the buffer works internally:
  *
@@ -154,9 +141,10 @@ hb_buffer_t::reset (void)
     return;
 
   hb_unicode_funcs_destroy (unicode);
-  unicode = _hb_buffer_nil.unicode;
+  unicode = _HB_BUFFER_UNICODE_FUNCS_DEFAULT;
 
-  props = _hb_buffer_nil.props;
+  hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT;
+  props = default_props;
 
   in_error = FALSE;
   have_output = FALSE;
@@ -543,7 +531,7 @@ hb_buffer_create ()
   hb_buffer_t *buffer;
 
   if (!(buffer = hb_object_create<hb_buffer_t> ()))
-    return &_hb_buffer_nil;
+    return hb_buffer_get_empty ();
 
   buffer->reset ();
 
@@ -553,7 +541,18 @@ hb_buffer_create ()
 hb_buffer_t *
 hb_buffer_get_empty (void)
 {
-  return &_hb_buffer_nil;
+  static const hb_buffer_t _hb_buffer_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    _HB_BUFFER_UNICODE_FUNCS_DEFAULT,
+    _HB_BUFFER_PROPS_DEFAULT,
+
+    TRUE, /* in_error */
+    TRUE, /* have_output */
+    TRUE  /* have_positions */
+  };
+
+  return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
 }
 
 hb_buffer_t *
@@ -601,7 +600,7 @@ hb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
     return;
 
   if (!unicode)
-    unicode = _hb_buffer_nil.unicode;
+    unicode = _HB_BUFFER_UNICODE_FUNCS_DEFAULT;
 
   hb_unicode_funcs_reference (unicode);
   hb_unicode_funcs_destroy (buffer->unicode);
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 1862ac3..783a2b0 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -217,7 +217,7 @@ hb_font_get_glyph_from_name_nil (hb_font_t *font,
 }
 
 
-static hb_font_funcs_t _hb_font_funcs_nil = {
+static const hb_font_funcs_t _hb_font_funcs_nil = {
   HB_OBJECT_HEADER_STATIC,
 
   TRUE, /* immutable */
@@ -236,7 +236,7 @@ hb_font_funcs_create (void)
   hb_font_funcs_t *ffuncs;
 
   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
-    return &_hb_font_funcs_nil;
+    return hb_font_funcs_get_empty ();
 
   ffuncs->get = _hb_font_funcs_nil.get;
 
@@ -246,7 +246,7 @@ hb_font_funcs_create (void)
 hb_font_funcs_t *
 hb_font_funcs_get_empty (void)
 {
-  return &_hb_font_funcs_nil;
+  return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil);
 }
 
 hb_font_funcs_t *
@@ -578,7 +578,7 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
  * hb_face_t
  */
 
-static hb_face_t _hb_face_nil = {
+static const hb_face_t _hb_face_nil = {
   HB_OBJECT_HEADER_STATIC,
 
   TRUE, /* immutable */
@@ -604,7 +604,7 @@ hb_face_create_for_tables (hb_reference_table_func_t  reference_table,
   if (!reference_table || !(face = hb_object_create<hb_face_t> ())) {
     if (destroy)
       destroy (user_data);
-    return &_hb_face_nil;
+    return hb_face_get_empty ();
   }
 
   face->reference_table = reference_table;
@@ -671,12 +671,12 @@ hb_face_create (hb_blob_t    *blob,
   hb_face_t *face;
 
   if (unlikely (!blob || !hb_blob_get_length (blob)))
-    return &_hb_face_nil;
+    return hb_face_get_empty ();
 
   hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Sanitizer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
 
   if (unlikely (!closure))
-    return &_hb_face_nil;
+    return hb_face_get_empty ();
 
   face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
 				    closure,
@@ -690,7 +690,7 @@ hb_face_create (hb_blob_t    *blob,
 hb_face_t *
 hb_face_get_empty (void)
 {
-  return &_hb_face_nil;
+  return const_cast<hb_face_t *> (&_hb_face_nil);
 }
 
 
@@ -811,40 +811,21 @@ hb_face_get_upem (hb_face_t *face)
  * hb_font_t
  */
 
-static hb_font_t _hb_font_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  TRUE, /* immutable */
-
-  NULL, /* parent */
-  &_hb_face_nil,
-
-  0, /* x_scale */
-  0, /* y_scale */
-
-  0, /* x_ppem */
-  0, /* y_ppem */
-
-  &_hb_font_funcs_nil, /* klass */
-  NULL, /* user_data */
-  NULL  /* destroy */
-};
-
 hb_font_t *
 hb_font_create (hb_face_t *face)
 {
   hb_font_t *font;
 
   if (unlikely (!face))
-    face = &_hb_face_nil;
+    face = hb_face_get_empty ();
   if (unlikely (hb_object_is_inert (face)))
-    return &_hb_font_nil;
+    return hb_font_get_empty ();
   if (!(font = hb_object_create<hb_font_t> ()))
-    return &_hb_font_nil;
+    return hb_font_get_empty ();
 
   hb_face_make_immutable (face);
   font->face = hb_face_reference (face);
-  font->klass = &_hb_font_funcs_nil;
+  font->klass = hb_font_funcs_get_empty ();
 
   return font;
 }
@@ -853,7 +834,7 @@ hb_font_t *
 hb_font_create_sub_font (hb_font_t *parent)
 {
   if (unlikely (!parent))
-    return &_hb_font_nil;
+    return hb_font_get_empty ();
 
   hb_font_t *font = hb_font_create (parent->face);
 
@@ -868,15 +849,32 @@ hb_font_create_sub_font (hb_font_t *parent)
   font->x_ppem = parent->x_ppem;
   font->y_ppem = parent->y_ppem;
 
-  font->klass = &_hb_font_funcs_nil;
-
   return font;
 }
 
 hb_font_t *
 hb_font_get_empty (void)
 {
-  return &_hb_font_nil;
+  static const hb_font_t _hb_font_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    TRUE, /* immutable */
+
+    NULL, /* parent */
+    const_cast<hb_face_t *> (&_hb_face_nil),
+
+    0, /* x_scale */
+    0, /* y_scale */
+
+    0, /* x_ppem */
+    0, /* y_ppem */
+
+    const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
+    NULL, /* user_data */
+    NULL  /* destroy */
+  };
+
+  return const_cast<hb_font_t *> (&_hb_font_nil);
 }
 
 hb_font_t *
@@ -960,7 +958,7 @@ hb_font_set_funcs (hb_font_t         *font,
     font->destroy (font->user_data);
 
   if (!klass)
-    klass = &_hb_font_funcs_nil;
+    klass = hb_font_funcs_get_empty ();
 
   hb_font_funcs_reference (klass);
   hb_font_funcs_destroy (font->klass);
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 90adc0d..aa09bd7 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -271,22 +271,22 @@ hb_ft_get_glyph_from_name (hb_font_t *font,
 }
 
 
-static hb_font_funcs_t ft_ffuncs = {
-  HB_OBJECT_HEADER_STATIC,
+static hb_font_funcs_t *
+_hb_ft_get_font_funcs (void)
+{
+  static const hb_font_funcs_t ft_ffuncs = {
+    HB_OBJECT_HEADER_STATIC,
 
-  TRUE, /* immutable */
+    TRUE, /* immutable */
 
-  {
+    {
 #define HB_FONT_FUNC_IMPLEMENT(name) hb_ft_get_##name,
-    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
-  }
-};
+    }
+  };
 
-static hb_font_funcs_t *
-_hb_ft_get_font_funcs (void)
-{
-  return &ft_ffuncs;
+  return const_cast<hb_font_funcs_t *> (&ft_ffuncs);
 }
 
 
@@ -398,26 +398,21 @@ hb_ft_font_create (FT_Face           ft_face,
 }
 
 
-
-
-static FT_Library ft_library;
-static hb_bool_t ft_library_initialized;
-static struct ft_library_destructor {
-  ~ft_library_destructor (void) {
-    if (ft_library)
-      FT_Done_FreeType (ft_library);
-  }
-} static_ft_library_destructor;
-
 static FT_Library
 _get_ft_library (void)
 {
-  if (unlikely (!ft_library_initialized)) {
-    FT_Init_FreeType (&ft_library);
-    ft_library_initialized = TRUE;
-  }
+  static struct ft_library_singleton
+  {
+    ft_library_singleton (void) {
+      FT_Init_FreeType (&ft_library);
+    }
+    ~ft_library_singleton (void) {
+      FT_Done_FreeType (ft_library);
+    }
+    FT_Library ft_library;
+  } ft_library_singleton;
 
-  return ft_library;
+  return ft_library_singleton.ft_library;
 }
 
 static void
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 26d40a3..33369b2 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -337,22 +337,21 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
 }
 
 
-extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_glib;
-hb_unicode_funcs_t _hb_glib_unicode_funcs = {
-  HB_OBJECT_HEADER_STATIC,
+hb_unicode_funcs_t *
+hb_glib_get_unicode_funcs (void)
+{
+  static const hb_unicode_funcs_t _hb_glib_unicode_funcs = {
+    HB_OBJECT_HEADER_STATIC,
 
-  NULL, /* parent */
-  TRUE, /* immutable */
-  {
+    NULL, /* parent */
+    TRUE, /* immutable */
+    {
 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
-    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
-  }
-};
+    }
+  };
 
-hb_unicode_funcs_t *
-hb_glib_get_unicode_funcs (void)
-{
-  return &_hb_glib_unicode_funcs;
+  return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs);
 }
 
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 5cd0143..78cbc1a 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -269,23 +269,22 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
   return ret;
 }
 
-extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_icu;
-hb_unicode_funcs_t _hb_icu_unicode_funcs = {
-  HB_OBJECT_HEADER_STATIC,
+hb_unicode_funcs_t *
+hb_icu_get_unicode_funcs (void)
+{
+  static const hb_unicode_funcs_t _hb_icu_unicode_funcs = {
+    HB_OBJECT_HEADER_STATIC,
 
-  NULL, /* parent */
-  TRUE, /* immutable */
-  {
+    NULL, /* parent */
+    TRUE, /* immutable */
+    {
 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_icu_unicode_##name,
-    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_UNICODE_FUNC_IMPLEMENT
-  }
-};
+    }
+  };
 
-hb_unicode_funcs_t *
-hb_icu_get_unicode_funcs (void)
-{
-  return &_hb_icu_unicode_funcs;
+  return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs);
 }
 
 
diff --git a/src/hb-set.cc b/src/hb-set.cc
index 5045386..a044199 100644
--- a/src/hb-set.cc
+++ b/src/hb-set.cc
@@ -30,12 +30,6 @@
 
 /* Public API */
 
-static hb_set_t _hb_set_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  {0} /* elts */
-};
-
 
 hb_set_t *
 hb_set_create ()
@@ -43,7 +37,7 @@ hb_set_create ()
   hb_set_t *set;
 
   if (!(set = hb_object_create<hb_set_t> ()))
-    return &_hb_set_nil;
+    return hb_set_get_empty ();
 
   set->clear ();
 
@@ -53,7 +47,13 @@ hb_set_create ()
 hb_set_t *
 hb_set_get_empty (void)
 {
-  return &_hb_set_nil;
+  static const hb_set_t _hb_set_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    {0} /* elts */
+  };
+
+  return const_cast<hb_set_t *> (&_hb_set_nil);
 }
 
 hb_set_t *
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index ddba1ac..9a900f5 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -91,15 +91,14 @@ struct _hb_unicode_funcs_t {
 
 
 #ifdef HAVE_GLIB
-extern HB_INTERNAL hb_unicode_funcs_t _hb_glib_unicode_funcs;
-#define _hb_unicode_funcs_default _hb_glib_unicode_funcs
+extern "C" hb_unicode_funcs_t * hb_glib_get_unicode_funcs (void);
+#define _hb_unicode_funcs_default hb_glib_get_unicode_funcs ()
 #elif defined(HAVE_ICU)
-extern HB_INTERNAL hb_unicode_funcs_t _hb_icu_unicode_funcs;
-#define _hb_unicode_funcs_default _hb_icu_unicode_funcs
+extern "C" hb_unicode_funcs_t * hb_icu_get_unicode_funcs (void);
+#define _hb_unicode_funcs_default hb_icu_get_unicode_funcs ()
 #else
 #define HB_UNICODE_FUNCS_NIL 1
-extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_nil;
-#define _hb_unicode_funcs_default _hb_unicode_funcs_nil
+#define _hb_unicode_funcs_default hb_unicode_funcs_get_empty ()
 #endif
 
 
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index f2fbebb..b7a5f8d 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -99,23 +99,11 @@ hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
 }
 
 
-hb_unicode_funcs_t _hb_unicode_funcs_nil = {
-  HB_OBJECT_HEADER_STATIC,
-
-  NULL, /* parent */
-  TRUE, /* immutable */
-  {
-#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
-    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_UNICODE_FUNC_IMPLEMENT
-  }
-};
-
 
 hb_unicode_funcs_t *
 hb_unicode_funcs_get_default (void)
 {
-  return &_hb_unicode_funcs_default;
+  return _hb_unicode_funcs_default;
 }
 
 hb_unicode_funcs_t *
@@ -124,10 +112,10 @@ hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
   hb_unicode_funcs_t *ufuncs;
 
   if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
-    return &_hb_unicode_funcs_nil;
+    return hb_unicode_funcs_get_empty ();
 
   if (!parent)
-    parent = &_hb_unicode_funcs_nil;
+    parent = hb_unicode_funcs_get_empty ();
 
   hb_unicode_funcs_make_immutable (parent);
   ufuncs->parent = hb_unicode_funcs_reference (parent);
@@ -145,7 +133,19 @@ hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
 hb_unicode_funcs_t *
 hb_unicode_funcs_get_empty (void)
 {
-  return &_hb_unicode_funcs_nil;
+  static const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    NULL, /* parent */
+    TRUE, /* immutable */
+    {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
+      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+    }
+  };
+
+  return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
 }
 
 hb_unicode_funcs_t *
@@ -205,7 +205,7 @@ hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
 hb_unicode_funcs_t *
 hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
 {
-  return ufuncs->parent ? ufuncs->parent : &_hb_unicode_funcs_nil;
+  return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
 }
 
 
commit bf93b636c4963cbc32d5fba7ace1053db6719192
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 14:17:32 2012 -0400

    Remove constructor from hb_prealloced_array_t
    
    This was causing all object types to be non-POD and have static
    initializers.  We don't need that!
    
    Now, most nil objects just moved from .bss to .data.  Fixing for that
    coming soon.

diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index e3c9d21..8a2cdb6 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -80,6 +80,8 @@ struct hb_user_data_array_t
 
   hb_lockable_set_t<hb_user_data_item_t, hb_static_mutex_t> items;
 
+  inline void init (void) { items.init (); }
+
   HB_INTERNAL bool set (hb_user_data_key_t *key,
 			void *              data,
 			hb_destroy_func_t   destroy,
@@ -111,6 +113,7 @@ struct hb_object_header_t
 
   inline void init (void) {
     ref_count.init (1);
+    user_data.init ();
   }
 
   inline bool is_inert (void) const {
diff --git a/src/hb-private.hh b/src/hb-private.hh
index aa86072..d18b8fb 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -247,7 +247,7 @@ struct hb_prealloced_array_t {
   Type *array;
   Type static_array[StaticSize];
 
-  hb_prealloced_array_t (void) { memset (this, 0, sizeof (*this)); }
+  void init (void) { memset (this, 0, sizeof (*this)); }
 
   inline Type& operator [] (unsigned int i) { return array[i]; }
   inline const Type& operator [] (unsigned int i) const { return array[i]; }
@@ -351,6 +351,8 @@ struct hb_lockable_set_t
 {
   hb_array_t <item_t> items;
 
+  inline void init (void) { items.init (); }
+
   template <typename T>
   inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
   {
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
index 9d8ba4a..b8407e9 100644
--- a/src/hb-set-private.hh
+++ b/src/hb-set-private.hh
@@ -37,6 +37,7 @@
 struct _hb_set_t
 {
   inline void init (void) {
+    header.init ();
     clear ();
   }
   inline void fini (void) {
commit 7037291aacb858f8090fd7d9028c196cc1a21703
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 13:30:11 2012 -0400

    Check for atexit()

diff --git a/configure.ac b/configure.ac
index 073228b..44b0df4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,7 +52,7 @@ AC_SUBST(HB_LIBTOOL_VERSION_INFO)
 dnl GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
 
 # Functions and headers
-AC_CHECK_FUNCS(mprotect sysconf getpagesize mmap _setmode isatty)
+AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap _setmode isatty)
 AC_CHECK_HEADERS(unistd.h sys/mman.h io.h)
 
 # Compiler flags
commit f1971a217424bd6db5c7072ba5cf197f318d4e47
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Jun 5 13:04:20 2012 -0400

    Fix warnings

diff --git a/src/indic.cc b/src/indic.cc
index e00311d..3b44076 100644
--- a/src/indic.cc
+++ b/src/indic.cc
@@ -41,6 +41,6 @@ main (void)
 
     hb_codepoint_t a, b;
     if (!hb_unicode_decompose (funcs, u, &a, &b))
-      printf ("U+%04X\n", u);
+      printf ("U+%04X %x %x\n", u, category, position);
   }
 }



More information about the HarfBuzz mailing list