* docs/CHANGES: small update

        * src/type1/t1objs.c (SFNT_Face_Init),
          src/cid/cidobjs.c (CID_Face_Init),
          src/cff/cffobjs.c (CFF_Face_Init): removed the bug that prevented
          correct bounding box values from being returned. (previous values
          were in 16.16 fixed format :-() !!

        * src/sfnt/ttload.c (TT_Load_Names), src/sfnt/sfobj.c (Get_Name),
        src/sfnt/sfdriver.c (get_sfnt_postscript_name):
        fixed the loader so that it accepts broken fonts like "foxjump.ttf",
        which make FreeType crash when trying to load them..

        also improved the name table parser to be able to load Windows-encoded
        entries before Macintosh or Unicode ones, since it seems some fonts
        don't have reliable values here anyway..

        * src/cid/cidriver.c (cid_get_postscript_name): fixed the routine
        used to return a CID font's Postscript name, in order to remove the
        leading "/"

        * include/freetype/internal/ftdebug.h: introduced the FT_TRACE_TEST
        macro to simplify debugging output a bit..

        * include/freetype/freetype.h: changed patch level to 9
        - added the declarations of FT_Get_First_Char and FT_Get_Next_Char

        * src/base/ftobjs.c: implemented FT_Get_First_Char and FT_Get_Next_Char
        to allow charmap enumeration..
diff --git a/ChangeLog b/ChangeLog
index 6a3123a..5ebd385 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,13 +1,42 @@
+2002-03-04  David Turner  <david@freetype.org>
+
+        * docs/CHANGES: small update
+
+        * src/type1/t1objs.c (SFNT_Face_Init),
+          src/cid/cidobjs.c (CID_Face_Init),
+          src/cff/cffobjs.c (CFF_Face_Init): removed the bug that prevented
+          correct bounding box values from being returned. (previous values
+          were in 16.16 fixed format :-() !!
+
+        * src/sfnt/ttload.c (TT_Load_Names), src/sfnt/sfobj.c (Get_Name),
+        src/sfnt/sfdriver.c (get_sfnt_postscript_name):
+        fixed the loader so that it accepts broken fonts like "foxjump.ttf",
+        which make FreeType crash when trying to load them..
+
+        also improved the name table parser to be able to load Windows-encoded
+        entries before Macintosh or Unicode ones, since it seems some fonts
+        don't have reliable values here anyway..
+
+        * src/cid/cidriver.c (cid_get_postscript_name): fixed the routine
+        used to return a CID font's Postscript name, in order to remove the
+        leading "/"
+
+        * include/freetype/internal/ftdebug.h: introduced the FT_TRACE_TEST
+        macro to simplify debugging output a bit..
+
+2002-02-28  David Turner  <david@freetype.org>
+
+        * include/freetype/freetype.h: changed patch level to 9
+        - added the declarations of FT_Get_First_Char and FT_Get_Next_Char
+
+        * src/base/ftobjs.c: implemented FT_Get_First_Char and FT_Get_Next_Char
+        to allow charmap enumeration..
+
 2002-02-28  David Turner  <david@freetype.org>
 
         * STABLE branch created, the HEAD is used for the major re-factoring
         needed to get FreeType 2.2 out
 
-        * src/sfnt/ttload.c (TT_Load_Names): simplifying and securing the
-        names table loader. Invalid individual name entries are now handled
-        correctly. This allows the loading of very buggy fonts like
-        "foxjump.ttf" without allocating tons of memory and causing crashes..
-
 2002-02-08  David Turner  <david@freetype.org>
 
 	* Version 2.0.8 released.
diff --git a/docs/CHANGES b/docs/CHANGES
index faec62a..1ad7f37 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,3 +1,46 @@
+LATESET CHANGES BETWEEN 2.0.9 and 2.0.8
+
+  I. IMPORTANT BUG FIXES
+  
+    - Certain fonts, lilke "foxjump.ttf" contain broken name tables with
+      invalid entries and wild offsets. This caused FreeType to crash when
+      trying to load them.
+      
+      the SFNT 'name' table loader has been fixed to be able to support these
+      strange fonts..
+
+      Moreover, the code in charge of processing this table has been changed
+      to always favor Windows-formatted entries over other ones. Hence, a
+      font that works on Windows but not on the Mac will load cleanly in
+      FreeType and report accurate values for Family & Postscript names
+
+    - the CID font driver has been fixed. It unfortunately returned a
+      Postscript Font name with a leading slash, as in
+      "/MunhwaGothic-Regular"
+
+
+  II. NEW FEATURES:
+
+    - Two new APIs have been added: FT_Get_First_Char and FT_Get_Next_Char..
+    
+      together, these can be used to iterate efficiently over the currently
+      selected charmap of a given face. Read the API reference for more
+      details..
+
+
+  III. MISCELLANEOUS:
+  
+    - The FreeType sources are under heavy internal re-factoring. As a
+      consequence, we have created a branch named "STABLE" on the CVS
+      to hold all future releases/fixes in the 2.0.x family..
+      
+      the HEAD branch now contain the re-factored sources and shouldn't
+      be used for testing or packaging new releases.. In the cases where
+      you'd like to access the 2.0.9 sources from our CVS repository, you
+      should use the tag VER-2-0-9..
+
+============================================================================
+
 LATEST CHANGES BETWEEN 2.0.8 and 2.0.7
 
   I. IMPORTANT BUG FIXES
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 40a4e65..230494e 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -35,7 +35,7 @@
   /*                                                                       */
 #define FREETYPE_MAJOR 2
 #define FREETYPE_MINOR 0
-#define FREETYPE_PATCH 8
+#define FREETYPE_PATCH 9
 
 
 #include <ft2build.h>
@@ -2394,6 +2394,88 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Get_First_Char                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used to return the first character code in the    */
+  /*    current charmap of a given face. It will also return the           */
+  /*    corresponding glyph index.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face     :: A handle to the source face object.                    */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    agindex  :: glyph index of first character code. 0 if charmap      */
+  /*                is empty..                                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    the charmap's first character code.                                */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    you should use this function with @FT_Get_Next_Char to be able     */
+  /*    to parse all character codes available in a given charmap.         */
+  /*    the code should look like:                                         */
+  /*                                                                       */
+  /*    {                                                                  */
+  /*      FT_ULong  charcode;                                              */
+  /*      FT_UInt   gindex;                                                */
+  /*                                                                       */
+  /*      charcode = FT_Get_First_Char( face, &gindex );                   */
+  /*      while ( gindex != 0 )                                            */
+  /*      {                                                                */
+  /*        .. do something with (charcode,gindex) pair                    */
+  /*                                                                       */
+  /*        charcode = FT_Get_Next_Char( face, charcode, &gindex );        */
+  /*      }                                                                */
+  /*    }                                                                  */
+  /*                                                                       */
+  /*    note that '*agindex' will be set to 0 if the charmap is empty.     */
+  /*    the result itself can be 0 in two cases: if the charmap is empty   */
+  /*    or when the value 0 is the first valid character code.             */
+  /*                                                                       */
+  FT_EXPORT( FT_ULong )
+  FT_Get_First_Char( FT_Face   face,
+                     FT_UInt  *agindex );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Next_Char                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used to return the next character code in the     */
+  /*    current charmap of a given face following the value 'char_code',   */
+  /*    as well as the corresponding glyph index                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face      :: A handle to the source face object.                   */
+  /*    char_code :: starting character code                               */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    agindex  :: glyph index of first character code. 0 if charmap      */
+  /*                is empty..                                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    the charmap's next character code.                                 */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    you should use this function with @FT_Get_First_Char to be able    */
+  /*    to parse all character codes available in a given charmap. see     */
+  /*    the note for this function for a simple code example..             */
+  /*                                                                       */
+  /*    note that '*agindex' will be set to 0 when there are no more       */
+  /*    codes in the charmap..                                             */
+  /*                                                                       */
+  FT_EXPORT( FT_ULong )
+  FT_Get_Next_Char( FT_Face    face,
+                    FT_ULong   char_code,
+                    FT_UInt   *agindex );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Get_Name_Index                                                  */
   /*                                                                       */
   /* <Description>                                                         */
diff --git a/include/freetype/internal/ftdebug.h b/include/freetype/internal/ftdebug.h
index e18acbb..1de4be5 100644
--- a/include/freetype/internal/ftdebug.h
+++ b/include/freetype/internal/ftdebug.h
@@ -127,11 +127,12 @@
   /*                                                                       */
   /*************************************************************************/
 
+#define FT_TRACE_TEST(level)    ( ft_trace_levels[FT_COMPONENT] >= level )
 
 #define FT_TRACE( level, varformat )                      \
           do                                              \
           {                                               \
-            if ( ft_trace_levels[FT_COMPONENT] >= level ) \
+            if ( FT_TRACE_TEST(level) )                   \
               FT_Message varformat;                       \
           } while ( 0 )
 
@@ -158,6 +159,7 @@
 
 #elif defined( FT_DEBUG_LEVEL_ERROR )
 
+#define FT_TRACE_TEST(level)     0
 
 #define FT_TRACE( level, varformat )  do ; while ( 0 )      /* nothing */
 
@@ -167,6 +169,7 @@
 
 #define FT_Assert( condition )        do ; while ( 0 )      /* nothing */
 
+#define FT_TRACE_TEST(level)          0
 #define FT_TRACE( level, varformat )  do ; while ( 0 )      /* nothing */
 #define FT_ERROR( varformat )         do ; while ( 0 )      /* nothing */
 
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 21a6be0..c4de8f3 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1867,22 +1867,56 @@
     return result;
   }
 
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_ULong )
+  FT_Get_First_Char( FT_Face   face,
+                     FT_UInt  *agindex )
+  {
+    FT_ULong   result = 0;
+    FT_UInt    gindex = 0;
+    
+    if ( face && face->charmap )
+    {
+      gindex = FT_Get_Char_Index( face, 0 );
+      if ( gindex == 0 )
+        result = FT_Get_Next_Char( face, 0, &gindex );
+    }
+    
+    if ( agindex  )
+      *agindex = gindex;
+      
+    return result;
+  }
+
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_ULong )
   FT_Get_Next_Char( FT_Face   face,
-                    FT_ULong  charcode )
+                    FT_ULong  charcode,
+                    FT_UInt  *agindex )
   {
-    FT_ULong   result;
+    FT_ULong   result = 0;
+    FT_UInt    gindex = 0;
     FT_Driver  driver;
 
 
-    result = 0;
     if ( face && face->charmap )
     {
       driver = face->driver;
       result = driver->clazz->get_next_char( face->charmap, charcode );
+      if ( result != 0 )
+      {
+        gindex = driver->clazz->get_char_index( face->charmap, result );
+        if ( gindex == 0 )
+          result = 0;
+      }
     }
+    
+    if ( agindex )
+      *agindex = gindex;
+      
     return result;
   }
 
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 0211b8e..1bf0195 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -571,9 +571,13 @@
           root->num_glyphs = cff->charstrings_index.count;
 
         /* set global bbox, as well as EM size */
-        root->bbox      = dict->font_bbox;
-        root->ascender  = (FT_Short)( root->bbox.yMax >> 16 );
-        root->descender = (FT_Short)( root->bbox.yMin >> 16 );
+        root->bbox.xMin =  dict->font_bbox.xMin >> 16;
+        root->bbox.yMin =  dict->font_bbox.yMin >> 16;
+        root->bbox.xMax = (dict->font_bbox.xMax + 0xFFFFU) >> 16;
+        root->bbox.yMax = (dict->font_bbox.yMax + 0xFFFFU) >> 16;
+        
+        root->ascender  = (FT_Short)( root->bbox.yMax );
+        root->descender = (FT_Short)( root->bbox.yMin );
         root->height    = (FT_Short)(
           ( ( root->ascender - root->descender ) * 12 ) / 10 );
 
diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c
index c42d0e8..1a43e75 100644
--- a/src/cid/cidobjs.c
+++ b/src/cid/cidobjs.c
@@ -381,41 +381,19 @@
         root->num_fixed_sizes = 0;
         root->available_sizes = 0;
 
-        root->bbox = face->cid.font_bbox;
+        root->bbox.xMin =  face->cid.font_bbox.xMin >> 16;
+        root->bbox.yMin =  face->cid.font_bbox.yMin >> 16;
+        root->bbox.xMax = (face->cid.font_bbox.xMax + 0xFFFFU) >> 16;
+        root->bbox.yMax = (face->cid.font_bbox.yMax + 0xFFFFU) >> 16;
+
         if ( !root->units_per_EM )
           root->units_per_EM  = 1000;
 
-        root->ascender  = (FT_Short)( face->cid.font_bbox.yMax >> 16 );
-        root->descender = (FT_Short)( face->cid.font_bbox.yMin >> 16 );
+        root->ascender  = (FT_Short)( face->cid.font_bbox.yMax );
+        root->descender = (FT_Short)( face->cid.font_bbox.yMin );
         root->height    = (FT_Short)(
           ( ( root->ascender + root->descender ) * 12 ) / 10 );
 
-
-#if 0
-
-        /* now compute the maximum advance width */
-
-        root->max_advance_width = face->type1.private_dict.standard_width[0];
-
-        /* compute max advance width for proportional fonts */
-        if ( !face->type1.font_info.is_fixed_pitch )
-        {
-          FT_Int  max_advance;
-
-
-          error = CID_Compute_Max_Advance( face, &max_advance );
-
-          /* in case of error, keep the standard width */
-          if ( !error )
-            root->max_advance_width = max_advance;
-          else
-            error = 0;   /* clear error */
-        }
-
-        root->max_advance_height = root->height;
-
-#endif /* 0 */
-
         root->underline_position  = face->cid.font_info.underline_position;
         root->underline_thickness = face->cid.font_info.underline_thickness;
 
@@ -424,73 +402,6 @@
       }
     }
 
-#if 0
-
-    /* charmap support - synthetize unicode charmap when possible */
-    {
-      FT_Face      root    = &face->root;
-      FT_CharMap   charmap = face->charmaprecs;
-
-
-      /* synthesize a Unicode charmap if there is support in the `psnames' */
-      /* module                                                            */
-      if ( face->psnames )
-      {
-        PSNames_Interface*  psnames = (PSNames_Interface*)face->psnames;
-
-
-        if ( psnames->unicode_value )
-        {
-          error = psnames->build_unicodes(
-                             root->memory,
-                             face->type1.num_glyphs,
-                             (const char**)face->type1.glyph_names,
-                             &face->unicode_map );
-          if ( !error )
-          {
-            root->charmap        = charmap;
-            charmap->face        = (FT_Face)face;
-            charmap->encoding    = ft_encoding_unicode;
-            charmap->platform_id = 3;
-            charmap->encoding_id = 1;
-            charmap++;
-          }
-
-          /* simply clear the error in case of failure (which really */
-          /* means that out of memory or no unicode glyph names)     */
-          error = 0;
-        }
-      }
-
-      /* now, support either the standard, expert, or custom encodings */
-      charmap->face        = (FT_Face)face;
-      charmap->platform_id = 7;  /* a new platform id for Adobe fonts? */
-
-      switch ( face->type1.encoding_type )
-      {
-      case t1_encoding_standard:
-        charmap->encoding    = ft_encoding_adobe_standard;
-        charmap->encoding_id = 0;
-        break;
-
-      case t1_encoding_expert:
-        charmap->encoding    = ft_encoding_adobe_expert;
-        charmap->encoding_id = 1;
-        break;
-
-      default:
-        charmap->encoding    = ft_encoding_adobe_custom;
-        charmap->encoding_id = 2;
-        break;
-      }
-
-      root->charmaps     = face->charmaps;
-      root->num_charmaps = charmap - face->charmaprecs + 1;
-      face->charmaps[0]  = &face->charmaprecs[0];
-      face->charmaps[1]  = &face->charmaprecs[1];
-    }
-
-#endif /* 0 */
 
   Exit:
     return error;
diff --git a/src/cid/cidriver.c b/src/cid/cidriver.c
index 21f0594..e832973 100644
--- a/src/cid/cidriver.c
+++ b/src/cid/cidriver.c
@@ -42,7 +42,12 @@
   static const char*
   cid_get_postscript_name( CID_Face  face )
   {
-    return (const char*)face->cid.cid_font_name;
+    const char*  result = face->cid.cid_font_name;
+    
+    if ( result && result[0] == '/' )
+      result++;
+      
+    return result;
   }
 
 
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 48fa643..af92ed2 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -114,7 +114,7 @@
   static const char*
   get_sfnt_postscript_name( TT_Face  face )
   {
-    FT_Int  n;
+    FT_Int  n, found_win, found_apple;
 
 
     /* shouldn't happen, but just in case to avoid memory leaks */
@@ -123,38 +123,66 @@
 
     /* scan the name table to see whether we have a Postscript name here, */
     /* either in Macintosh or Windows platform encodings                  */
+    found_win     = -1;
+    found_apple   = -1;
+    
     for ( n = 0; n < face->num_names; n++ )
     {
       TT_NameRec*  name = face->name_table.names + n;
 
 
-      if ( name->nameID == 6 )
+      if ( name->nameID == 6 && name->string != NULL )
       {
-        if ( ( name->platformID == 3 &&
-               name->encodingID == 1 &&
-               name->languageID == 0x409 ) ||
-
-             ( name->platformID == 1 &&
-               name->encodingID == 0 &&
-               name->languageID == 0     ) )
-        {
-          FT_UInt     len = name->stringLength;
-          FT_Error    error;
-          FT_Memory   memory = face->root.memory;
-          FT_String*  result;
-
-
-          if ( !ALLOC( result, len + 1 ) )
-          {
-            memcpy( result, name->string, len );
-            result[len] = '\0';
-
-            face->root.internal->postscript_name = result;
-          }
-          return result;
-        }
+        if ( name->platformID == 3     &&
+             name->encodingID == 1     &&
+             name->languageID == 0x409 )
+          found_win = n;
+          
+        if ( name->platformID == 1 &&
+             name->encodingID == 0 &&
+             name->languageID == 0 )
+          found_apple = n;
       }
     }
+    
+    if ( found_win )
+    {
+      FT_Memory    memory = face->root.memory;
+      TT_NameRec*  name   = face->name_table.names + found_win;
+      FT_UInt      len    = name->stringLength/2;
+      FT_Error     error;
+      FT_String*   result;
+      
+      if ( !ALLOC( result, len+1 ) )
+      {
+        FT_String*  r = result;
+        FT_Byte*    p = (FT_Byte*) name->string;
+        
+        for ( ; len > 0; len--, p += 2 )
+        {
+          if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
+            *r++ = p[1];
+        }
+        *r = '\0';
+      }
+      return result;
+    }
+
+    if ( found_apple )
+    {
+      FT_Memory    memory = face->root.memory;
+      TT_NameRec*  name   = face->name_table.names + found_win;
+      FT_UInt      len    = name->stringLength;
+      FT_Error     error;
+      FT_String*   result;
+      
+      if ( !ALLOC( result, len+1 ) )
+      {
+        MEM_Copy( result, name->string, len );
+        result[len] = '\0';
+      }
+      return result;
+    }
 
     return NULL;
   }
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 119fc35..9d54b76 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -60,70 +60,96 @@
     FT_Memory    memory = face->root.memory;
     FT_UShort    n;
     TT_NameRec*  rec;
-    FT_Bool      wide_chars = 1;
+    FT_Bool      wide_chars    = 1;
+    FT_Int       found_apple   = -1;
+    FT_Int       found_win     = -1;
+    FT_Int       found_unicode = -1;
+    FT_Int       found;
 
 
     rec = face->name_table.names;
     for ( n = 0; n < face->name_table.numNameRecords; n++, rec++ )
     {
-      if ( rec->nameID == nameid )
+      if ( rec->nameID == nameid && rec->string )
       {
-        /* found the name -- now create an ASCII string from it */
-        FT_Bool  found = 0;
-
-
-        /* test for Microsoft English language */
-        if ( rec->platformID == TT_PLATFORM_MICROSOFT &&
-             rec->encodingID <= TT_MS_ID_UNICODE_CS   &&
-             ( rec->languageID & 0x3FF ) == 0x009     )
-          found = 1;
-
-        /* test for Apple Unicode encoding */
-        else if ( rec->platformID == TT_PLATFORM_APPLE_UNICODE )
-          found = 1;
-
-        /* test for Apple Roman */
-        else if ( rec->platformID == TT_PLATFORM_MACINTOSH &&
-                  rec->languageID == TT_MAC_ID_ROMAN       )
+        switch ( rec->platformID )
         {
-          found      = 1;
-          wide_chars = 0;
-        }
-
-        /* found a Unicode name */
-        if ( found )
-        {
-          FT_String*  string;
-          FT_UInt     len;
-
-
-          if ( wide_chars )
-          {
-            FT_UInt   m;
-
-
-            len = (FT_UInt)rec->stringLength / 2;
-            if ( MEM_Alloc( string, len + 1 ) )
-              return NULL;
-
-            for ( m = 0; m < len; m ++ )
-              string[m] = rec->string[2 * m + 1];
-          }
-          else
-          {
-            len = rec->stringLength;
-            if ( MEM_Alloc( string, len + 1 ) )
-              return NULL;
-
-            MEM_Copy( string, rec->string, len );
-          }
-
-          string[len] = '\0';
-          return string;
+          case TT_PLATFORM_APPLE_UNICODE:
+            {
+              found_unicode = n;
+              break;
+            }
+            
+          case TT_PLATFORM_MACINTOSH:
+            {
+              if ( rec->languageID == TT_MAC_ID_ROMAN )
+                found_apple = n;
+              
+              break;
+            }
+            
+          case TT_PLATFORM_MICROSOFT:
+            {
+              if (  rec->encodingID <= TT_MS_ID_UNICODE_CS &&
+                   (rec->languageID & 0x3FF) == 0x009      )
+              {
+                found_win = n;
+              }
+              break;
+            }
+          
+          default:
+            ;
         }
       }
     }
 
+    /* some fonts contain invalid Unicode or Macintosh formatted entries */
+    /* we will thus favor name encoded in Windows formats when they're   */
+    /* available..                                                       */
+    /*                                                                   */
+    found = found_win;
+    if ( found < 0 )
+    {
+      found = found_apple;
+      if ( found_apple < 0 )
+        found = found_unicode;
+      else
+        wide_chars = 0;
+    }
+
+    /* found a Unicode name */
+    if ( found >= 0 )
+    {
+      FT_String*  string;
+      FT_UInt     len;
+
+      rec = face->name_table.names + found;
+      if ( wide_chars )
+      {
+        FT_UInt   m;
+
+
+        len = (FT_UInt)rec->stringLength / 2;
+        if ( MEM_Alloc( string, len + 1 ) )
+          return NULL;
+
+        for ( m = 0; m < len; m ++ )
+          string[m] = rec->string[2 * m + 1];
+      }
+      else
+      {
+        len = rec->stringLength;
+        if ( MEM_Alloc( string, len + 1 ) )
+          return NULL;
+
+        MEM_Copy( string, rec->string, len );
+      }
+
+      string[len] = '\0';
+      return string;
+    }
+
     return NULL;
   }
 
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index 8dc5cdc..4db3deb 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -27,6 +27,7 @@
 #include "sferrors.h"
 
 #include <stdlib.h>  /* for qsort */
+#include <stdio.h>   /* for printf */
 
   /*************************************************************************/
   /*                                                                       */
@@ -923,10 +924,12 @@
     FT_Memory  memory = stream->memory;
 
     FT_ULong   table_pos, table_len;
-    FT_ULong   storageOffset, storageSize;
+    FT_ULong   storageSize, storageOffset;
     FT_Byte*   storage;
 
-    TT_NameTable*  names;
+    TT_NameTable*  table;
+    TT_NameRec*    names;
+    FT_UInt        num_names;
 
     const FT_Frame_Field  name_table_fields[] =
     {
@@ -969,100 +972,247 @@
 
     table_pos = FILE_Pos();
 
-    names = &face->name_table;
+    table = &face->name_table;
 
-    if ( READ_Fields( name_table_fields, names ) )
+    if ( READ_Fields( name_table_fields, table ) )
       goto Exit;
 
-    /* check the 'storageOffset' field */
-    storageOffset = names->storageOffset;
-    if ( storageOffset <  (FT_ULong)(6 + 12*names->numNameRecords) ||
-         table_len     <= storageOffset                            )
+    num_names     = (FT_UInt) table->numNameRecords;
+    storageOffset = table->storageOffset;
+    storageSize   = (FT_ULong)( table_len - storageOffset );
+    
+    /* check the storage offset field */
+    if ( storageOffset < 6 + 12*num_names ||
+         table_len     < storageOffset    )
     {
-      FT_ERROR(( "TT.load_names: invalid 'name' table\n" ));
+      FT_TRACE2(( "table is broken.. Ignoring !!\n" ));
+      
+      table->numNameRecords = 0;
+      table->storageOffset  = 0;
+      
       error = SFNT_Err_Name_Table_Missing;
       goto Exit;
     }
-
-    storageSize = (FT_ULong)(table_len - storageOffset);
-
+    
     /* Allocate the array of name records. */
-    if ( ALLOC( names->names,
-                names->numNameRecords*sizeof(TT_NameRec) + storageSize )  ||
-         ACCESS_Frame( names->numNameRecords * 12L ) )
+    if ( ALLOC( table->names,
+                num_names*sizeof(table->names[0]) + storageSize ) ||
+         ACCESS_Frame( num_names*12L ) )
       goto Exit;
 
-    storage = (FT_Byte*)(names->names + names->numNameRecords);
+    names   = table->names;
+    storage = (FT_Byte*)(names + num_names);
 
     /* Load the name records and determine how much storage is needed */
     /* to hold the strings themselves.                                */
     {
-      TT_NameRec*  cur   = names->names;
-      TT_NameRec*  limit = cur + names->numNameRecords;
-
+      TT_NameRec*  cur   = names;
+      TT_NameRec*  limit = cur + num_names;
 
       for ( ; cur < limit; cur ++ )
       {
-        FT_ULong  upper;
-
-
         if ( READ_Fields( name_record_fields, cur ) )
           break;
 
-        /* invalid name entries will have "cur->string" set to NULL !! */
-        if ( (FT_ULong)(cur->stringOffset + cur->stringLength) < storageSize )
+        /* check the fields */
+        if ( cur->stringOffset + cur->stringLength <= (FT_Long)storageSize )
           cur->string = storage + cur->stringOffset;
+        else
+        {
+          /* that's an invalid entry !! */
+          cur->stringOffset = 0;
+          cur->string       = NULL;
+        }
       }
     }
 
     FORGET_Frame();
-
-    if (error)
+    
+    if ( error )
       goto Exit;
 
-#ifdef FT_DEBUG_LEVEL_TRACE
+    storageOffset -= 6 + 12*num_names;
+    if ( FILE_Skip( storageOffset )        ||
+         FILE_Read( storage, storageSize ) )
+      goto Exit;
 
-      /* Print Name Record Table in case of debugging */
+
+    /* Print Name Record Table in case of debugging */
+    if ( FT_TRACE_TEST(3) )
+    {
+      TT_NameRec*  cur   = table->names;
+      TT_NameRec*  limit = cur + num_names;
+
+
+      for ( ; cur < limit; cur++ )
       {
-        TT_NameRec*  cur   = names->names;
-        TT_NameRec*  limit = cur + names->numNameRecords;
+        FT_UInt  j;
 
 
-        for ( ; cur < limit; cur++ )
-        {
-          FT_UInt  j;
+        printf( "%2d %2d %4x %2d:",
+                 cur->platformID,
+                 cur->encodingID,
+                 cur->languageID,
+                 cur->nameID );
 
-
-          FT_TRACE3(( "(%2d %2d %4x %2d)  ",
-                       cur->platformID,
-                       cur->encodingID,
-                       cur->languageID,
-                       cur->nameID ));
-
-          /* I know that M$ encoded strings are Unicode,            */
-          /* but this works reasonable well for debugging purposes. */
-          if ( cur->string )
-            for ( j = 0; j < (FT_UInt)cur->stringLength; j++ )
-            {
-              FT_Byte  c = *(FT_Byte*)(cur->string + j);
-
-
-              if ( c >= 32 && c < 128 )
-                FT_TRACE3(( "%c", c ));
-            }
-          else
-            FT_TRACE3(( "INVALID ENTRY !!\n" ));
-
-          FT_TRACE3(( "\n" ));
+        /* printf name id */
+        switch ( cur->nameID )
+        {          
+          case 0:  printf( " copyright" ); break;
+          case 1:  printf( " font_family" ); break;
+          case 2:  printf( " style" ); break;
+          case 3:  printf( " unique_id" ); break;
+          case 4:  printf( " full_name" ); break;
+          case 5:  printf( " version" ); break;
+          case 6:  printf( " postscript" ); break;
+          case 7:  printf( " trademark" ); break;
+          case 8:  printf( " manufacturer" ); break;
+          case 9:  printf( " designer" ); break;
+          case 10: printf( " description" ); break;
+          case 11: printf( " url_vendor" ); break;
+          case 12: printf( " url_designer" ); break;
+          case 13: printf( " license" ); break;
+          case 14: printf( " url_license" ); break;
+          case 15: printf( " reserved (15)" ); break;
+          case 16: printf( " prefered_family" ); break;
+          case 17: printf( " prefered_style" ); break;
+          case 18: printf( " mac_full_name" ); break;
+          case 19: printf( " sample_text" ); break;
+          case 20: printf( " cid_name" ); break;
+          default: printf( " unknown_type(%d)", cur->nameID );
         }
-      }
 
-#endif /* FT_DEBUG_LEVEL_TRACE */
+        /* printf platform/encoding id */
+        j = 0;
+        switch ( cur->platformID )
+        {
+          case 0:  /* Unicode encodings */
+            {
+              switch ( cur->encodingID )
+              {
+                case 0: printf( " unicode_1.0" ); break;
+                case 1: printf( " unicode_1.1" ); break;
+                case 2: printf( " ISO_10646" ); break;
+                case 3: printf( " unicode_2.0" ); break;
+                default:
+                  j = 1;
+              }
+              break;
+            }
+          
+          case 1:  /* Apple encodings */
+            {
+              switch ( cur->encodingID )
+              {
+                case 0: printf( " mac_Roman" ); break;
+                case 1: printf( " mac_Japanese" ); break;
+                case 2: printf( " mac_Chinese_traditional" ); break;
+                case 3: printf( " mac_Korean" ); break;
+                case 4: printf( " mac_Arabic" ); break;
+                case 5: printf( " mac_Hebrew" ); break;
+                case 6: printf( " mac_Greek" ); break;
+                case 7: printf( " mac_Russian" ); break;
+                case 8: printf( " mac_RSymbol" ); break;
+                case 9: printf( " mac_Devanagari" ); break;
+                case 10: printf( " mac_Gurmukhi" ); break;
+                case 11: printf( " mac_Gujarati" ); break;
+                case 12: printf( " mac_Oriya" ); break;
+                case 13: printf( " mac_Bengali" ); break;
+                case 14: printf( " mac_Tamil" ); break;
+                case 15: printf( " mac_Telugu" ); break;
+                case 16: printf( " mac_Kannada" ); break;
+                case 17: printf( " mac_Malayalam" ); break;
+                case 18: printf( " mac_Sinhalese" ); break;
+                case 19: printf( " mac_Burmese" ); break;
+                case 20: printf( " mac_Khmer" ); break;
+                case 21: printf( " mac_Thai" ); break;
+                case 22: printf( " mac_Laotian" ); break;
+                case 23: printf( " mac_Goergian" ); break;
+                case 24: printf( " mac_Armenian" ); break;
+                case 25: printf( " mac_Chinese_simplified" ); break;
+                case 26: printf( " mac_Tibetan" ); break;
+                case 27: printf( " mac_Mongolian" ); break;
+                case 28: printf( " mac_Geez" ); break;
+                case 29: printf( " mac_Slavic" ); break;
+                case 30: printf( " mac_Vietnamese" ); break;
+                case 31: printf( " mac_Sindhi" ); break;
+                case 32: printf( " mac_Uninterpreted" ); break;
+                default:
+                  j = 1;
+              }
+              break;
+            }
+        
+          case 2:  /* deprecated IDO encoding */
+            {
+              switch ( cur->encodingID )
+              {
+                case 0: printf( " iso_ASCII" ); break;
+                case 1: printf( " iso_10646" ); break;
+                case 2: printf( " iso_8859-1" ); break;
+                default:
+                  j = 1;
+              }
+              break;
+            }
+          
+          case 3:  /* Windows encodings */
+            {
+              switch ( cur->encodingID )
+              {
+                case 0:  printf( " win_symbol" ); break;
+                case 1:  printf( " win_unicode" ); break;
+                case 2:  printf( " win_shiftJIS" ); break;
+                case 3:  printf( " win_PRC" ); break;
+                case 4:  printf( " win_Big5" ); break;
+                case 5:  printf( " win_Wansung" ); break;
+                case 6:  printf( " win_Johab" ); break;
+                case 10: printf( " win_UCS4" ); break;
+                default:
+                  j = 1;
+              }
+              break;
+            }
+          
+          default:
+            j = 1;
+        }
+
+        if ( j == 1 )
+          printf( " unknown_encoding" );
+
+        printf( "\n    " );
+
+        /* printf language - XXXX for later ....*/
+
+        /* I know that M$ encoded strings are Unicode,            */
+        /* but this works reasonable well for debugging purposes. */
+        if ( cur->string )
+        {
+          for ( j = 0; j < (FT_UInt)cur->stringLength; j++ )
+          {
+            FT_Byte  c = (FT_Byte)*( cur->string + j );
+
+
+            if ( c < 32 || c > 127 )
+              c = '.';
+              
+            printf( "%c", c );
+          }
+        }
+        else
+          printf( "INVALID_ENTRY!!" );
+          
+        printf( "\n" );
+      }
+      printf( "\n" );
+    }
+
 
     FT_TRACE2(( "loaded\n" ));
 
     /* everything went well, update face->num_names */
-    face->num_names = names->numNameRecords;
+    face->num_names = (FT_UShort)num_names;
 
   Exit:
     return error;
diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c
index dfe8125..e9a5c40 100644
--- a/src/type1/t1objs.c
+++ b/src/type1/t1objs.c
@@ -404,20 +404,23 @@
       root->num_fixed_sizes = 0;
       root->available_sizes = 0;
 
-      root->bbox = face->type1.font_bbox;
+      root->bbox.xMin =  face->type1.font_bbox.xMin >> 16;
+      root->bbox.yMin =  face->type1.font_bbox.yMin >> 16;
+      root->bbox.xMax = (face->type1.font_bbox.xMax + 0xFFFFU) >> 16;
+      root->bbox.yMax = (face->type1.font_bbox.yMax + 0xFFFFU) >> 16;
 
       /* Set units_per_EM if we didn't set it in parse_font_matrix. */
       if ( !root->units_per_EM )
         root->units_per_EM = 1000;
 
-      root->ascender  = (FT_Short)( face->type1.font_bbox.yMax >> 16 );
-      root->descender = (FT_Short)( face->type1.font_bbox.yMin >> 16 );
+      root->ascender  = (FT_Short)( face->type1.font_bbox.yMax );
+      root->descender = (FT_Short)( face->type1.font_bbox.yMin );
       root->height    = (FT_Short)(
                           ( ( root->ascender - root->descender ) * 12 ) / 10 );
 
       /* now compute the maximum advance width */
       root->max_advance_width =
-        (FT_Short)( face->type1.font_bbox.xMax >> 16 );
+        (FT_Short)( face->type1.font_bbox.xMax );
       {
         FT_Int  max_advance;