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

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Apr 23 16:54:09 PDT 2010


 src/hb-blob.c                        |    5 -
 src/hb-buffer.c                      |    6 -
 src/hb-font.cc                       |   37 ++++++++---
 src/hb-ft.c                          |   31 ++++++---
 src/hb-ft.h                          |    1 
 src/hb-open-file-private.hh          |  109 ++++++++++++++++++++++++-----------
 src/hb-open-type-private.hh          |   75 +++++++++---------------
 src/hb-ot-layout-common-private.hh   |   12 +--
 src/hb-ot-layout-gdef-private.hh     |    2 
 src/hb-ot-layout-gpos-private.hh     |   11 +--
 src/hb-ot-layout-gsub-private.hh     |   15 +---
 src/hb-ot-layout-gsubgpos-private.hh |    2 
 src/hb-ot-layout.cc                  |   10 +--
 src/hb-ot-shape.c                    |    9 +-
 src/hb-shape.c                       |   32 +++++-----
 src/hb-unicode.c                     |    8 +-
 src/main.cc                          |    8 +-
 17 files changed, 209 insertions(+), 164 deletions(-)

New commits:
commit ad3653751b1e4a03f7058200cb83f64db46722d5
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 19:43:40 2010 -0400

    Typo

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index ccd26dc..106af0c 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -295,7 +295,7 @@ struct Sanitizer
     if (sane) {
       if (context.edit_count) {
 #if HB_DEBUG_SANITIZE
-	fprintf (stderr, "Sanitizer %p passed first round with %d edits; going a second round %s\n",
+	fprintf (stderr, "Sanitizer %p passed first round with %d edits; doing a second round %s\n",
 		 blob, context.edit_count, __PRETTY_FUNCTION__);
 #endif
         /* sanitize again to ensure no toe-stepping */
commit 990443e5f282ad61de00dcf1ebff9cf1d5bc2d70
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 17:53:32 2010 -0400

    Remove lock_instance()

diff --git a/src/hb-font.cc b/src/hb-font.cc
index 5e4e02c..4fdb569 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -227,7 +227,7 @@ _hb_face_get_table_from_blob (hb_tag_t tag, void *user_data)
 {
   hb_face_t *face = (hb_face_t *) user_data;
 
-  const OpenTypeFontFile &ot_file = Sanitizer<OpenTypeFontFile>::lock_instance (face->blob);
+  const OpenTypeFontFile &ot_file = *CastP<OpenTypeFontFile> (hb_blob_lock (face->blob));
   const OpenTypeFontFace &ot_face = ot_file.get_face (face->index);
 
   const OpenTypeTable &table = ot_face.get_table_by_tag (tag);
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index daf0c40..ccd26dc 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -332,10 +332,6 @@ struct Sanitizer
       return hb_blob_create_empty ();
     }
   }
-
-  static const Type& lock_instance (hb_blob_t *blob) {
-    return *CastP<Type> (hb_blob_lock (blob));
-  }
 };
 
 
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 96a0d9a..757722b 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -47,13 +47,13 @@ _hb_ot_layout_init (hb_face_t *face)
   memset (layout, 0, sizeof (*layout));
 
   layout->gdef_blob = Sanitizer<GDEF>::sanitize (hb_face_get_table (face, HB_OT_TAG_GDEF));
-  layout->gdef = &Sanitizer<GDEF>::lock_instance (layout->gdef_blob);
+  layout->gdef = CastP<GDEF> (hb_blob_lock (layout->gdef_blob));
 
   layout->gsub_blob = Sanitizer<GSUB>::sanitize (hb_face_get_table (face, HB_OT_TAG_GSUB));
-  layout->gsub = &Sanitizer<GSUB>::lock_instance (layout->gsub_blob);
+  layout->gsub = CastP<GSUB> (hb_blob_lock (layout->gsub_blob));
 
   layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_get_table (face, HB_OT_TAG_GPOS));
-  layout->gpos = &Sanitizer<GPOS>::lock_instance (layout->gpos_blob);
+  layout->gpos = CastP<GPOS> (hb_blob_lock (layout->gpos_blob));
 }
 
 void
commit 187454c595559ce48d072fee6bccb51f3de283d4
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 16:35:01 2010 -0400

    Add different casts from pointer and ref to avoid bugs

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 232a61e..daf0c40 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -49,14 +49,22 @@ template <typename Type>
 inline char * CharP (Type* X)
 { return reinterpret_cast<char *>(X); }
 
-/* Cast to struct T& */
+/* Cast to struct T, reference to reference */
 template<typename Type, typename TObject>
-inline const Type& Cast(const TObject &X)
+inline const Type& CastR(const TObject &X)
 { return reinterpret_cast<const Type&> (X); }
 template<typename Type, typename TObject>
-inline Type& Cast(TObject &X)
+inline Type& CastR(TObject &X)
 { return reinterpret_cast<Type&> (X); }
 
+/* Cast to struct T, pointer to pointer */
+template<typename Type, typename TObject>
+inline const Type* CastP(const TObject *X)
+{ return reinterpret_cast<const Type*> (X); }
+template<typename Type, typename TObject>
+inline Type* CastP(TObject *X)
+{ return reinterpret_cast<Type*> (X); }
+
 /* StructAtOffset<T>(X,Ofs) returns the struct T& that is placed at memory
  * location of X plus Ofs bytes. */
 template<typename Type, typename TObject>
@@ -91,7 +99,7 @@ static const void *_NullPool[32 / sizeof (void *)];
 template <typename Type>
 static inline const Type& Null () {
   ASSERT_STATIC (sizeof (Type) <= sizeof (_NullPool));
-  return Cast<Type> (*_NullPool);
+  return *CastP<Type> (_NullPool);
 }
 
 /* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
@@ -99,7 +107,7 @@ static inline const Type& Null () {
 static const char _Null##Type[size + 1] = data; /* +1 is for nul-termination in data */ \
 template <> \
 inline const Type& Null<Type> () { \
-  return Cast<Type> (*_Null##Type); \
+  return *CastP<Type> (_Null##Type); \
 } /* The following line really exists such that we end in a place needing semicolon */ \
 ASSERT_STATIC (sizeof (Type) + 1 <= sizeof (_Null##Type))
 
@@ -281,7 +289,7 @@ struct Sanitizer
     _hb_sanitize_init (&context, blob);
 
     /* Note: We drop const here */
-    Type *t = &Cast<Type> (* (char *) CharP(context.start));
+    Type *t = CastP<Type> ((void *) context.start);
 
     sane = t->sanitize (SANITIZE_ARG_INIT);
     if (sane) {
@@ -326,7 +334,7 @@ struct Sanitizer
   }
 
   static const Type& lock_instance (hb_blob_t *blob) {
-    return Cast<Type> (* (const char *) hb_blob_lock (blob));
+    return *CastP<Type> (hb_blob_lock (blob));
   }
 };
 
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 73ac56d..777874b 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -1445,7 +1445,7 @@ struct PosLookupSubTable
 struct PosLookup : Lookup
 {
   inline const PosLookupSubTable& get_subtable (unsigned int i) const
-  { return this+Cast<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
+  { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
 
   inline bool apply_once (hb_ot_layout_context_t *context,
 			  hb_buffer_t    *buffer,
@@ -1504,7 +1504,7 @@ struct PosLookup : Lookup
   inline bool sanitize (SANITIZE_ARG_DEF) {
     TRACE_SANITIZE ();
     if (HB_UNLIKELY (!Lookup::sanitize (SANITIZE_ARG))) return false;
-    OffsetArrayOf<PosLookupSubTable> &list = Cast<OffsetArrayOf<PosLookupSubTable> > (subTable);
+    OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable);
     return SANITIZE_THIS (list);
   }
 };
@@ -1521,7 +1521,7 @@ struct GPOS : GSUBGPOS
   static const hb_tag_t Tag	= HB_OT_TAG_GPOS;
 
   inline const PosLookup& get_lookup (unsigned int i) const
-  { return Cast<PosLookup> (GSUBGPOS::get_lookup (i)); }
+  { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
 
   inline bool position_lookup (hb_ot_layout_context_t *context,
 			       hb_buffer_t  *buffer,
@@ -1532,7 +1532,7 @@ struct GPOS : GSUBGPOS
   inline bool sanitize (SANITIZE_ARG_DEF) {
     TRACE_SANITIZE ();
     if (HB_UNLIKELY (!GSUBGPOS::sanitize (SANITIZE_ARG))) return false;
-    OffsetTo<PosLookupList> &list = Cast<OffsetTo<PosLookupList> > (lookupList);
+    OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
     return SANITIZE_THIS (list);
   }
 };
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index fc3bb29..77c27a8 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -743,7 +743,7 @@ struct SubstLookupSubTable
 struct SubstLookup : Lookup
 {
   inline const SubstLookupSubTable& get_subtable (unsigned int i) const
-  { return this+Cast<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i]; }
+  { return this+CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i]; }
 
   inline static bool lookup_type_is_reverse (unsigned int lookup_type)
   { return lookup_type == SubstLookupSubTable::ReverseChainSingle; }
@@ -752,7 +752,7 @@ struct SubstLookup : Lookup
   {
     unsigned int type = get_type ();
     if (HB_UNLIKELY (type == SubstLookupSubTable::Extension))
-      return Cast<ExtensionSubst> (get_subtable(0)).is_reverse ();
+      return CastR<ExtensionSubst> (get_subtable(0)).is_reverse ();
     return lookup_type_is_reverse (type);
   }
 
@@ -839,7 +839,7 @@ struct SubstLookup : Lookup
   inline bool sanitize (SANITIZE_ARG_DEF) {
     TRACE_SANITIZE ();
     if (HB_UNLIKELY (!Lookup::sanitize (SANITIZE_ARG))) return false;
-    OffsetArrayOf<SubstLookupSubTable> &list = Cast<OffsetArrayOf<SubstLookupSubTable> > (subTable);
+    OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable);
     return SANITIZE_THIS (list);
   }
 };
@@ -856,7 +856,7 @@ struct GSUB : GSUBGPOS
   static const hb_tag_t Tag	= HB_OT_TAG_GSUB;
 
   inline const SubstLookup& get_lookup (unsigned int i) const
-  { return Cast<SubstLookup> (GSUBGPOS::get_lookup (i)); }
+  { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
 
   inline bool substitute_lookup (hb_ot_layout_context_t *context,
 				 hb_buffer_t  *buffer,
@@ -868,7 +868,7 @@ struct GSUB : GSUBGPOS
   inline bool sanitize (SANITIZE_ARG_DEF) {
     TRACE_SANITIZE ();
     if (HB_UNLIKELY (!GSUBGPOS::sanitize (SANITIZE_ARG))) return false;
-    OffsetTo<SubstLookupList> &list = Cast<OffsetTo<SubstLookupList> > (lookupList);
+    OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
     return SANITIZE_THIS (list);
   }
 };
@@ -896,7 +896,7 @@ inline bool ExtensionSubst::is_reverse (void) const
 {
   unsigned int type = get_type ();
   if (HB_UNLIKELY (type == SubstLookupSubTable::Extension))
-    return Cast<ExtensionSubst> (get_subtable()).is_reverse ();
+    return CastR<ExtensionSubst> (get_subtable()).is_reverse ();
   return SubstLookup::lookup_type_is_reverse (type);
 }
 
diff --git a/src/main.cc b/src/main.cc
index badf91b..2e0927a 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -61,7 +61,7 @@ main (int argc, char **argv)
 
   printf ("Opened font file %s: %d bytes long\n", argv[1], len);
 
-  const OpenTypeFontFile &ot = Cast<OpenTypeFontFile> (font_data);
+  const OpenTypeFontFile &ot = *CastP<OpenTypeFontFile> (font_data);
 
   switch (ot.get_tag ()) {
   case OpenTypeFontFile::TrueTypeTag:
@@ -99,7 +99,7 @@ main (int argc, char **argv)
       case GSUBGPOS::GPOSTag:
 	{
 
-	const GSUBGPOS &g = Cast<GSUBGPOS> (font_data + table.offset);
+	const GSUBGPOS &g = *CastP<GSUBGPOS> (font_data + table.offset);
 
 	int num_scripts = g.get_script_count ();
 	printf ("    %d script(s) found in table\n", num_scripts);
@@ -162,7 +162,7 @@ main (int argc, char **argv)
       case GDEF::Tag:
 	{
 
-	const GDEF &gdef = Cast<GDEF> (font_data + table.offset);
+	const GDEF &gdef = *CastP<GDEF> (font_data + table.offset);
 
 	printf ("    Has %sglyph classes\n",
 		  gdef.has_glyph_classes () ? "" : "no ");
commit efb324a46ff64adb4ec8612b4089e8daff1e6d8e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 16:22:54 2010 -0400

    Remove GET_FOR_DATA macros
    
    The major-version check is now handled by sanitize.  If major
    doesn't match, we reject and fall back to the Null object.

diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index f45ba8f..a3efaf1 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -66,8 +66,6 @@ typedef struct OffsetTable
 {
   friend struct OpenTypeFontFile;
 
-  STATIC_DEFINE_GET_FOR_DATA (OffsetTable);
-
   inline unsigned int get_table_count (void) const
   { return numTables; }
   inline const Tag& get_table_tag (unsigned int i) const
@@ -201,8 +199,6 @@ struct OpenTypeFontFile
   static const hb_tag_t TrueTypeTag	= HB_TAG ( 0 , 1 , 0 , 0 );
   static const hb_tag_t TTCTag		= HB_TAG ('t','t','c','f');
 
-  STATIC_DEFINE_GET_FOR_DATA (OpenTypeFontFile);
-
   inline hb_tag_t get_tag (void) const { return u.tag; }
 
   inline unsigned int get_face_count (void) const
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 1a11cd1..232a61e 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -107,25 +107,6 @@ ASSERT_STATIC (sizeof (Type) + 1 <= sizeof (_Null##Type))
 #define Null(Type) Null<Type>()
 
 
-/* get_for_data() is a static class method returning a reference to an
- * instance of Type located at the input data location.  It's just a
- * fancy, NULL-safe, cast! */
-#define STATIC_DEFINE_GET_FOR_DATA(Type) \
-  static inline const Type& get_for_data (const char *data) \
-  { \
-    if (HB_UNLIKELY (data == NULL)) return Null(Type); \
-    return Cast<Type> (*data); \
-  }
-/* Like get_for_data(), but checks major version first. */
-#define STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION(Type, MajorMin, MajorMax) \
-  static inline const Type& get_for_data (const char *data) \
-  { \
-    if (HB_UNLIKELY (data == NULL)) return Null(Type); \
-    const Type& t = Cast<Type> (*data); \
-    if (HB_UNLIKELY (t.version.major < MajorMin || t.version.major > MajorMax)) return Null(Type); \
-    return t; \
-  }
-
 
 /*
  * Sanitize
@@ -299,7 +280,7 @@ struct Sanitizer
 
     _hb_sanitize_init (&context, blob);
 
-    /* We drop const here */
+    /* Note: We drop const here */
     Type *t = &Cast<Type> (* (char *) CharP(context.start));
 
     sane = t->sanitize (SANITIZE_ARG_INIT);
@@ -345,7 +326,7 @@ struct Sanitizer
   }
 
   static const Type& lock_instance (hb_blob_t *blob) {
-    return Type::get_for_data (hb_blob_lock (blob));
+    return Cast<Type> (* (const char *) hb_blob_lock (blob));
   }
 };
 
diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh
index 4de5740..14bef8c 100644
--- a/src/hb-ot-layout-gdef-private.hh
+++ b/src/hb-ot-layout-gdef-private.hh
@@ -314,8 +314,6 @@ struct GDEF
     ComponentGlyph	= 4
   };
 
-  STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (GDEF, 1, 1);
-
   inline bool has_glyph_classes () const { return glyphClassDef != 0; }
   inline hb_ot_layout_class_t get_glyph_class (hb_codepoint_t glyph) const
   { return (this+glyphClassDef).get_class (glyph); }
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 65937fb..73ac56d 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -1520,9 +1520,6 @@ struct GPOS : GSUBGPOS
 {
   static const hb_tag_t Tag	= HB_OT_TAG_GPOS;
 
-  static inline const GPOS& get_for_data (const char *data)
-  { return Cast<GPOS> (GSUBGPOS::get_for_data (data)); }
-
   inline const PosLookup& get_lookup (unsigned int i) const
   { return Cast<PosLookup> (GSUBGPOS::get_lookup (i)); }
 
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 0d6bbc9..fc3bb29 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -855,9 +855,6 @@ struct GSUB : GSUBGPOS
 {
   static const hb_tag_t Tag	= HB_OT_TAG_GSUB;
 
-  static inline const GSUB& get_for_data (const char *data)
-  { return Cast<GSUB> (GSUBGPOS::get_for_data (data)); }
-
   inline const SubstLookup& get_lookup (unsigned int i) const
   { return Cast<SubstLookup> (GSUBGPOS::get_lookup (i)); }
 
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 74d9b04..73e6283 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -896,8 +896,6 @@ struct GSUBGPOS
   static const hb_tag_t GSUBTag	= HB_OT_TAG_GSUB;
   static const hb_tag_t GPOSTag	= HB_OT_TAG_GPOS;
 
-  STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (GSUBGPOS, 1, 1);
-
   inline unsigned int get_script_count (void) const
   { return (this+scriptList).len; }
   inline const Tag& get_script_tag (unsigned int i) const
diff --git a/src/main.cc b/src/main.cc
index b4123b5..badf91b 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -61,7 +61,7 @@ main (int argc, char **argv)
 
   printf ("Opened font file %s: %d bytes long\n", argv[1], len);
 
-  const OpenTypeFontFile &ot = OpenTypeFontFile::get_for_data (font_data);
+  const OpenTypeFontFile &ot = Cast<OpenTypeFontFile> (font_data);
 
   switch (ot.get_tag ()) {
   case OpenTypeFontFile::TrueTypeTag:
@@ -99,7 +99,7 @@ main (int argc, char **argv)
       case GSUBGPOS::GPOSTag:
 	{
 
-	const GSUBGPOS &g = GSUBGPOS::get_for_data ((const char *) &ot + table.offset);
+	const GSUBGPOS &g = Cast<GSUBGPOS> (font_data + table.offset);
 
 	int num_scripts = g.get_script_count ();
 	printf ("    %d script(s) found in table\n", num_scripts);
@@ -162,7 +162,7 @@ main (int argc, char **argv)
       case GDEF::Tag:
 	{
 
-	const GDEF &gdef = GDEF::get_for_data ((const char *) &ot + table.offset);
+	const GDEF &gdef = Cast<GDEF> (font_data + table.offset);
 
 	printf ("    Has %sglyph classes\n",
 		  gdef.has_glyph_classes () ? "" : "no ");
commit f1aaa2a43654c28405ffd393de2cb127437c99a5
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 15:19:50 2010 -0400

    Add TODO

diff --git a/src/hb-ft.c b/src/hb-ft.c
index 79e1084..b5dd657 100644
--- a/src/hb-ft.c
+++ b/src/hb-ft.c
@@ -177,7 +177,6 @@ hb_ft_face_create (FT_Face           ft_face,
 {
   hb_face_t *face;
 
-  /* TODO: Handle NULL ft_face (in other places too) */
   if (ft_face->stream->read == NULL) {
     hb_blob_t *blob;
 
@@ -204,7 +203,6 @@ hb_ft_face_finalize (FT_Face ft_face)
 hb_face_t *
 hb_ft_face_create_cached (FT_Face ft_face)
 {
-  /* TODO: Not thread-safe */
   if (HB_UNLIKELY (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize))
   {
     if (ft_face->generic.finalizer)
diff --git a/src/hb-ft.h b/src/hb-ft.h
index 8930804..d7dc97e 100644
--- a/src/hb-ft.h
+++ b/src/hb-ft.h
@@ -43,6 +43,7 @@ hb_face_t *
 hb_ft_face_create (FT_Face           ft_face,
 		   hb_destroy_func_t destroy);
 
+/* Note: This function is not thread-safe */
 hb_face_t *
 hb_ft_face_create_cached (FT_Face ft_face);
 
diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index b6e282d..f45ba8f 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -84,7 +84,7 @@ typedef struct OffsetTable
   {
     Tag t;
     t.set (tag);
-    // TODO: bsearch (need to sort in sanitize)
+    /* TODO: bsearch (need to sort in sanitize) */
     unsigned int count = numTables;
     for (unsigned int i = 0; i < count; i++)
     {
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index d7354be..1a11cd1 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -366,6 +366,8 @@ struct Sanitizer
 
 template <typename Type, int Bytes> class BEInt;
 
+/* LONGTERMTODO: On machines allowing unaligned access, we can make the
+ * following tighter by using byteswap instructions on ints directly. */
 template <typename Type>
 class BEInt<Type, 2>
 {
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 2315df9..37d6782 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -87,7 +87,7 @@ struct RecordArrayOf : ArrayOf<Record<Type> > {
   {
     Tag t;
     t.set (tag);
-    // TODO: bsearch (need to sort in sanitize)
+    /* TODO: bsearch (need to sort in sanitize) */
     const Record<Type> *a = this->array();
     unsigned int count = this->len;
     for (unsigned int i = 0; i < count; i++)
@@ -235,8 +235,8 @@ struct Feature
     return SANITIZE_SELF () && SANITIZE (lookupIndex);
   }
 
-  /* TODO: implement get_feature_parameters() */
-  /* TODO: implement FeatureSize and other special features? */
+  /* LONGTERMTODO: implement get_feature_parameters() */
+  /* LONGTERMTODO: implement FeatureSize and other special features? */
   Offset	featureParams;	/* Offset to Feature Parameters table (if one
 				 * has been defined for the feature), relative
 				 * to the beginning of the Feature Table; = Null
@@ -321,7 +321,7 @@ struct CoverageFormat1
       return NOT_COVERED;
     GlyphID gid;
     gid.set (glyph_id);
-    // TODO: bsearch (need to sort in sanitize)
+    /* TODO: bsearch (need to sort in sanitize) */
     unsigned int num_glyphs = glyphArray.len;
     for (unsigned int i = 0; i < num_glyphs; i++)
       if (gid == glyphArray[i])
@@ -377,7 +377,7 @@ struct CoverageFormat2
   private:
   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
   {
-    // TODO: bsearch (need to sort in sanitize)
+    /* TODO: bsearch (need to sort in sanitize) */
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -497,7 +497,7 @@ struct ClassDefFormat2
   private:
   inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const
   {
-    // TODO: bsearch (need to sort in sanitize)
+    /* TODO: bsearch (need to sort in sanitize) */
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
     {
commit 33d4d4325e15e332105ea8f361bab79ee542f0f8
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 14:56:55 2010 -0400

    Zero glyph metrics before calling user callback

diff --git a/src/hb-font.cc b/src/hb-font.cc
index 9c33d97..5e4e02c 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -62,8 +62,8 @@ hb_font_get_glyph_metrics_nil (hb_font_t *font HB_GNUC_UNUSED,
 			       hb_face_t *face HB_GNUC_UNUSED,
 			       const void *user_data HB_GNUC_UNUSED,
 			       hb_codepoint_t glyph HB_GNUC_UNUSED,
-			       hb_glyph_metrics_t *metrics)
-{ memset (metrics, 0, sizeof (*metrics)); }
+			       hb_glyph_metrics_t *metrics HB_GNUC_UNUSED)
+{ }
 
 static hb_position_t
 hb_font_get_kerning_nil (hb_font_t *font HB_GNUC_UNUSED,
@@ -205,7 +205,7 @@ void
 hb_font_get_glyph_metrics (hb_font_t *font, hb_face_t *face,
 			   hb_codepoint_t glyph, hb_glyph_metrics_t *metrics)
 {
-  /* TODO Zero metrics here? */
+  memset (metrics, 0, sizeof (*metrics));
   return font->klass->get_glyph_metrics (font, face, font->user_data,
 					 glyph, metrics);
 }
commit 4206e9511a222c0c50cc9b4fe72ec421983bba2c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 14:44:55 2010 -0400

    More warning fixes

diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 22f31f4..96a0d9a 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -595,8 +595,8 @@ hb_ot_layout_position_lookup   (hb_font_t    *font,
 }
 
 void
-hb_ot_layout_position_finish (hb_font_t    *font,
-			      hb_face_t    *face,
+hb_ot_layout_position_finish (hb_font_t    *font HB_GNUC_UNUSED,
+			      hb_face_t    *face HB_GNUC_UNUSED,
 			      hb_buffer_t  *buffer)
 {
   unsigned int i, j;
diff --git a/src/hb-ot-shape.c b/src/hb-ot-shape.c
index f535183..54d2895 100644
--- a/src/hb-ot-shape.c
+++ b/src/hb-ot-shape.c
@@ -68,8 +68,7 @@ cmp_lookups (const void *p1, const void *p2)
 }
 
 static void
-setup_lookups (hb_font_t    *font,
-	       hb_face_t    *face,
+setup_lookups (hb_face_t    *face,
 	       hb_buffer_t  *buffer,
 	       hb_feature_t *features,
 	       unsigned int  num_features,
@@ -115,7 +114,7 @@ setup_lookups (hb_font_t    *font,
 
 
 hb_bool_t
-_hb_ot_substitute_complex (hb_font_t    *font,
+_hb_ot_substitute_complex (hb_font_t    *font HB_GNUC_UNUSED,
 			   hb_face_t    *face,
 			   hb_buffer_t  *buffer,
 			   hb_feature_t *features,
@@ -128,7 +127,7 @@ _hb_ot_substitute_complex (hb_font_t    *font,
   if (!hb_ot_layout_has_substitution (face))
     return FALSE;
 
-  setup_lookups (font, face, buffer, features, num_features,
+  setup_lookups (face, buffer, features, num_features,
 		 HB_OT_TAG_GSUB,
 		 lookups, &num_lookups);
 
@@ -152,7 +151,7 @@ _hb_ot_position_complex (hb_font_t    *font,
   if (!hb_ot_layout_has_positioning (face))
     return FALSE;
 
-  setup_lookups (font, face, buffer, features, num_features,
+  setup_lookups (face, buffer, features, num_features,
 		 HB_OT_TAG_GPOS,
 		 lookups, &num_lookups);
 
diff --git a/src/hb-shape.c b/src/hb-shape.c
index a3315bb..2754dac 100644
--- a/src/hb-shape.c
+++ b/src/hb-shape.c
@@ -113,8 +113,8 @@ static void
 hb_substitute_default (hb_font_t    *font,
 		       hb_face_t    *face,
 		       hb_buffer_t  *buffer,
-		       hb_feature_t *features,
-		       unsigned int  num_features)
+		       hb_feature_t *features HB_GNUC_UNUSED,
+		       unsigned int  num_features HB_GNUC_UNUSED)
 {
   hb_mirror_chars (buffer);
   hb_map_glyphs (font, face, buffer);
@@ -131,11 +131,11 @@ hb_substitute_complex (hb_font_t    *font,
 }
 
 static void
-hb_substitute_fallback (hb_font_t    *font,
-			hb_face_t    *face,
-			hb_buffer_t  *buffer,
-			hb_feature_t *features,
-			unsigned int  num_features)
+hb_substitute_fallback (hb_font_t    *font HB_GNUC_UNUSED,
+			hb_face_t    *face HB_GNUC_UNUSED,
+			hb_buffer_t  *buffer HB_GNUC_UNUSED,
+			hb_feature_t *features HB_GNUC_UNUSED,
+			unsigned int  num_features HB_GNUC_UNUSED)
 {
   /* TODO Arabic */
 }
@@ -147,8 +147,8 @@ static void
 hb_position_default (hb_font_t    *font,
 		     hb_face_t    *face,
 		     hb_buffer_t  *buffer,
-		     hb_feature_t *features,
-		     unsigned int  num_features)
+		     hb_feature_t *features HB_GNUC_UNUSED,
+		     unsigned int  num_features HB_GNUC_UNUSED)
 {
   unsigned int count;
 
@@ -174,11 +174,11 @@ hb_position_complex (hb_font_t    *font,
 }
 
 static void
-hb_position_fallback (hb_font_t    *font,
-		      hb_face_t    *face,
-		      hb_buffer_t  *buffer,
-		      hb_feature_t *features,
-		      unsigned int  num_features)
+hb_position_fallback (hb_font_t    *font HB_GNUC_UNUSED,
+		      hb_face_t    *face HB_GNUC_UNUSED,
+		      hb_buffer_t  *buffer HB_GNUC_UNUSED,
+		      hb_feature_t *features HB_GNUC_UNUSED,
+		      unsigned int  num_features HB_GNUC_UNUSED)
 {
   /* TODO Mark pos */
 }
@@ -187,8 +187,8 @@ static void
 hb_truetype_kern (hb_font_t    *font,
 		  hb_face_t    *face,
 		  hb_buffer_t  *buffer,
-		  hb_feature_t *features,
-		  unsigned int  num_features)
+		  hb_feature_t *features HB_GNUC_UNUSED,
+		  unsigned int  num_features HB_GNUC_UNUSED)
 {
   unsigned int count;
 
commit ef66ebeabc6c234004bd9e9bb67eb5c9711f4a1e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 14:40:36 2010 -0400

    Remove unused parameter

diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index 7b2481b..b6e282d 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -105,7 +105,7 @@ typedef struct OffsetTable
   }
 
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base) {
+  inline bool sanitize (SANITIZE_ARG_DEF) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF () && SANITIZE_ARRAY (tableDir, TableDirectory::get_size (), numTables);
   }
@@ -133,7 +133,7 @@ struct TTCHeaderVersion1
 
   inline bool sanitize (SANITIZE_ARG_DEF) {
     TRACE_SANITIZE ();
-    return HB_LIKELY (table.sanitize (SANITIZE_ARG, CharP(this), CharP(this)));
+    return SANITIZE_THIS (table);
   }
 
   private:
@@ -232,7 +232,7 @@ struct OpenTypeFontFile
     if (!SANITIZE (u.tag)) return false;
     switch (u.tag) {
     case CFFTag:	/* All the non-collection tags */
-    case TrueTypeTag:	return u.fontFace->sanitize (SANITIZE_ARG, CharP(this));
+    case TrueTypeTag:	return u.fontFace->sanitize (SANITIZE_ARG);
     case TTCTag:	return u.ttcHeader->sanitize (SANITIZE_ARG);
     default:		return true;
     }
commit 1d720192b193f48b44be0385eda3c2c5d5cd28ad
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 14:39:10 2010 -0400

    Fix compile warnings (HB_GNUC_UNUSED)

diff --git a/src/hb-buffer.c b/src/hb-buffer.c
index ac6b47d..777ee7f 100644
--- a/src/hb-buffer.c
+++ b/src/hb-buffer.c
@@ -594,7 +594,7 @@ hb_utf8_next (const uint8_t *text,
 void
 hb_buffer_add_utf8 (hb_buffer_t  *buffer,
 		    const char   *text,
-		    unsigned int  text_length,
+		    unsigned int  text_length HB_GNUC_UNUSED,
 		    unsigned int  item_offset,
 		    unsigned int  item_length)
 {
@@ -628,7 +628,7 @@ hb_utf16_next (const uint16_t *text,
 void
 hb_buffer_add_utf16 (hb_buffer_t    *buffer,
 		     const uint16_t *text,
-		     unsigned int    text_length,
+		     unsigned int    text_length HB_GNUC_UNUSED,
 		     unsigned int    item_offset,
 		     unsigned int    item_length)
 {
@@ -640,7 +640,7 @@ hb_buffer_add_utf16 (hb_buffer_t    *buffer,
 void
 hb_buffer_add_utf32 (hb_buffer_t    *buffer,
 		     const uint32_t *text,
-		     unsigned int    text_length,
+		     unsigned int    text_length HB_GNUC_UNUSED,
 		     unsigned int    item_offset,
 		     unsigned int    item_length)
 {
diff --git a/src/hb-font.cc b/src/hb-font.cc
index e1b0b87..9c33d97 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -40,24 +40,37 @@
  */
 
 static hb_codepoint_t
-hb_font_get_glyph_nil (hb_font_t *font, hb_face_t *face, const void *user_data,
-		       hb_codepoint_t unicode, hb_codepoint_t variation_selector)
+hb_font_get_glyph_nil (hb_font_t *font HB_GNUC_UNUSED,
+		       hb_face_t *face HB_GNUC_UNUSED,
+		       const void *user_data HB_GNUC_UNUSED,
+		       hb_codepoint_t unicode HB_GNUC_UNUSED,
+		       hb_codepoint_t variation_selector HB_GNUC_UNUSED)
 { return 0; }
 
 static hb_bool_t
-hb_font_get_contour_point_nil (hb_font_t *font, hb_face_t *face, const void *user_data,
-			       unsigned int point_index,
-			       hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y)
+hb_font_get_contour_point_nil (hb_font_t *font HB_GNUC_UNUSED,
+			       hb_face_t *face HB_GNUC_UNUSED,
+			       const void *user_data HB_GNUC_UNUSED,
+			       unsigned int point_index HB_GNUC_UNUSED,
+			       hb_codepoint_t glyph HB_GNUC_UNUSED,
+			       hb_position_t *x HB_GNUC_UNUSED,
+			       hb_position_t *y HB_GNUC_UNUSED)
 { return false; }
 
 static void
-hb_font_get_glyph_metrics_nil (hb_font_t *font, hb_face_t *face, const void *user_data,
-			       hb_codepoint_t glyph, hb_glyph_metrics_t *metrics)
+hb_font_get_glyph_metrics_nil (hb_font_t *font HB_GNUC_UNUSED,
+			       hb_face_t *face HB_GNUC_UNUSED,
+			       const void *user_data HB_GNUC_UNUSED,
+			       hb_codepoint_t glyph HB_GNUC_UNUSED,
+			       hb_glyph_metrics_t *metrics)
 { memset (metrics, 0, sizeof (*metrics)); }
 
 static hb_position_t
-hb_font_get_kerning_nil (hb_font_t *font, hb_face_t *face, const void *user_data,
-			 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph)
+hb_font_get_kerning_nil (hb_font_t *font HB_GNUC_UNUSED,
+			 hb_face_t *face HB_GNUC_UNUSED,
+			 const void *user_data HB_GNUC_UNUSED,
+			 hb_codepoint_t first_glyph HB_GNUC_UNUSED,
+			 hb_codepoint_t second_glyph HB_GNUC_UNUSED)
 { return 0; }
 
 hb_font_funcs_t _hb_font_funcs_nil = {
diff --git a/src/hb-ft.c b/src/hb-ft.c
index 18b6e0b..79e1084 100644
--- a/src/hb-ft.c
+++ b/src/hb-ft.c
@@ -34,8 +34,11 @@
 #include FT_TRUETYPE_TABLES_H
 
 static hb_codepoint_t
-hb_ft_get_glyph (hb_font_t *font, hb_face_t *face, const void *user_data,
-		 hb_codepoint_t unicode, hb_codepoint_t variation_selector)
+hb_ft_get_glyph (hb_font_t *font HB_GNUC_UNUSED,
+		 hb_face_t *face HB_GNUC_UNUSED,
+		 const void *user_data,
+		 hb_codepoint_t unicode,
+		 hb_codepoint_t variation_selector)
 {
   FT_Face ft_face = (FT_Face) user_data;
 
@@ -51,9 +54,13 @@ hb_ft_get_glyph (hb_font_t *font, hb_face_t *face, const void *user_data,
 }
 
 static hb_bool_t
-hb_ft_get_contour_point (hb_font_t *font, hb_face_t *face, const void *user_data,
+hb_ft_get_contour_point (hb_font_t *font HB_GNUC_UNUSED,
+			 hb_face_t *face HB_GNUC_UNUSED,
+			 const void *user_data,
 			 unsigned int point_index,
-			 hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y)
+			 hb_codepoint_t glyph,
+			 hb_position_t *x,
+			 hb_position_t *y)
 {
   FT_Face ft_face = (FT_Face) user_data;
   int load_flags = FT_LOAD_DEFAULT;
@@ -76,8 +83,11 @@ hb_ft_get_contour_point (hb_font_t *font, hb_face_t *face, const void *user_data
 }
 
 static void
-hb_ft_get_glyph_metrics (hb_font_t *font, hb_face_t *face, const void *user_data,
-			 hb_codepoint_t glyph, hb_glyph_metrics_t *metrics)
+hb_ft_get_glyph_metrics (hb_font_t *font HB_GNUC_UNUSED,
+			 hb_face_t *face HB_GNUC_UNUSED,
+			 const void *user_data,
+			 hb_codepoint_t glyph,
+			 hb_glyph_metrics_t *metrics)
 {
   FT_Face ft_face = (FT_Face) user_data;
   int load_flags = FT_LOAD_DEFAULT;
@@ -100,8 +110,11 @@ hb_ft_get_glyph_metrics (hb_font_t *font, hb_face_t *face, const void *user_data
 }
 
 static hb_position_t
-hb_ft_get_kerning (hb_font_t *font, hb_face_t *face, const void *user_data,
-		   hb_codepoint_t first_glyph, hb_codepoint_t second_glyph)
+hb_ft_get_kerning (hb_font_t *font HB_GNUC_UNUSED,
+		   hb_face_t *face HB_GNUC_UNUSED,
+		   const void *user_data,
+		   hb_codepoint_t first_glyph,
+		   hb_codepoint_t second_glyph)
 {
   FT_Face ft_face = (FT_Face) user_data;
   FT_Vector kerning;
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 6ec22f5..d7354be 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -186,7 +186,7 @@ _hb_sanitize_init (hb_sanitize_context_t *context,
 }
 
 static HB_GNUC_UNUSED void
-_hb_sanitize_fini (hb_sanitize_context_t *context,
+_hb_sanitize_fini (hb_sanitize_context_t *context HB_GNUC_UNUSED,
 		   hb_blob_t *blob)
 {
 #if HB_DEBUG_SANITIZE
diff --git a/src/hb-unicode.c b/src/hb-unicode.c
index e155d6d..b6bd4ba 100644
--- a/src/hb-unicode.c
+++ b/src/hb-unicode.c
@@ -33,10 +33,10 @@
  */
 
 static hb_codepoint_t hb_unicode_get_mirroring_nil (hb_codepoint_t unicode) { return unicode; }
-static hb_category_t hb_unicode_get_general_category_nil (hb_codepoint_t unicode) { return HB_CATEGORY_OTHER_LETTER; }
-static hb_script_t hb_unicode_get_script_nil (hb_codepoint_t unicode) { return HB_SCRIPT_UNKNOWN; }
-static unsigned int hb_unicode_get_combining_class_nil (hb_codepoint_t unicode) { return 0; }
-static unsigned int hb_unicode_get_eastasian_width_nil (hb_codepoint_t unicode) { return 1; }
+static hb_category_t hb_unicode_get_general_category_nil (hb_codepoint_t unicode HB_GNUC_UNUSED) { return HB_CATEGORY_OTHER_LETTER; }
+static hb_script_t hb_unicode_get_script_nil (hb_codepoint_t unicode HB_GNUC_UNUSED) { return HB_SCRIPT_UNKNOWN; }
+static unsigned int hb_unicode_get_combining_class_nil (hb_codepoint_t unicode HB_GNUC_UNUSED) { return 0; }
+static unsigned int hb_unicode_get_eastasian_width_nil (hb_codepoint_t unicode HB_GNUC_UNUSED) { return 1; }
 
 hb_unicode_funcs_t _hb_unicode_funcs_nil = {
   HB_REFERENCE_COUNT_INVALID, /* ref_count */
commit 8dfdca599c0a3ba5255131002910bca3b381acac
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 14:07:34 2010 -0400

    No need to keep blob in sanitize context

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index a4b76c5..6ec22f5 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -168,14 +168,12 @@ struct _hb_sanitize_context_t
   const char *start, *end;
   hb_bool_t writable;
   unsigned int edit_count;
-  hb_blob_t *blob;
 };
 
 static HB_GNUC_UNUSED void
 _hb_sanitize_init (hb_sanitize_context_t *context,
 		   hb_blob_t *blob)
 {
-  context->blob = blob;
   context->start = hb_blob_lock (blob);
   context->end = context->start + hb_blob_get_length (blob);
   context->writable = hb_blob_is_writable (blob);
@@ -189,15 +187,14 @@ _hb_sanitize_init (hb_sanitize_context_t *context,
 
 static HB_GNUC_UNUSED void
 _hb_sanitize_fini (hb_sanitize_context_t *context,
-		   bool unlock)
+		   hb_blob_t *blob)
 {
 #if HB_DEBUG_SANITIZE
   fprintf (stderr, "sanitize %p fini [%p..%p] %u edit requests\n",
-	   context->blob, context->start, context->end, context->edit_count);
+	   blob, context->start, context->end, context->edit_count);
 #endif
 
-  if (unlock)
-    hb_blob_unlock (context->blob);
+  hb_blob_unlock (blob);
 }
 
 static HB_GNUC_UNUSED inline bool
@@ -323,10 +320,10 @@ struct Sanitizer
 	  sane = false;
 	}
       }
-      _hb_sanitize_fini (&context, true);
+      _hb_sanitize_fini (&context, blob);
     } else {
       unsigned int edit_count = context.edit_count;
-      _hb_sanitize_fini (&context, true);
+      _hb_sanitize_fini (&context, blob);
       if (edit_count && !hb_blob_is_writable (blob) && hb_blob_try_writable (blob)) {
         /* ok, we made it writable by relocating.  try again */
 #if HB_DEBUG_SANITIZE
commit 254933c397f1ce9796f59689a25f9fc2e58df4ea
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 13:57:10 2010 -0400

    When sanitizing, delay making writable
    
    Before, as soon as we needed to make an edit, we tried to make the blob
    writable inplace.  That grows code unnecessarily though.  We can simply
    fail, make writable, then start again.  That's indeed what the fallback
    was doing anyway.

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 3a89425..a4b76c5 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -166,7 +166,8 @@ typedef struct _hb_sanitize_context_t hb_sanitize_context_t;
 struct _hb_sanitize_context_t
 {
   const char *start, *end;
-  int edit_count;
+  hb_bool_t writable;
+  unsigned int edit_count;
   hb_blob_t *blob;
 };
 
@@ -177,6 +178,7 @@ _hb_sanitize_init (hb_sanitize_context_t *context,
   context->blob = blob;
   context->start = hb_blob_lock (blob);
   context->end = context->start + hb_blob_get_length (blob);
+  context->writable = hb_blob_is_writable (blob);
   context->edit_count = 0;
 
 #if HB_DEBUG_SANITIZE
@@ -236,6 +238,7 @@ _hb_sanitize_array (SANITIZE_ARG_DEF,
 	     context->start, context->end,
 	     !overflows ? "does not overflow" : "OVERFLOWS FAIL");
 #endif
+
   return HB_LIKELY (!overflows) && _hb_sanitize_check (SANITIZE_ARG, base, record_size * len);
 }
 
@@ -244,7 +247,6 @@ _hb_sanitize_edit (SANITIZE_ARG_DEF,
 		   const char *base HB_GNUC_UNUSED,
 		   unsigned int len HB_GNUC_UNUSED)
 {
-  bool perm = hb_blob_try_writable_inplace (context->blob);
   context->edit_count++;
 
 #if HB_DEBUG_SANITIZE
@@ -254,9 +256,10 @@ _hb_sanitize_edit (SANITIZE_ARG_DEF,
 	   context->edit_count,
 	   base, base+len, len,
 	   context->start, context->end,
-	   perm ? "granted" : "REJECTED");
+	   context->writable ? "granted" : "REJECTED");
 #endif
-  return perm;
+
+  return context->writable;
 }
 
 #define SANITIZE(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG))
commit 71e735e915c85536ee4d3035576f7426e8cd19dd
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 13:48:06 2010 -0400

    [blob] Fallback to copying if mprotect() fails

diff --git a/src/hb-blob.c b/src/hb-blob.c
index c5f8726..8276d78 100644
--- a/src/hb-blob.c
+++ b/src/hb-blob.c
@@ -348,6 +348,9 @@ hb_blob_try_writable (hb_blob_t *blob)
 
   hb_mutex_lock (blob->lock);
 
+  if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE)
+    _try_writable_inplace_locked (blob);
+
   if (blob->mode == HB_MEMORY_MODE_READONLY)
   {
     char *new_data;
@@ -373,8 +376,6 @@ hb_blob_try_writable (hb_blob_t *blob)
       blob->user_data = new_data;
     }
   }
-  else if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE)
-    _try_writable_inplace_locked (blob);
 
 done:
   mode = blob->mode;
commit 1aa4666b914da7747fc58a8f6f2d913c94e3b8da
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 13:32:03 2010 -0400

    Cleanup OpenTypeFontFile

diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index c7ddff9..7b2481b 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -104,8 +104,6 @@ typedef struct OffsetTable
     return get_table (table_index);
   }
 
-  inline unsigned int get_face_count (void) const { return 1; }
-
   public:
   inline bool sanitize (SANITIZE_ARG_DEF, void *base) {
     TRACE_SANITIZE ();
@@ -167,7 +165,7 @@ struct TTCHeader
     switch (u.header.version) {
     case 2: /* version 2 is compatible with version 1 */
     case 1: return u.version1->get_face (i);
-    default: return Null(OpenTypeFontFace);
+    default:return Null(OpenTypeFontFace);
     }
   }
 
@@ -199,43 +197,53 @@ struct TTCHeader
 
 struct OpenTypeFontFile
 {
-  static const hb_tag_t TrueTypeTag	= HB_TAG ( 0 , 1 , 0 , 0 );
   static const hb_tag_t CFFTag		= HB_TAG ('O','T','T','O');
+  static const hb_tag_t TrueTypeTag	= HB_TAG ( 0 , 1 , 0 , 0 );
   static const hb_tag_t TTCTag		= HB_TAG ('t','t','c','f');
 
   STATIC_DEFINE_GET_FOR_DATA (OpenTypeFontFile);
 
+  inline hb_tag_t get_tag (void) const { return u.tag; }
+
   inline unsigned int get_face_count (void) const
   {
-    switch (tag) {
-    case TrueTypeTag: case CFFTag: return Cast<OpenTypeFontFace> (*this).get_face_count ();
-    case TTCTag: return Cast<TTCHeader> (*this).get_face_count ();
-    default: return 0;
+    switch (u.tag) {
+    case CFFTag:	/* All the non-collection tags */
+    case TrueTypeTag:	return 1;
+    case TTCTag:	return u.ttcHeader->get_face_count ();
+    default:		return 0;
     }
   }
   inline const OpenTypeFontFace& get_face (unsigned int i) const
   {
-    switch (tag) {
+    switch (u.tag) {
     /* Note: for non-collection SFNT data we ignore index.  This is because
      * Apple dfont container is a container of SFNT's.  So each SFNT is a
      * non-TTC, but the index is more than zero. */
-    case TrueTypeTag: case CFFTag: return Cast<OpenTypeFontFace> (*this);
-    case TTCTag: return Cast<TTCHeader> (*this).get_face (i);
-    default: return Null(OpenTypeFontFace);
+    case CFFTag:	/* All the non-collection tags */
+    case TrueTypeTag:	return u.fontFace[0];
+    case TTCTag:	return u.ttcHeader->get_face (i);
+    default:		return Null(OpenTypeFontFace);
     }
   }
 
   inline bool sanitize (SANITIZE_ARG_DEF) {
     TRACE_SANITIZE ();
-    if (!SANITIZE_SELF ()) return false;
-    switch (tag) {
-    default: return true;
-    case TrueTypeTag: case CFFTag: return SANITIZE_THIS (Cast<OpenTypeFontFace> (*this));
-    case TTCTag: return SANITIZE (Cast<TTCHeader> (*this));
+    if (!SANITIZE (u.tag)) return false;
+    switch (u.tag) {
+    case CFFTag:	/* All the non-collection tags */
+    case TrueTypeTag:	return u.fontFace->sanitize (SANITIZE_ARG, CharP(this));
+    case TTCTag:	return u.ttcHeader->sanitize (SANITIZE_ARG);
+    default:		return true;
     }
   }
 
-  Tag		tag;		/* 4-byte identifier. */
+  private:
+  union {
+  Tag			tag;		/* 4-byte identifier. */
+  OpenTypeFontFace	fontFace[VAR];
+  TTCHeader		ttcHeader[VAR];
+  } u;
 };
 ASSERT_SIZE (OpenTypeFontFile, 4);
 
diff --git a/src/main.cc b/src/main.cc
index b2aee2b..b4123b5 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -63,7 +63,7 @@ main (int argc, char **argv)
 
   const OpenTypeFontFile &ot = OpenTypeFontFile::get_for_data (font_data);
 
-  switch (ot.tag) {
+  switch (ot.get_tag ()) {
   case OpenTypeFontFile::TrueTypeTag:
     printf ("OpenType font with TrueType outlines\n");
     break;
commit ae4190cafe927649f8ff8be6a0082478d1298fda
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 23 12:33:02 2010 -0400

    Properly define separate structs for TTCHeader and TTCHeaderVersion1

diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index 2e70b96..c7ddff9 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -65,7 +65,6 @@ ASSERT_SIZE (TableDirectory, 16);
 typedef struct OffsetTable
 {
   friend struct OpenTypeFontFile;
-  friend struct TTCHeader;
 
   STATIC_DEFINE_GET_FOR_DATA (OffsetTable);
 
@@ -127,31 +126,71 @@ ASSERT_SIZE_VAR (OffsetTable, 12, TableDirectory);
  * TrueType Collections
  */
 
-struct TTCHeader
+struct TTCHeaderVersion1
 {
-  friend struct OpenTypeFontFile;
-
-  STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (TTCHeader, 1, 2);
+  friend struct TTCHeader;
 
   inline unsigned int get_face_count (void) const { return table.len; }
   inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
 
   inline bool sanitize (SANITIZE_ARG_DEF) {
     TRACE_SANITIZE ();
-    if (!SANITIZE (version)) return false;
-    if (HB_UNLIKELY (version.major < 1 || version.major > 2)) return false;
     return HB_LIKELY (table.sanitize (SANITIZE_ARG, CharP(this), CharP(this)));
   }
 
   private:
   Tag		ttcTag;		/* TrueType Collection ID string: 'ttcf' */
-  FixedVersion	version;	/* Version of the TTC Header (1.0 or 2.0),
-				 * 0x00010000 or 0x00020000 */
+  FixedVersion	version;	/* Version of the TTC Header (1.0),
+				 * 0x00010000 */
   LongOffsetLongArrayOf<OffsetTable>
 		table;		/* Array of offsets to the OffsetTable for each font
 				 * from the beginning of the file */
 };
-ASSERT_SIZE (TTCHeader, 12);
+ASSERT_SIZE (TTCHeaderVersion1, 12);
+
+struct TTCHeader
+{
+  friend struct OpenTypeFontFile;
+
+  private:
+
+  inline unsigned int get_face_count (void) const
+  {
+    switch (u.header.version) {
+    case 2: /* version 2 is compatible with version 1 */
+    case 1: return u.version1->get_face_count ();
+    default:return 0;
+    }
+  }
+  inline const OpenTypeFontFace& get_face (unsigned int i) const
+  {
+    switch (u.header.version) {
+    case 2: /* version 2 is compatible with version 1 */
+    case 1: return u.version1->get_face (i);
+    default: return Null(OpenTypeFontFace);
+    }
+  }
+
+  inline bool sanitize (SANITIZE_ARG_DEF) {
+    TRACE_SANITIZE ();
+    if (!SANITIZE (u.header.version)) return false;
+    switch (u.header.version) {
+    case 2: /* version 2 is compatible with version 1 */
+    case 1: return u.version1->sanitize (SANITIZE_ARG);
+    default:return true;
+    }
+  }
+
+  private:
+  union {
+  struct {
+  Tag		ttcTag;		/* TrueType Collection ID string: 'ttcf' */
+  FixedVersion	version;	/* Version of the TTC Header (1.0 or 2.0),
+				 * 0x00010000 or 0x00020000 */
+  }			header;
+  TTCHeaderVersion1	version1[VAR];
+  } u;
+};
 
 
 /*
@@ -169,20 +208,20 @@ struct OpenTypeFontFile
   inline unsigned int get_face_count (void) const
   {
     switch (tag) {
+    case TrueTypeTag: case CFFTag: return Cast<OpenTypeFontFace> (*this).get_face_count ();
+    case TTCTag: return Cast<TTCHeader> (*this).get_face_count ();
     default: return 0;
-    case TrueTypeTag: case CFFTag: return OffsetTable::get_for_data (CharP(this)).get_face_count ();
-    case TTCTag: return TTCHeader::get_for_data (CharP(this)).get_face_count ();
     }
   }
   inline const OpenTypeFontFace& get_face (unsigned int i) const
   {
     switch (tag) {
-    default: return Null(OpenTypeFontFace);
     /* Note: for non-collection SFNT data we ignore index.  This is because
      * Apple dfont container is a container of SFNT's.  So each SFNT is a
      * non-TTC, but the index is more than zero. */
-    case TrueTypeTag: case CFFTag: return OffsetTable::get_for_data (CharP(this));
-    case TTCTag: return TTCHeader::get_for_data (CharP(this)).get_face (i);
+    case TrueTypeTag: case CFFTag: return Cast<OpenTypeFontFace> (*this);
+    case TTCTag: return Cast<TTCHeader> (*this).get_face (i);
+    default: return Null(OpenTypeFontFace);
     }
   }
 
@@ -191,7 +230,7 @@ struct OpenTypeFontFile
     if (!SANITIZE_SELF ()) return false;
     switch (tag) {
     default: return true;
-    case TrueTypeTag: case CFFTag: return SANITIZE_THIS (Cast<OffsetTable> (*this));
+    case TrueTypeTag: case CFFTag: return SANITIZE_THIS (Cast<OpenTypeFontFace> (*this));
     case TTCTag: return SANITIZE (Cast<TTCHeader> (*this));
     }
   }



More information about the HarfBuzz mailing list