* include/freetype/ftconfig.h: changed FT_LOCAL xxxx to FT_LOCAL( xxxx )
        everywhere in the source. Sames goes for FT_LOCAL_DEF xxxx translated
        into FT_LOCAL_DEF( xxxxx )
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index c4e8d98..967c93c 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -179,7 +179,7 @@
   }
 
 
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   SFNT_Init_Face( FT_Stream      stream,
                   TT_Face        face,
                   FT_Int         face_index,
@@ -242,7 +242,7 @@
                       != SFNT_Err_Ok )
 
 
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   SFNT_Load_Face( FT_Stream      stream,
                   TT_Face        face,
                   FT_Int         face_index,
@@ -592,7 +592,7 @@
 #undef LOAD_
 
 
-  FT_LOCAL_DEF void
+  FT_LOCAL_DEF( void )
   SFNT_Done_Face( TT_Face  face )
   {
     FT_Memory        memory = face->root.memory;
diff --git a/src/sfnt/sfobjs.h b/src/sfnt/sfobjs.h
index 463f0b6..a935956 100644
--- a/src/sfnt/sfobjs.h
+++ b/src/sfnt/sfobjs.h
@@ -28,21 +28,21 @@
 FT_BEGIN_HEADER
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   SFNT_Init_Face( FT_Stream      stream,
                   TT_Face        face,
                   FT_Int         face_index,
                   FT_Int         num_params,
                   FT_Parameter*  params );
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   SFNT_Load_Face( FT_Stream      stream,
                   TT_Face        face,
                   FT_Int         face_index,
                   FT_Int         num_params,
                   FT_Parameter*  params );
 
-  FT_LOCAL void
+  FT_LOCAL( void )
   SFNT_Done_Face( TT_Face  face );
 
 
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index 2fd58cf..8bb3aea 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -106,7 +106,7 @@
   /*    opened).  In case of error, all partially allocated tables are     */
   /*    released.                                                          */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_CharMap_Load( TT_Face        face,
                    TT_CMapTable*  cmap,
                    FT_Stream      stream )
@@ -414,7 +414,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_CharMap_Free( TT_Face        face,
                    TT_CMapTable*  cmap )
   {
diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h
index 2dea02e..13861a8 100644
--- a/src/sfnt/ttcmap.h
+++ b/src/sfnt/ttcmap.h
@@ -27,12 +27,12 @@
 FT_BEGIN_HEADER
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_CharMap_Load( TT_Face        face,
                    TT_CMapTable*  cmap,
                    FT_Stream      input );
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_CharMap_Free( TT_Face        face,
                    TT_CMapTable*  cmap );
 
diff --git a/src/sfnt/ttcmap0.c b/src/sfnt/ttcmap0.c
index 2ac62c4..52fbb93 100644
--- a/src/sfnt/ttcmap0.c
+++ b/src/sfnt/ttcmap0.c
@@ -45,32 +45,13 @@
 #define  TT_NEXT_ULong   FT_NEXT_ULONG_BE
 
 
-  typedef struct TT_CMap_InfoRec_
-  {
-    FT_ByteP            base;
-    FT_ByteP            limit;
-    FT_ValidationLevel  level;
-
-  } TT_CMap_InfoRec, *TT_CMap_Info;
-
-
   FT_CALLBACK_DEF  FT_Error
-  tt_cmap_init( FT_CMap       cmap,
-                TT_CMap_Info  info )
+  tt_cmap_init( TT_CMap   cmap,
+                FT_Byte*  data )
   {
-    FT_Error         error;
-    TT_CMap_Class    clazz = (TT_CMap_Class) FT_CMAP_CLASS(cmap);
-    FT_ValidatorRec  valid;
-    
-    cmap->data = info->base;
-    
-    ft_validator_init( &valid, info->base, info->limit, info->level );
-    
-    if ( setjmp( valid->jump_buffer, 0 ) == 0 )
-      clazz->validate( info->base, &valid );
-      
-    return valid.error;
-  }                
+    cmap->data = data;
+    return 0;
+  }
 
 
  /************************************************************************/
@@ -124,19 +105,22 @@
 
 
   FT_CALLBACK_DEF FT_UInt
-  tt_cmap0_char_index( FT_Byte*   table,
-                       FT_ULong   char_code )
+  tt_cmap0_char_index( TT_CMap    cmap,
+                       FT_UInt32  char_code )
   {
+    FT_Byte*  table = cmap->data;
+
     return  ( char_code < 256 ? table[6+char_code] : 0 );
   }
 
 
-  FT_CALLBACK_DEF FT_ULong
-  tt_cmap0_char_next( FT_Byte*  table,
-                      FT_ULong  char_code,
+  FT_CALLBACK_DEF FT_UInt32
+  tt_cmap0_char_next( TT_CMap    cmap,
+                      FT_UInt32  char_code,
                       FT_UInt   *agindex )
   {
-    FT_ULong  result = 0;
+    FT_Byte*  table  = cmap->data;
+    FT_UInt32 result = 0;
     FT_UInt   gindex = 0;
 
     table += 6;  /* go to glyph ids */
@@ -157,20 +141,21 @@
   }
 
 
-  FT_CALLBACK_TABLE const TT_Cmap_ClassRec  tt_cmap0_class_rec =
+  FT_CALLBACK_TABLE const TT_CMap_ClassRec  tt_cmap0_class_rec =
   {
     {
       sizeof( FT_CMapRec ),
-      
+
       (FT_CMap_InitFunc)      tt_cmap_init,
       (FT_CMap_DoneFunc)      NULL,
       (FT_CMap_CharIndexFunc) tt_cmap0_char_index,
       (FT_CMap_CharNextFunc)  tt_cmap0_char_next
     },
+    0,
     (TT_CMap_ValidateFunc)    tt_cmap0_validate
   };
 
-  FT_LOCAL_DEF  TT_CMap_Class tt_cmap0_class = &tt_cmap0_class_rec;
+  FT_LOCAL_DEF( TT_CMap_Class ) tt_cmap0_class = &tt_cmap0_class_rec;
 
 #endif /* TT_CONFIG_CMAP_FORMAT_0 */
 
@@ -354,8 +339,8 @@
   /* return sub header corresponding to a given character code */
   /* NULL on invalid charcode..                                */
   static FT_Byte*
-  tt_cmap2_get_subheader( FT_Byte*  table,
-                          FT_ULong  char_code )
+  tt_cmap2_get_subheader( FT_Byte*   table,
+                          FT_UInt32  char_code )
   {
     FT_Byte*  result = NULL;
 
@@ -401,9 +386,10 @@
 
 
   FT_CALLBACK_DEF FT_UInt
-  tt_cmap2_char_index( FT_Byte*   table,
-                       FT_ULong   char_code )
+  tt_cmap2_char_index( TT_CMap    cmap,
+                       FT_UInt32  char_code )
   {
+    FT_Byte*  table   = cmap->data;
     FT_UInt   result  = 0;
     FT_Byte*  subheader;
 
@@ -437,10 +423,11 @@
 
 
   FT_CALLBACK_DEF FT_UInt
-  tt_cmap2_char_next( FT_Byte*  table,
-                      FT_ULong  char_code,
+  tt_cmap2_char_next( TT_CMap    cmap,
+                      FT_UInt32  char_code,
                       FT_UInt   *agindex )
   {
+    FT_Byte*  table     = cmap->data;
     FT_UInt   result    = 0;
     FT_UInt   n, gindex = 0;
     FT_Byte*  subheader;
@@ -502,20 +489,21 @@
     return result;
   }
 
-  FT_CALLBACK_TABLE const TT_Cmap_ClassRec  tt_cmap2_class_rec =
+  FT_CALLBACK_TABLE const TT_CMap_ClassRec  tt_cmap2_class_rec =
   {
     {
       sizeof( FT_CMapRec ),
-      
+
       (FT_CMap_InitFunc)      tt_cmap_init,
       (FT_CMap_DoneFunc)      NULL,
       (FT_CMap_CharIndexFunc) tt_cmap2_char_index,
       (FT_CMap_CharNextFunc)  tt_cmap2_char_next
     },
+    2,
     (TT_CMap_ValidateFunc)    tt_cmap2_validate
   };
 
-  FT_LOCAL_DEF  TT_CMap_Class tt_cmap2_class = &tt_cmap2_class_rec;
+  FT_LOCAL_DEF( TT_CMap_Class )  tt_cmap2_class = &tt_cmap2_class_rec;
 
 #endif /* TT_CONFIG_CMAP_FORMAT_2 */
 
@@ -700,9 +688,10 @@
 
 
   FT_CALLBACK_DEF FT_UInt
-  tt_cmap4_char_index( FT_Byte*  table,
-                       FT_ULong  char_code )
+  tt_cmap4_char_index( TT_CMap    cmap,
+                       FT_UInt32  char_code )
   {
+    FT_Byte*  table  = cmap->data;
     FT_UInt   result = 0;
 
     if ( char_code < 0x10000U )
@@ -749,12 +738,13 @@
 
 
 
-  FT_CALLBACK_DEF FT_ULong
-  tt_cmap4_char_next( FT_Byte*  table,
-                      FT_ULong  char_code,
-                      FT_UInt  *agindex )
+  FT_CALLBACK_DEF FT_UInt32
+  tt_cmap4_char_next( TT_CMap    cmap,
+                      FT_UInt32  char_code,
+                      FT_UInt   *agindex )
   {
-    FT_ULong  result = 0;
+    FT_Byte*  table  = cmap->data;
+    FT_UInt32 result = 0;
     FT_UInt   gindex = 0;
     FT_Byte*  p;
     FT_UInt   code, num_segs2;
@@ -830,20 +820,21 @@
     return result;
   }
 
-  FT_CALLBACK_TABLE const TT_Cmap_ClassRec  tt_cmap4_class_rec =
+  FT_CALLBACK_TABLE const TT_CMap_ClassRec  tt_cmap4_class_rec =
   {
     {
       sizeof( FT_CMapRec ),
-      
+
       (FT_CMap_InitFunc)      tt_cmap_init,
       (FT_CMap_DoneFunc)      NULL,
       (FT_CMap_CharIndexFunc) tt_cmap4_char_index,
       (FT_CMap_CharNextFunc)  tt_cmap4_char_next
     },
+    4,
     (TT_CMap_ValidateFunc)    tt_cmap4_validate
   };
 
-  FT_LOCAL_DEF  TT_CMap_Class tt_cmap4_class = &tt_cmap4_class_rec;
+  static TT_CMap_Class tt_cmap4_class = &tt_cmap4_class_rec;
 
 #endif /* TT_CONFIG_CMAP_FORMAT_4 */
 
@@ -912,9 +903,10 @@
 
 
   FT_CALLBACK_DEF FT_UInt
-  tt_cmap6_char_index( FT_Byte*   table,
-                       FT_ULong   char_code )
+  tt_cmap6_char_index( TT_CMap    cmap,
+                       FT_UInt32  char_code )
   {
+    FT_Byte*  table  = cmap->data;
     FT_UInt   result = 0;
     FT_Byte*  p      = table + 6;
     FT_UInt   start  = TT_NEXT_USHORT(p);
@@ -930,12 +922,13 @@
   }
 
 
-  FT_CALLBACK_DEF FT_ULong
-  tt_cmap6_char_next( FT_Byte*    table,
-                      FT_ULong    char_code,
+  FT_CALLBACK_DEF FT_UInt32
+  tt_cmap6_char_next( TT_CMap     cmap,
+                      FT_UInt32   char_code,
                       FT_UInt    *agindex )
   {
-    FT_ULong  result = 0;
+    FT_Byte*  table  = cmap->data;
+    FT_UInt32 result = 0;
     FT_UInt   gindex = 0;
     FT_Byte*  p      = table + 6;
     FT_UInt   start  = TT_NEXT_USHORT(p);
@@ -971,20 +964,21 @@
   }
 
 
-  FT_CALLBACK_TABLE const TT_Cmap_ClassRec  tt_cmap6_class_rec =
+  FT_CALLBACK_TABLE const TT_CMap_ClassRec  tt_cmap6_class_rec =
   {
     {
       sizeof( FT_CMapRec ),
-      
+
       (FT_CMap_InitFunc)      tt_cmap_init,
       (FT_CMap_DoneFunc)      NULL,
       (FT_CMap_CharIndexFunc) tt_cmap6_char_index,
       (FT_CMap_CharNextFunc)  tt_cmap6_char_next
     },
+    6,
     (TT_CMap_ValidateFunc)    tt_cmap6_validate
   };
 
-  FT_LOCAL_DEF  TT_CMap_Class tt_cmap6_class = &tt_cmap6_class_rec;
+  FT_LOCAL_DEF( TT_CMap_Class )  tt_cmap6_class = &tt_cmap6_class_rec;
 
 #endif /* TT_CONFIG_CMAP_FORMAT_6 */
 
@@ -1054,8 +1048,8 @@
   {
     FT_Byte*   p = table + 4;
     FT_Byte*   is32;
-    FT_ULong   length;
-    FT_ULong   num_groups;
+    FT_UInt32  length;
+    FT_UInt32  num_groups;
 
     if ( table + 16 + 8192 > valid->limit )
       INVALID_TOO_SHORT;
@@ -1073,7 +1067,7 @@
 
     /* check groups, they must be in increasing order */
     {
-      FT_ULong  n, start, end, start_id, count, last = 0;
+      FT_UInt32  n, start, end, start_id, count, last = 0;
 
       for ( n = 0; n < num_groups; n++ )
       {
@@ -1095,7 +1089,7 @@
           if ( start_id + end - start >= valid->num_glyphs )
             INVALID_GLYPH_ID;
 
-          count = (FT_ULong)(end - start + 1);
+          count = (FT_UInt32)(end - start + 1);
 
           if ( start & ~0xFFFFU )
           {
@@ -1139,13 +1133,14 @@
 
 
   FT_CALLBACK_DEF FT_UInt
-  tt_cmap8_char_index( FT_Byte*   table,
-                       FT_ULong   char_code )
+  tt_cmap8_char_index( TT_CMap     cmap,
+                       FT_UInt32   char_code )
   {
-    FT_UInt   result     = 0;
-    FT_Byte*  p          = table + 8204;
-    FT_ULong  num_groups = TT_NEXT_ULONG(p);
-    FT_ULong  n, start, end, start_id;
+    FT_Byte*   table      = cmap->data;
+    FT_UInt    result     = 0;
+    FT_Byte*   p          = table + 8204;
+    FT_UInt32  num_groups = TT_NEXT_ULONG(p);
+    FT_UInt32  n, start, end, start_id;
 
     for ( ; num_groups > 0; num_groups-- )
     {
@@ -1166,16 +1161,16 @@
   }
 
 
-  FT_CALLBACK_DEF FT_ULong
-  tt_cmap8_char_next( FT_Byte*   table,
-                      FT_ULong   char_code,
+  FT_CALLBACK_DEF FT_UInt32
+  tt_cmap8_char_next( TT_CMap    cmap,
+                      FT_UInt32  char_code,
                       FT_UInt   *agindex )
   {
-    FT_ULong   result     = 0;
+    FT_UInt32  result     = 0;
     FT_UInt    gindex     = 0;
     FT_Byte*   p          = table + 8204;
-    FT_ULong   num_groups = TT_NEXT_ULONG(p);
-    FT_ULong   n, start, end, start_id;
+    FT_UInt32  num_groups = TT_NEXT_ULONG(p);
+    FT_UInt32  n, start, end, start_id;
 
     ++char_code;
     p = table + 8208;
@@ -1208,20 +1203,21 @@
   }
 
 
-  FT_CALLBACK_TABLE const TT_Cmap_ClassRec  tt_cmap8_class_rec =
+  FT_CALLBACK_TABLE const TT_CMap_ClassRec  tt_cmap8_class_rec =
   {
     {
       sizeof( FT_CMapRec ),
-      
+
       (FT_CMap_InitFunc)      tt_cmap_init,
       (FT_CMap_DoneFunc)      NULL,
       (FT_CMap_CharIndexFunc) tt_cmap8_char_index,
       (FT_CMap_CharNextFunc)  tt_cmap8_char_next
     },
+    8,
     (TT_CMap_ValidateFunc)    tt_cmap8_validate
   };
 
-  FT_LOCAL_DEF  TT_CMap_Class tt_cmap8_class = &tt_cmap8_class_rec;
+  FT_LOCAL_DEF( TT_CMap_Class )  tt_cmap8_class = &tt_cmap8_class_rec;
 
 #endif /* TT_CONFIG_CMAP_FORMAT_8 */
 
@@ -1286,14 +1282,15 @@
 
 
   FT_CALLBACK_DEF FT_UInt
-  tt_cmap10_char_index( FT_Byte*   table,
-                        FT_ULong   char_code )
+  tt_cmap10_char_index( TT_CMap    cmap,
+                        FT_UInt32  char_code )
   {
-    FT_UInt   result = 0;
-    FT_Byte*  p      = table + 12;
-    FT_ULong  start  = TT_NEXT_ULONG(p);
-    FT_ULong  count  = TT_NEXT_ULONG(p);
-    FT_ULong  index  = (FT_ULong)( char_code - start );
+    FT_Byte*   table  = cmap->data;
+    FT_UInt    result = 0;
+    FT_Byte*   p      = table + 12;
+    FT_UInt32  start  = TT_NEXT_ULONG(p);
+    FT_UInt32  count  = TT_NEXT_ULONG(p);
+    FT_UInt32  index  = (FT_ULong)( char_code - start );
 
     if ( index < count )
     {
@@ -1304,23 +1301,24 @@
   }
 
 
-  FT_CALLBACK_DEF FT_ULong
-  tt_cmap10_char_next( FT_Byte*    table,
-                       FT_ULong    char_code,
+  FT_CALLBACK_DEF FT_UInt32
+  tt_cmap10_char_next( TT_CMap     cmap,
+                       FT_UInt32   char_code,
                        FT_UInt    *agindex )
   {
-    FT_ULong  result = 0;
-    FT_UInt   gindex = 0;
-    FT_Byte*  p      = table + 12;
-    FT_ULong  start  = TT_NEXT_ULONG(p);
-    FT_ULong  count  = TT_NEXT_ULONG(p);
-    FT_ULong  index;
+    FT_Byte*   table  = cmap->data;
+    FT_UInt32  result = 0;
+    FT_UInt    gindex = 0;
+    FT_Byte*   p      = table + 12;
+    FT_UInt32  start  = TT_NEXT_ULONG(p);
+    FT_UInt32  count  = TT_NEXT_ULONG(p);
+    FT_UInt32  index;
 
     char_code++;
     if ( char_code < start )
       char_code = start;
 
-    index = (FT_ULong)( char_code - start );
+    index = (FT_UInt32)( char_code - start );
     p    += 2*index;
 
     for ( ; index < count; index++ )
@@ -1342,20 +1340,21 @@
   }
 
 
-  FT_CALLBACK_TABLE const TT_Cmap_ClassRec  tt_cmap10_class_rec =
+  FT_CALLBACK_TABLE const TT_CMap_ClassRec  tt_cmap10_class_rec =
   {
     {
       sizeof( FT_CMapRec ),
-      
+
       (FT_CMap_InitFunc)      tt_cmap_init,
       (FT_CMap_DoneFunc)      NULL,
       (FT_CMap_CharIndexFunc) tt_cmap10_char_index,
       (FT_CMap_CharNextFunc)  tt_cmap10_char_next
     },
+    10,
     (TT_CMap_ValidateFunc)    tt_cmap10_validate
   };
 
-  FT_LOCAL_DEF  TT_CMap_Class tt_cmap10_class = &tt_cmap10_class_rec;
+  FT_LOCAL_DEF( TT_CMap_Class )  tt_cmap10_class = &tt_cmap10_class_rec;
 
 #endif /* TT_CONFIG_CMAP_FORMAT_10 */
 
@@ -1445,13 +1444,13 @@
 
 
   FT_CALLBACK_DEF FT_UInt
-  tt_cmap12_char_index( FT_Byte*   table,
-                        FT_ULong   char_code )
+  tt_cmap12_char_index( TT_CMap    cmap,
+                        FT_UInt32  char_code )
   {
-    FT_UInt   result     = 0;
-    FT_Byte*  p          = table + 12;
-    FT_ULong  num_groups = TT_NEXT_ULONG(p);
-    FT_ULong  n, start, end, start_id;
+    FT_UInt    result     = 0;
+    FT_Byte*   p          = table + 12;
+    FT_UInt32  num_groups = TT_NEXT_ULONG(p);
+    FT_UInt32  n, start, end, start_id;
 
     for ( ; num_groups > 0; num_groups-- )
     {
@@ -1472,16 +1471,17 @@
   }
 
 
-  FT_CALLBACK_DEF FT_ULong
-  tt_cmap12_char_next( FT_Byte*   table,
-                       FT_ULong   char_code,
+  FT_CALLBACK_DEF FT_UInt32
+  tt_cmap12_char_next( TT_CMap    cmap,
+                       FT_UInt32  char_code,
                        FT_UInt   *agindex )
   {
-    FT_ULong   result     = 0;
+    FT_Byte*   table      = cmap->data;
+    FT_UInt32  result     = 0;
     FT_UInt    gindex     = 0;
     FT_Byte*   p          = table + 12;
-    FT_ULong   num_groups = TT_NEXT_ULONG(p);
-    FT_ULong   n, start, end, start_id;
+    FT_UInt32  num_groups = TT_NEXT_ULONG(p);
+    FT_UInt32  n, start, end, start_id;
 
     ++char_code;
     p = table + 8208;
@@ -1514,21 +1514,124 @@
   }
 
 
-  FT_CALLBACK_TABLE const TT_Cmap_ClassRec  tt_cmap12_class_rec =
+  FT_CALLBACK_TABLE const TT_CMap_ClassRec  tt_cmap12_class_rec =
   {
     {
       sizeof( FT_CMapRec ),
-      
+
       (FT_CMap_InitFunc)      tt_cmap_init,
       (FT_CMap_DoneFunc)      NULL,
       (FT_CMap_CharIndexFunc) tt_cmap12_char_index,
       (FT_CMap_CharNextFunc)  tt_cmap12_char_next
     },
+    12,
     (TT_CMap_ValidateFunc)    tt_cmap12_validate
   };
 
-  FT_LOCAL_DEF  TT_CMap_Class tt_cmap12_class = &tt_cmap12_class_rec;
+  FT_LOCAL_DEF( TT_CMap_Class )  tt_cmap12_class = &tt_cmap12_class_rec;
 
 #endif /* TT_CONFIG_CMAP_FORMAT_12 */
 
+
+
+  static TT_CMap_Class  tt_cmap_classes[] =
+  {
+#ifdef TT_CONFIG_CMAP_FORMAT_0
+    tt_cmap0_class,
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_2
+    tt_cmap2_class,
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_4
+    tt_cmap4_class,
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_6
+    tt_cmap6_class,
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_8
+    tt_cmap8_class,
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_10
+    tt_cmap10_class,
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_12
+    tt_cmap12_class,
+#endif
+
+    NULL,
+  };
+
+
+ /* parse the 'cmap' table and build the corresponding TT_CMap objects */
+ /* in the current face..                                              */
+ /*                                                                    */
+  FT_LOCAL_DEF( FT_Error )
+  TT_Build_CMaps( TT_Face   face )
+  {
+    TT_CMap_Class    clazz;
+    FT_ValidatorRec  valid;
+    FT_UInt          num_cmaps;
+    FT_Byte*         table = face->cmap_table;
+    FT_Byte*         limit = table + face->cmap_size;
+    FT_Byte*         p     = table;
+    FT_UInt          format;
+
+    if ( p + 4 < limit )
+      return FT_Err_Invalid_Table;
+
+    /* only recognize format 0 */
+    if ( NEXT_UShort(p) != 0 )
+      return FT_Err_Invalid_Table;
+
+    num_cmaps = NEXT_UShort(p);
+
+    for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
+    {
+      FT_CharMapRec  charmap;
+      FT_UInt32      offset;
+
+      charmap.platform_id = NEXT_UShort(p);
+      charmap.encoding_id = NEXT_UShort(p);
+      offset              = NEXT_ULong(p);
+
+      if ( offset && table + offset + 2 < limit )
+      {
+        FT_Byte*         cmap   = table + offset;
+        FT_UInt          format = PEEK_UShort(cmap);
+        TT_CMap_Class*   pclazz = tt_cmap_classes;
+        TT_CMap_Class    clazz;
+
+        for ( ; *pclazz; pclazz++ )
+        {
+          clazz = *pclazz;
+          if ( clazz->format == format )
+          {
+            volatile FT_Validator  valid;
+
+            ft_validator_init( &valid, cmap, limit,
+                               FT_VALIDATE_LEVEL_DEFAULT );
+
+            if ( setjmp( valid.jump_buffer ) == 0 )
+              clazz->validate( cmap, &valid );
+
+            if ( valid.error == 0 )
+              (void)FT_CMap_New( clazz, cmap, face, NULL );
+            else
+              FT_ERROR(( "TT_Build_CMaps: broken cmap sub-table ignored !!\n" ));
+          }
+        }
+      }
+    }
+
+    return 0;
+  }
+
+
+
 /* END */
diff --git a/src/sfnt/ttcmap0.h b/src/sfnt/ttcmap0.h
index 338ae2f..90e8a89 100644
--- a/src/sfnt/ttcmap0.h
+++ b/src/sfnt/ttcmap0.h
@@ -27,14 +27,29 @@
 
 FT_BEGIN_HEADER
 
-  FT_LOCAL FT_Error
-  TT_CharMap_Load( TT_Face        face,
-                   TT_CMapTable*  cmap,
-                   FT_Stream      input );
+  typedef struct TT_CMapRec_
+  {
+    FT_CMapRec  cmap;
+    FT_Byte*    data;
 
-  FT_LOCAL FT_Error
-  TT_CharMap_Free( TT_Face        face,
-                   TT_CMapTable*  cmap );
+  } TT_CMapRec, *TT_CMap;
+
+  typedef const struct TT_CMap_ClassRec_*   TT_CMap_Class;
+
+  typedef FT_Error  (*TT_CMap_ValidateFunc)( FT_Byte*      data,
+                                             FT_Validator  valid );
+
+  typedef struct TT_CMap_ClassRec_
+  {
+    FT_CMap_ClassRec      clazz;
+    FT_UInt               format;
+    TT_CMap_ValidateFunc  validate;
+
+  } TT_CMap_ClassRec;
+
+
+  FT_LOCAL( FT_Error )
+  TT_Build_CMaps( TT_Face   face )
 
 
 FT_END_HEADER
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index 8dc5cdc..4127bbd 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -53,7 +53,7 @@
   /* <Return>                                                              */
   /*    A pointer to the table directory entry.  0 if not found.           */
   /*                                                                       */
-  FT_LOCAL_DEF TT_Table*
+  FT_LOCAL_DEF( TT_Table* )
   TT_LookUp_Table( TT_Face   face,
                    FT_ULong  tag  )
   {
@@ -104,7 +104,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Goto_Table( TT_Face    face,
                  FT_ULong   tag,
                  FT_Stream  stream,
@@ -159,7 +159,7 @@
   /*    The header will be checked whether it is valid by looking at the   */
   /*    values of `search_range', `entry_selector', and `range_shift'.     */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_SFNT_Header( TT_Face       face,
                        FT_Stream     stream,
                        FT_Long       face_index,
@@ -294,7 +294,7 @@
   /* <Note>                                                                */
   /*    The stream cursor must be at the font file's origin.               */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_Directory( TT_Face       face,
                      FT_Stream     stream,
                      SFNT_Header*  sfnt )
@@ -388,7 +388,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_Any( TT_Face    face,
                FT_ULong   tag,
                FT_Long    offset,
@@ -519,7 +519,7 @@
   }
 
 
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_Header( TT_Face    face,
                   FT_Stream  stream )
   {
@@ -529,7 +529,7 @@
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_Bitmap_Header( TT_Face    face,
                          FT_Stream  stream )
   {
@@ -554,7 +554,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_MaxProfile( TT_Face    face,
                       FT_Stream  stream )
   {
@@ -816,7 +816,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_Metrics_Header( TT_Face    face,
                           FT_Stream  stream,
                           FT_Bool    vertical )
@@ -915,7 +915,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_Names( TT_Face    face,
                  FT_Stream  stream )
   {
@@ -1080,7 +1080,7 @@
   /* <Input>                                                               */
   /*    face :: A handle to the target face object.                        */
   /*                                                                       */
-  FT_LOCAL_DEF void
+  FT_LOCAL_DEF( void )
   TT_Free_Names( TT_Face  face )
   {
     FT_Memory      memory = face->root.driver->root.memory;
@@ -1115,7 +1115,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_CMap( TT_Face    face,
                 FT_Stream  stream )
   {
@@ -1229,7 +1229,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_OS2( TT_Face    face,
                FT_Stream  stream )
   {
@@ -1371,7 +1371,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_PostScript( TT_Face    face,
                       FT_Stream  stream )
   {
@@ -1429,7 +1429,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_PCLT( TT_Face    face,
                 FT_Stream  stream )
   {
@@ -1496,7 +1496,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_Gasp( TT_Face    face,
                 FT_Stream  stream )
   {
@@ -1573,7 +1573,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_Kern( TT_Face    face,
                 FT_Stream  stream )
   {
@@ -1720,7 +1720,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_Hdmx( TT_Face    face,
                 FT_Stream  stream )
   {
@@ -1798,7 +1798,7 @@
   /* <Input>                                                               */
   /*    face :: A handle to the target face object.                        */
   /*                                                                       */
-  FT_LOCAL_DEF void
+  FT_LOCAL_DEF( void )
   TT_Free_Hdmx( TT_Face  face )
   {
     if ( face )
diff --git a/src/sfnt/ttload.h b/src/sfnt/ttload.h
index 2e67e03..45e1ba1 100644
--- a/src/sfnt/ttload.h
+++ b/src/sfnt/ttload.h
@@ -29,29 +29,29 @@
 FT_BEGIN_HEADER
 
 
-  FT_LOCAL TT_Table*
+  FT_LOCAL( TT_Table* )
   TT_LookUp_Table( TT_Face   face,
                    FT_ULong  tag );
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Goto_Table( TT_Face    face,
                  FT_ULong   tag,
                  FT_Stream  stream,
                  FT_ULong*  length );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_SFNT_Header( TT_Face       face,
                        FT_Stream     stream,
                        FT_Long       face_index,
                        SFNT_Header*  sfnt );
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_Directory( TT_Face       face,
                      FT_Stream     stream,
                      SFNT_Header*  sfnt );
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_Any( TT_Face    face,
                FT_ULong   tag,
                FT_Long    offset,
@@ -59,70 +59,70 @@
                FT_ULong*  length );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_Header( TT_Face    face,
                   FT_Stream  stream );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_Metrics_Header( TT_Face    face,
                           FT_Stream  stream,
                           FT_Bool    vertical );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_CMap( TT_Face    face,
                 FT_Stream  stream );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_MaxProfile( TT_Face    face,
                       FT_Stream  stream );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_Names( TT_Face    face,
                  FT_Stream  stream );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_OS2( TT_Face    face,
                FT_Stream  stream );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_PostScript( TT_Face    face,
                       FT_Stream  stream );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_Hdmx( TT_Face    face,
                 FT_Stream  stream );
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_PCLT( TT_Face    face,
                 FT_Stream  stream );
 
-  FT_LOCAL void
+  FT_LOCAL( void )
   TT_Free_Names( TT_Face  face );
 
 
-  FT_LOCAL void
+  FT_LOCAL( void )
   TT_Free_Hdmx ( TT_Face  face );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_Kern( TT_Face    face,
                 FT_Stream  stream );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_Gasp( TT_Face    face,
                 FT_Stream  stream );
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_Bitmap_Header( TT_Face    face,
                          FT_Stream  stream );
 
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
index 6942ff4..fa2baee 100644
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -377,7 +377,7 @@
   }
 
 
-  FT_LOCAL_DEF void
+  FT_LOCAL_DEF( void )
   TT_Free_Post_Names( TT_Face  face )
   {
     FT_Memory       memory = face->root.memory;
@@ -441,7 +441,7 @@
   /* <Output>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Get_PS_Name( TT_Face      face,
                   FT_UInt      index,
                   FT_String**  PSname )
diff --git a/src/sfnt/ttpost.h b/src/sfnt/ttpost.h
index 2c30122..3c42e36 100644
--- a/src/sfnt/ttpost.h
+++ b/src/sfnt/ttpost.h
@@ -29,12 +29,12 @@
 FT_BEGIN_HEADER
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Get_PS_Name( TT_Face      face,
                   FT_UInt      index,
                   FT_String**  PSname );
 
-  FT_LOCAL void
+  FT_LOCAL( void )
   TT_Free_Post_Names( TT_Face  face );
 
 
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 645d99e..41cdf66 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -391,7 +391,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_SBit_Strikes( TT_Face    face,
                         FT_Stream  stream )
   {
@@ -588,7 +588,7 @@
   /* <Input>                                                               */
   /*    face :: The target face object.                                    */
   /*                                                                       */
-  FT_LOCAL_DEF void
+  FT_LOCAL_DEF( void )
   TT_Free_SBit_Strikes( TT_Face  face )
   {
     FT_Memory        memory       = face->root.memory;
@@ -623,7 +623,7 @@
   }
 
 
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Set_SBit_Strike( TT_Face    face,
                       FT_Int     x_ppem,
                       FT_Int     y_ppem,
@@ -1395,7 +1395,7 @@
   /*  <Note>                                                               */
   /*    The `map.buffer' field is always freed before the glyph is loaded. */
   /*                                                                       */
-  FT_LOCAL_DEF FT_Error
+  FT_LOCAL_DEF( FT_Error )
   TT_Load_SBit_Image( TT_Face           face,
                       FT_ULong          strike_index,
                       FT_UInt           glyph_index,
diff --git a/src/sfnt/ttsbit.h b/src/sfnt/ttsbit.h
index 2e0c236..b421c86 100644
--- a/src/sfnt/ttsbit.h
+++ b/src/sfnt/ttsbit.h
@@ -27,21 +27,21 @@
 FT_BEGIN_HEADER
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_SBit_Strikes( TT_Face    face,
                         FT_Stream  stream );
 
-  FT_LOCAL void
+  FT_LOCAL( void )
   TT_Free_SBit_Strikes( TT_Face  face );
 
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Set_SBit_Strike( TT_Face    face,
                       FT_Int     x_ppem,
                       FT_Int     y_ppem,
                       FT_ULong  *astrike_index );
 
-  FT_LOCAL FT_Error
+  FT_LOCAL( FT_Error )
   TT_Load_SBit_Image( TT_Face           face,
                       FT_ULong          strike_index,
                       FT_UInt           glyph_index,