* src/type42/t42drivr.c: s/T42_ENCODING_TYPE_/T1_ENCODING_TYPE_/.
(parse_font_matrix): Remove unnecessary code.
(parse_sfnts): Initialize some variables.
(t42_driver_class) [TT_CONFIG_OPTION_BYTECODE_INTERPRETER]: Use
ft_module_driver_has_hinter conditionally.
Moved some type 42 specific structure definitions to...
* include/freetype/internal/t42types.h: New file.
* include/freetype/internal/internal.h (FT_INTERNAL_T42_TYPES_H):
New macro.

* include/freetype/cache/ftcsbits.h (FTC_SBit): Added a new field
`num_grays' for specifying the number of used gray levels.
* src/cache/ftcsbits.c (ftc_sbit_node_load): Initialize it.

Adding a driver for BDF fonts written by Francesco Zappa Nardelli
<Francesco.Zappa.Nardelli@ens.fr>.  Heavily modified by me to
better adapt it to FreeType, removing unneeded stuff.  Additionally,
it now supports Mark Leisher's BDF extension for anti-aliased
bitmap glyphs with 2 and 4 bpp.

* src/bdf/*: New driver.
* include/freetype/internal/bdftypes.h: New file.
* include/freetype/internal/fttrace.h: Added BDF driver components.
* include/freetype/fterrdef.h: Added error codes for BDF driver.
* include/freetype/config/ftmodule.h, src/Jamfile: Updated.
* include/freetype/internal/internal.h (FT_INTERNAL_BDF_TYPES_H):
New macro.

* include/freetype/config/ftstdlib.h (ft_sprintf): New alias for
sprintf.

* include/freetype/internal/fttrace.h: Added Type 42 driver
component.
* src/type42/t42drivr.c: Use it.

* include/freetype/internal/internal.h (FT_INTERNAL_PCF_TYPES_H):
New macro.
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index d7bc87c..ce00313 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1,6 +1,6 @@
 /*
  * Copyright 2000 Computing Research Labs, New Mexico State University
- * Copyright 2001 Francesco Zappa Nardelli
+ * Copyright 2001, 2002 Francesco Zappa Nardelli
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -21,9 +21,14 @@
  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/*
-static char rcsid[] = "$Id$";
-*/
+  /*************************************************************************/
+  /*                                                                       */
+  /*  This file is based on bdf.c,v 1.22 2000/03/16 20:08:50               */
+  /*                                                                       */
+  /*  taken from Mark Leisher's xmbdfed package                            */
+  /*                                                                       */
+  /*************************************************************************/
+
 
 #include <ft2build.h>
 
@@ -32,779 +37,708 @@
 #include FT_INTERNAL_OBJECTS_H
 
 #include "bdf.h"
-
 #include "bdferror.h"
 
-#undef MAX
-#define MAX(h, i) ((h) > (i) ? (h) : (i))
 
-#undef MIN
-#define MIN(l, o) ((l) < (o) ? (l) : (o))
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_bdflib
 
-/**************************************************************************
- *
- * Masks used for checking different bits per pixel cases.
- *
- **************************************************************************/
 
-static const unsigned char onebpp[]   = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
-static const unsigned char twobpp[]   = { 0xc0, 0x30, 0x0c, 0x03 };
-static const unsigned char fourbpp[]  = { 0xf0, 0x0f };
-static const unsigned char eightbpp[] = { 0xff };
+  /*************************************************************************/
+  /*                                                                       */
+  /* Default BDF font options.                                             */
+  /*                                                                       */
+  /*************************************************************************/
 
-/**************************************************************************
- *
- * Default BDF font options.
- *
- **************************************************************************/
 
-static const bdf_options_t _bdf_opts =
-{
-    1,                /* Hint TTF glyphs.               */
+  static bdf_options_t  _bdf_opts =
+  {
     1,                /* Correct metrics.               */
     1,                /* Preserve unencoded glyphs.     */
-    1,                /* Preserve comments.             */
-    1,                /* Pad character-cells.           */
-    BDF_PROPORTIONAL, /* Default spacing.               */
-    12,               /* Default point size.            */
-    0,                /* Default horizontal resolution. */
-    0,                /* Default vertical resolution.   */
-    1,                /* Bits per pixel.                */
-    BDF_UNIX_EOL,     /* Line separator.                */
-};
+    0,                /* Preserve comments.             */
+    BDF_PROPORTIONAL  /* Default spacing.               */
+  };
 
-/**************************************************************************
- *
- * Builtin BDF font properties.
- *
- **************************************************************************/
 
-/*
- * List of most properties that might appear in a font.  Doesn't include the
- * RAW_* and AXIS_* properties in X11R6 polymorphic fonts.
- */
-static const bdf_property_t _bdf_properties[] =
-{
-    {"ADD_STYLE_NAME",          BDF_ATOM,     1},
-    {"AVERAGE_WIDTH",           BDF_INTEGER,  1},
-    {"AVG_CAPITAL_WIDTH",       BDF_INTEGER,  1},
-    {"AVG_LOWERCASE_WIDTH",     BDF_INTEGER,  1},
-    {"CAP_HEIGHT",              BDF_INTEGER,  1},
-    {"CHARSET_COLLECTIONS",     BDF_ATOM,     1},
-    {"CHARSET_ENCODING",        BDF_ATOM,     1},
-    {"CHARSET_REGISTRY",        BDF_ATOM,     1},
-    {"COMMENT",                 BDF_ATOM,     1},
-    {"COPYRIGHT",               BDF_ATOM,     1},
-    {"DEFAULT_CHAR",            BDF_CARDINAL, 1},
-    {"DESTINATION",             BDF_CARDINAL, 1},
-    {"DEVICE_FONT_NAME",        BDF_ATOM,     1},
-    {"END_SPACE",               BDF_INTEGER,  1},
-    {"FACE_NAME",               BDF_ATOM,     1},
-    {"FAMILY_NAME",             BDF_ATOM,     1},
-    {"FIGURE_WIDTH",            BDF_INTEGER,  1},
-    {"FONT",                    BDF_ATOM,     1},
-    {"FONTNAME_REGISTRY",       BDF_ATOM,     1},
-    {"FONT_ASCENT",             BDF_INTEGER,  1},
-    {"FONT_DESCENT",            BDF_INTEGER,  1},
-    {"FOUNDRY",                 BDF_ATOM,     1},
-    {"FULL_NAME",               BDF_ATOM,     1},
-    {"ITALIC_ANGLE",            BDF_INTEGER,  1},
-    {"MAX_SPACE",               BDF_INTEGER,  1},
-    {"MIN_SPACE",               BDF_INTEGER,  1},
-    {"NORM_SPACE",              BDF_INTEGER,  1},
-    {"NOTICE",                  BDF_ATOM,     1},
-    {"PIXEL_SIZE",              BDF_INTEGER,  1},
-    {"POINT_SIZE",              BDF_INTEGER,  1},
-    {"QUAD_WIDTH",              BDF_INTEGER,  1},
-    {"RAW_ASCENT",              BDF_INTEGER,  1},
-    {"RAW_AVERAGE_WIDTH",       BDF_INTEGER,  1},
-    {"RAW_AVG_CAPITAL_WIDTH",   BDF_INTEGER,  1},
-    {"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER,  1},
-    {"RAW_CAP_HEIGHT",          BDF_INTEGER,  1},
-    {"RAW_DESCENT",             BDF_INTEGER,  1},
-    {"RAW_END_SPACE",           BDF_INTEGER,  1},
-    {"RAW_FIGURE_WIDTH",        BDF_INTEGER,  1},
-    {"RAW_MAX_SPACE",           BDF_INTEGER,  1},
-    {"RAW_MIN_SPACE",           BDF_INTEGER,  1},
-    {"RAW_NORM_SPACE",          BDF_INTEGER,  1},
-    {"RAW_PIXEL_SIZE",          BDF_INTEGER,  1},
-    {"RAW_POINT_SIZE",          BDF_INTEGER,  1},
-    {"RAW_PIXELSIZE",           BDF_INTEGER,  1},
-    {"RAW_POINTSIZE",           BDF_INTEGER,  1},
-    {"RAW_QUAD_WIDTH",          BDF_INTEGER,  1},
-    {"RAW_SMALL_CAP_SIZE",      BDF_INTEGER,  1},
-    {"RAW_STRIKEOUT_ASCENT",    BDF_INTEGER,  1},
-    {"RAW_STRIKEOUT_DESCENT",   BDF_INTEGER,  1},
-    {"RAW_SUBSCRIPT_SIZE",      BDF_INTEGER,  1},
-    {"RAW_SUBSCRIPT_X",         BDF_INTEGER,  1},
-    {"RAW_SUBSCRIPT_Y",         BDF_INTEGER,  1},
-    {"RAW_SUPERSCRIPT_SIZE",    BDF_INTEGER,  1},
-    {"RAW_SUPERSCRIPT_X",       BDF_INTEGER,  1},
-    {"RAW_SUPERSCRIPT_Y",       BDF_INTEGER,  1},
-    {"RAW_UNDERLINE_POSITION",  BDF_INTEGER,  1},
-    {"RAW_UNDERLINE_THICKNESS", BDF_INTEGER,  1},
-    {"RAW_X_HEIGHT",            BDF_INTEGER,  1},
-    {"RELATIVE_SETWIDTH",       BDF_CARDINAL, 1},
-    {"RELATIVE_WEIGHT",         BDF_CARDINAL, 1},
-    {"RESOLUTION",              BDF_INTEGER,  1},
-    {"RESOLUTION_X",            BDF_CARDINAL, 1},
-    {"RESOLUTION_Y",            BDF_CARDINAL, 1},
-    {"SETWIDTH_NAME",           BDF_ATOM,     1},
-    {"SLANT",                   BDF_ATOM,     1},
-    {"SMALL_CAP_SIZE",          BDF_INTEGER,  1},
-    {"SPACING",                 BDF_ATOM,     1},
-    {"STRIKEOUT_ASCENT",        BDF_INTEGER,  1},
-    {"STRIKEOUT_DESCENT",       BDF_INTEGER,  1},
-    {"SUBSCRIPT_SIZE",          BDF_INTEGER,  1},
-    {"SUBSCRIPT_X",             BDF_INTEGER,  1},
-    {"SUBSCRIPT_Y",             BDF_INTEGER,  1},
-    {"SUPERSCRIPT_SIZE",        BDF_INTEGER,  1},
-    {"SUPERSCRIPT_X",           BDF_INTEGER,  1},
-    {"SUPERSCRIPT_Y",           BDF_INTEGER,  1},
-    {"UNDERLINE_POSITION",      BDF_INTEGER,  1},
-    {"UNDERLINE_THICKNESS",     BDF_INTEGER,  1},
-    {"WEIGHT",                  BDF_CARDINAL, 1},
-    {"WEIGHT_NAME",             BDF_ATOM,     1},
-    {"X_HEIGHT",                BDF_INTEGER,  1},
-    {"_MULE_BASELINE_OFFSET",   BDF_INTEGER,  1},
-    {"_MULE_RELATIVE_COMPOSE",  BDF_INTEGER,  1},
-};
+  /*************************************************************************/
+  /*                                                                       */
+  /* Builtin BDF font properties.                                          */
+  /*                                                                       */
+  /*************************************************************************/
 
-static const FT_ULong _num_bdf_properties = FT_NUM_ELEMENT(_bdf_properties);
+  /* List of most properties that might appear in a font.  Doesn't include */
+  /* the RAW_* and AXIS_* properties in X11R6 polymorphic fonts.           */
 
-/*
- * User defined properties.
- */
-/*static bdf_property_t *user_props;
-  static unsigned long nuser_props = 0;*/
-
-/**************************************************************************
- *
- * Hash table utilities for the properties.
- *
- **************************************************************************/
-
-#define INITIAL_HT_SIZE 241
-
-typedef void (*hash_free_func)(hashnode node);
-
-static hashnode*
-hash_bucket(char *key, hashtable *ht)
-{
-  char*         kp  = key;
-  unsigned long res = 0;
-  hashnode*     bp  = ht->table, *ndp;
-
-  /*
-   * Mocklisp hash function.
-   */
-  while (*kp)
-    res = (res << 5) - res + *kp++;
-
-  ndp = bp + (res % ht->size);
-  while (*ndp)
+  static bdf_property_t  _bdf_properties[] =
   {
-    kp = (*ndp)->key;
+    { (char *)"ADD_STYLE_NAME",          BDF_ATOM,     1, { 0 } },
+    { (char *)"AVERAGE_WIDTH",           BDF_INTEGER,  1, { 0 } },
+    { (char *)"AVG_CAPITAL_WIDTH",       BDF_INTEGER,  1, { 0 } },
+    { (char *)"AVG_LOWERCASE_WIDTH",     BDF_INTEGER,  1, { 0 } },
+    { (char *)"CAP_HEIGHT",              BDF_INTEGER,  1, { 0 } },
+    { (char *)"CHARSET_COLLECTIONS",     BDF_ATOM,     1, { 0 } },
+    { (char *)"CHARSET_ENCODING",        BDF_ATOM,     1, { 0 } },
+    { (char *)"CHARSET_REGISTRY",        BDF_ATOM,     1, { 0 } },
+    { (char *)"COMMENT",                 BDF_ATOM,     1, { 0 } },
+    { (char *)"COPYRIGHT",               BDF_ATOM,     1, { 0 } },
+    { (char *)"DEFAULT_CHAR",            BDF_CARDINAL, 1, { 0 } },
+    { (char *)"DESTINATION",             BDF_CARDINAL, 1, { 0 } },
+    { (char *)"DEVICE_FONT_NAME",        BDF_ATOM,     1, { 0 } },
+    { (char *)"END_SPACE",               BDF_INTEGER,  1, { 0 } },
+    { (char *)"FACE_NAME",               BDF_ATOM,     1, { 0 } },
+    { (char *)"FAMILY_NAME",             BDF_ATOM,     1, { 0 } },
+    { (char *)"FIGURE_WIDTH",            BDF_INTEGER,  1, { 0 } },
+    { (char *)"FONT",                    BDF_ATOM,     1, { 0 } },
+    { (char *)"FONTNAME_REGISTRY",       BDF_ATOM,     1, { 0 } },
+    { (char *)"FONT_ASCENT",             BDF_INTEGER,  1, { 0 } },
+    { (char *)"FONT_DESCENT",            BDF_INTEGER,  1, { 0 } },
+    { (char *)"FOUNDRY",                 BDF_ATOM,     1, { 0 } },
+    { (char *)"FULL_NAME",               BDF_ATOM,     1, { 0 } },
+    { (char *)"ITALIC_ANGLE",            BDF_INTEGER,  1, { 0 } },
+    { (char *)"MAX_SPACE",               BDF_INTEGER,  1, { 0 } },
+    { (char *)"MIN_SPACE",               BDF_INTEGER,  1, { 0 } },
+    { (char *)"NORM_SPACE",              BDF_INTEGER,  1, { 0 } },
+    { (char *)"NOTICE",                  BDF_ATOM,     1, { 0 } },
+    { (char *)"PIXEL_SIZE",              BDF_INTEGER,  1, { 0 } },
+    { (char *)"POINT_SIZE",              BDF_INTEGER,  1, { 0 } },
+    { (char *)"QUAD_WIDTH",              BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_ASCENT",              BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_AVERAGE_WIDTH",       BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_AVG_CAPITAL_WIDTH",   BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_CAP_HEIGHT",          BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_DESCENT",             BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_END_SPACE",           BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_FIGURE_WIDTH",        BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_MAX_SPACE",           BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_MIN_SPACE",           BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_NORM_SPACE",          BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_PIXEL_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_POINT_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_PIXELSIZE",           BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_POINTSIZE",           BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_QUAD_WIDTH",          BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_SMALL_CAP_SIZE",      BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_STRIKEOUT_ASCENT",    BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_STRIKEOUT_DESCENT",   BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_SUBSCRIPT_SIZE",      BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_SUBSCRIPT_X",         BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_SUBSCRIPT_Y",         BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_SUPERSCRIPT_SIZE",    BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_SUPERSCRIPT_X",       BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_SUPERSCRIPT_Y",       BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_UNDERLINE_POSITION",  BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER,  1, { 0 } },
+    { (char *)"RAW_X_HEIGHT",            BDF_INTEGER,  1, { 0 } },
+    { (char *)"RELATIVE_SETWIDTH",       BDF_CARDINAL, 1, { 0 } },
+    { (char *)"RELATIVE_WEIGHT",         BDF_CARDINAL, 1, { 0 } },
+    { (char *)"RESOLUTION",              BDF_INTEGER,  1, { 0 } },
+    { (char *)"RESOLUTION_X",            BDF_CARDINAL, 1, { 0 } },
+    { (char *)"RESOLUTION_Y",            BDF_CARDINAL, 1, { 0 } },
+    { (char *)"SETWIDTH_NAME",           BDF_ATOM,     1, { 0 } },
+    { (char *)"SLANT",                   BDF_ATOM,     1, { 0 } },
+    { (char *)"SMALL_CAP_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { (char *)"SPACING",                 BDF_ATOM,     1, { 0 } },
+    { (char *)"STRIKEOUT_ASCENT",        BDF_INTEGER,  1, { 0 } },
+    { (char *)"STRIKEOUT_DESCENT",       BDF_INTEGER,  1, { 0 } },
+    { (char *)"SUBSCRIPT_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { (char *)"SUBSCRIPT_X",             BDF_INTEGER,  1, { 0 } },
+    { (char *)"SUBSCRIPT_Y",             BDF_INTEGER,  1, { 0 } },
+    { (char *)"SUPERSCRIPT_SIZE",        BDF_INTEGER,  1, { 0 } },
+    { (char *)"SUPERSCRIPT_X",           BDF_INTEGER,  1, { 0 } },
+    { (char *)"SUPERSCRIPT_Y",           BDF_INTEGER,  1, { 0 } },
+    { (char *)"UNDERLINE_POSITION",      BDF_INTEGER,  1, { 0 } },
+    { (char *)"UNDERLINE_THICKNESS",     BDF_INTEGER,  1, { 0 } },
+    { (char *)"WEIGHT",                  BDF_CARDINAL, 1, { 0 } },
+    { (char *)"WEIGHT_NAME",             BDF_ATOM,     1, { 0 } },
+    { (char *)"X_HEIGHT",                BDF_INTEGER,  1, { 0 } },
+    { (char *)"_MULE_BASELINE_OFFSET",   BDF_INTEGER,  1, { 0 } },
+    { (char *)"_MULE_RELATIVE_COMPOSE",  BDF_INTEGER,  1, { 0 } },
+  };
 
-    if (kp[0] == key[0] && ft_strcmp(kp, key) == 0)
-      break;
-
-    ndp--;
-    if (ndp < bp)
-      ndp = bp + (ht->size - 1);
-  }
-  return ndp;
-}
+  static unsigned long
+  _num_bdf_properties = sizeof ( _bdf_properties ) /
+                        sizeof ( _bdf_properties[0] );
 
 
-static  FT_Error
-hash_rehash ( hashtable*  ht,
-              FT_Memory   memory )
-{
-  hashnode *obp = ht->table, *bp, *nbp;
-  int i, sz = ht->size;
-  FT_Error error;
+  /*************************************************************************/
+  /*                                                                       */
+  /* Hash table utilities for the properties.                              */
+  /*                                                                       */
+  /*************************************************************************/
 
-  ht->size <<= 1;
-  ht->limit  = ht->size / 3;
+  /* XXX: Replace this with FreeType's hash functions */
 
-  if ( FT_NEW_ARRAY( ht->table , ht->size ) )
-    return error;
 
-  for (i = 0, bp = obp; i < sz; i++, bp++)
+#define INITIAL_HT_SIZE  241
+
+  typedef void
+  (*hash_free_func)( hashnode  node );
+
+  static hashnode*
+  hash_bucket( char*       key,
+               hashtable*  ht )
   {
-    if (*bp)
+    char*          kp  = key;
+    unsigned long  res = 0;
+    hashnode*      bp  = ht->table, *ndp;
+
+
+    /* Mocklisp hash function. */
+    while ( *kp )
+      res = ( res << 5 ) - res + *kp++;
+
+    ndp = bp + ( res % ht->size );
+    while ( *ndp )
     {
-      nbp = hash_bucket((*bp)->key, ht);
-      *nbp = *bp;
+      kp = (*ndp)->key;
+      if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 )
+        break;
+      ndp--;
+      if ( ndp < bp )
+        ndp = bp + ( ht->size - 1 );
     }
+
+    return ndp;
   }
-  FT_FREE(obp);
-
-  return FT_Err_Ok;
-}
 
 
-static FT_Error
-hash_init ( hashtable*  ht,
-            FT_Memory   memory )
-{
-  int      sz = INITIAL_HT_SIZE;
-  FT_Error error;
-
-  ht->size  = sz;
-  ht->limit = sz / 3;
-  ht->used  = 0;
-
-  if ( FT_NEW_ARRAY( ht->table, size ) )
-    return error;
-
-  return FT_Err_Ok;
-}
-
-
-static void
-hash_free( hashtable*  ht,
-           FT_Memory   memory )
-{
-  /* FT_Error error; */
-
-  if ( ht != 0 )
+  static FT_Error
+  hash_rehash( hashtable*  ht,
+               FT_Memory   memory )
   {
+    hashnode*  obp = ht->table, *bp, *nbp;
     int        i, sz = ht->size;
-    hashnode*  bp    = ht->table;
+    FT_Error   error = BDF_Err_Ok;
 
-    for (i = 0; i < sz; i++, bp++)
+
+    ht->size <<= 1;
+    ht->limit  = ht->size / 3;
+
+    if ( FT_NEW_ARRAY( ht->table, ht->size ) )
+      goto Exit;
+    FT_MEM_SET( ht->table, 0, sizeof ( hashnode ) * ht->size );
+
+    for ( i = 0, bp = obp; i < sz; i++, bp++ )
     {
-      if (*bp)
-        FT_FREE(*bp);
+      if ( *bp )
+      {
+        nbp = hash_bucket( (*bp)->key, ht );
+        *nbp = *bp;
+      }
     }
-    if (sz > 0)
-      FT_FREE(ht->table);
+    FT_FREE( obp );
+
+  Exit:
+    return error;
   }
-}
 
 
-static FT_Error
-hash_insert ( char*       key,
-              void*       data,
-              hashtable*  ht,
-              FT_Memory   memory )
-{
-  FT_Error  error   = FT_Err_Ok;
-  hashnode  nn, *bp = hash_bucket(key, ht);
-
-  nn = *bp;
-  if (!nn)
+  static FT_Error
+  hash_init( hashtable*  ht,
+             FT_Memory   memory )
   {
-    if ( FT_NEW( nn ) )
-      return error;
+    int       sz = INITIAL_HT_SIZE;
+    FT_Error  error = BDF_Err_Ok;
 
-    *bp      = nn;
-    nn->key  = key;
-    nn->data = data;
 
-    if (ht->used >= ht->limit)
-      error = hash_rehash(ht, memory);
+    ht->size  = sz;
+    ht->limit = sz / 3;
+    ht->used  = 0;
 
-    ht->used++;
+    if ( FT_NEW_ARRAY( ht->table, sz ) )
+      goto Exit;
+    FT_MEM_SET( ht->table, 0, sizeof ( hashnode ) * sz );
+
+  Exit:
+    return error;
   }
-  else
-    nn->data = data;
-
-  return error;
-}
 
 
-static hashnode
-hash_lookup(char *key, hashtable *ht)
-{
-  hashnode *np = hash_bucket(key, ht);
-  return   *np;
-}
-
-#ifdef 0
-static void
-hash_delete(char *name, hashtable *ht , FT_Memory memory)
-{
-  hashnode *hp;
-  /* FT_Error error; */
-
-  hp = hash_bucket(name, ht);
-  FT_FREE( *hp );
-}
-#endif
-
-/*
- * The builtin property table.
- */
-/*static hashtable proptbl; */ /* XXX eliminate this */
-
-
-
-/**************************************************************************
- *
- * Utility types and functions.
- *
- **************************************************************************/
-
-/*
- * Function type for parsing lines of a BDF font.
- */
-typedef int (*_bdf_line_func_t)( char*         line,
-                                 unsigned long linelen,
-                                 unsigned long lineno,
-                                 void*         call_data,
-                                 void*         client_data );
-
-/*
- * List structure for splitting lines into fields.
- */
-typedef struct
-{
-  char**         field;
-  unsigned long  size;
-  unsigned long  used;
-  char*          bfield;
-  unsigned long  bsize;
-  unsigned long  bused;
-
-} _bdf_list_t;
-
-
-/*
- * Structure used while loading BDF fonts.
- */
-typedef struct
-{
-  unsigned long          flags;
-  unsigned long          cnt;
-  unsigned long          row;
-  unsigned long          bpr;
-  short                  minlb;
-  short                  maxlb;
-  short                  maxrb;
-  short                  maxas;
-  short                  maxds;
-  short                  rbearing;
-  char*                  glyph_name;
-  long                   glyph_enc;
-  bdf_font_t*            font;
-  bdf_options_t*         opts;
-  void*                  client_data;
-  bdf_callback_t         callback;
-  bdf_callback_struct_t  cb;
-  unsigned long          have[2048];
-  _bdf_list_t            list;
-
-  FT_Memory              memory;
-
-} _bdf_parse_t;
-
-#define setsbit(m, cc) (m[(cc) >> 3] |= (1 << ((cc) & 7)))
-#define sbitset(m, cc) (m[(cc) >> 3] & (1 << ((cc) & 7)))
-
-/*
- * An empty string for empty fields.
- */
-static const char empty[1] = { 0 };   /* XXX eliminate this */
-
-/*
- * Assume the line is NULL terminated and that the `list' parameter was
- * initialized the first time it was used.
- */
-static FT_Error
-_bdf_split ( char*          separators,
-             char*          line,
-             unsigned long  linelen,
-             _bdf_list_t*   list,
-             FT_Memory      memory )
-{
-  int mult, final_empty;
-  char *sp, *ep, *end;
-  unsigned char seps[32];
-  FT_Error error;
-
-  /*
-   * Initialize the list.
-   */
-  list->used = list->bused = 0;
-
-  /*
-   * If the line is empty, then simply return.
-   */
-  if ( linelen == 0 || line[0] == 0 )
-    return FT_Err_Ok;
-
-  /*
-   * If the `separators' parameter is NULL or empty, split the list into
-   * individual bytes.
-   */
-  if ( separators == 0 || *separators == 0 )
+  static void
+  hash_free( hashtable*  ht,
+             FT_Memory   memory )
   {
-    if ( linelen > list->bsize )
+    if ( ht != 0 )
     {
-      if ( list->bsize )
-      {
-        if ( FT_ALLOC ( list->bfield , linelen) )
-          return error;
-      }
-      else
-      {
-        if ( FT_REALLOC ( list->bfield , list->bsize, linelen) )
-          return error;
-      }
-      list->bsize = linelen;
-    }
-    list->bused = linelen;
+      int        i, sz = ht->size;
+      hashnode*  bp = ht->table;
 
-    FT_MEM_COPY (list->bfield, line, linelen);
-    return FT_Err_Ok;
+
+      for ( i = 0; i < sz; i++, bp++ )
+        FT_FREE( *bp );
+
+      FT_FREE( ht->table );
+    }
   }
 
-  /*
-   * Prepare the separator bitmap.
-   */
-  FT_MEM_ZERO( seps, 32 );
 
-  /*
-   * If the very last character of the separator string is a plus, then set
-   * the `mult' flag to indicate that multiple separators should be
-   * collapsed into one.
-   */
-  for ( mult = 0, sp = separators; sp && *sp; sp++ )
+  static FT_Error
+  hash_insert( char*       key,
+               void*       data,
+               hashtable*  ht,
+               FT_Memory   memory )
   {
-    if ( sp[0] == '+' && sp[1] == 0)
-      mult = 1;
+    hashnode  nn, *bp = hash_bucket( key, ht );
+    FT_Error  error = BDF_Err_Ok;
+
+
+    nn = *bp;
+    if ( !nn )
+    {
+      if ( FT_NEW( nn ) )
+        goto Exit;
+      *bp = nn;
+
+      nn->key  = key;
+      nn->data = data;
+
+      if ( ht->used >= ht->limit )
+      {
+        error = hash_rehash( ht, memory );
+        if ( error )
+          goto Exit;
+      }
+      ht->used++;
+    }
     else
-      setsbit( seps, sp[0] );
+      nn->data = data;
+
+  Exit:
+    return error;
   }
 
-  /*
-   * Break the line up into fields.
-   */
-  final_empty = 0;
-  sp          = ep = line;
-  end         = sp + linelen;
-  for ( ; sp < end && *sp;)
-  {
-    /*
-     * Collect everything that is not a separator.
-     */
-    for ( ; *ep && !sbitset( seps, *ep ); ep++ ) ;
 
-    /*
-     * Resize the list if necessary.
-     */
-    if ( list->used == list->size )
+  static hashnode
+  hash_lookup( char*       key,
+               hashtable*  ht )
+  {
+    hashnode *np = hash_bucket( key, ht );
+
+
+    return *np;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Utility types and functions.                                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /* Function type for parsing lines of a BDF font. */
+
+  typedef FT_Error
+  (*_bdf_line_func_t)( char*          line,
+                       unsigned long  linelen,
+                       unsigned long  lineno,
+                       void*          call_data,
+                       void*          client_data );
+
+
+  /* List structure for splitting lines into fields. */
+
+  typedef struct  _bdf_list_t_
+  {
+    char**         field;
+    unsigned long  size;
+    unsigned long  used;
+
+  } _bdf_list_t;
+
+
+  /* Structure used while loading BDF fonts. */
+
+  typedef struct  _bdf_parse_t_
+  {
+    unsigned long   flags;
+    unsigned long   cnt;
+    unsigned long   row;
+
+    short           minlb;
+    short           maxlb;
+    short           maxrb;
+    short           maxas;
+    short           maxds;
+
+    short           rbearing;
+
+    char*           glyph_name;
+    long            glyph_enc;
+
+    bdf_font_t*     font;
+    bdf_options_t*  opts;
+
+    unsigned long   have[2048];
+    _bdf_list_t     list;
+
+    FT_Memory       memory;
+
+  } _bdf_parse_t;
+
+
+#define setsbit( m, cc )  ( m[(cc) >> 3] |= ( 1 << ( (cc) & 7 ) ) )
+#define sbitset( m, cc )  ( m[(cc) >> 3]  & ( 1 << ( (cc) & 7 ) ) )
+
+
+  /* An empty string for empty fields. */
+
+  static char  empty[1] = { 0 };   /* XXX eliminate this */
+
+
+  /* Assume the line is NULL-terminated and that the `list' parameter */
+  /* was initialized the first time it was used.                      */
+
+  static FT_Error
+  _bdf_split( char*          separators,
+              char*          line,
+              unsigned long  linelen,
+              _bdf_list_t*   list,
+              FT_Memory      memory )
+  {
+    int       mult, final_empty;
+    char      *sp, *ep, *end;
+    char      seps[32];
+    FT_Error  error = BDF_Err_Ok;
+
+
+    /* Initialize the list. */
+    list->used = 0;
+
+    /* If the line is empty, then simply return. */
+    if ( linelen == 0 || line[0] == 0 )
+      goto Exit;
+
+    /* In the original code, if the `separators' parameter is NULL or */
+    /* empty, the list is split into individual bytes.  We don't need */
+    /* this, so an error is signaled.                                 */
+    if ( separators == 0 || *separators == 0 )
     {
-      if ( list->size == 0 )
-      {
-        if ( FT_NEW_ARRAY( list->field , 5) )
-          return error;
-      }
+      error = BDF_Err_Invalid_Argument;
+      goto Exit;
+    }
+
+    /* Prepare the separator bitmap. */
+    FT_MEM_SET( seps, 0, 32 );
+
+    /* If the very last character of the separator string is a plus, then */
+    /* set the `mult' flag to indicate that multiple separators should be */
+    /* collapsed into one.                                                */
+    for ( mult = 0, sp = separators; sp && *sp; sp++ )
+    {
+      if ( *sp == '+' && *( sp + 1 ) == 0 )
+        mult = 1;
       else
+        setsbit( seps, *sp );
+    }
+
+    /* Break the line up into fields. */
+    for ( final_empty = 0, sp = ep = line, end = sp + linelen;
+          sp < end && *sp; )
+    {
+      /* Collect everything that is not a separator. */
+      for ( ; *ep && !sbitset( seps, *ep ); ep++ )
+        ;
+
+      /* Resize the list if necessary. */
+      if ( list->used == list->size )
       {
-        if ( FT_RENEW_ARRAY( list->field , list->size, list->size+5 )
-          return error;
+        if ( list->size == 0 )
+        {
+          if ( FT_NEW_ARRAY( list->field, 5 ) )
+            goto Exit;
+        }
+        else
+        {
+          if ( FT_RENEW_ARRAY ( list->field ,
+                                list->size,
+                                list->size + 5 ) )
+            goto Exit;
+        }
+
+        list->size += 5;
       }
-      list->size += 5;
+
+      /* Assign the field appropriately. */
+      list->field[list->used++] = ( ep > sp ) ? sp : empty;
+
+      sp = ep;
+
+      if ( mult )
+      {
+        /* If multiple separators should be collapsed, do it now by */
+        /* setting all the separator characters to 0.               */
+        for ( ; *ep && sbitset( seps, *ep ); ep++ )
+          *ep = 0;
+      }
+      else if ( *ep != 0 )
+        /* Don't collapse multiple separators by making them 0, so just */
+        /* make the one encountered 0.                                  */
+        *ep++ = 0;
+
+      final_empty = ( ep > sp && *ep == 0 );
+      sp = ep;
     }
 
-    /*
-     * Assign the field appropriately.
-     */
-    list->field[ list->used++ ] = (ep > sp) ? sp : empty;
-
-    sp = ep;
-    if (mult)
+    /* Finally, NULL-terminate the list. */
+    if ( list->used + final_empty + 1 >= list->size )
     {
-      /*
-       * If multiple separators should be collapsed, do it now by
-       * setting all the separator characters to 0.
-       */
-      for ( ; *ep && sbitset(seps, *ep); ep++ )
-        *ep = 0;
+      if ( list->used == list->size )
+      {
+        if ( list->size == 0 )
+        {
+          if ( FT_NEW_ARRAY( list->field, 5 ) )
+            goto Exit;
+        }
+        else
+        {
+          if ( FT_RENEW_ARRAY( list->field,
+                               list->size,
+                               list->size + 5 ) )
+            goto Exit;
+        }
 
-    }
-    else if (*ep != 0)
-    {
-      /*
-       * Don't collapse multiple separators by making them 0, so just
-       * make the one encountered 0.
-       */
-      *ep++ = 0;
+        list->size += 5;
+      }
     }
 
-    final_empty = ( ep > sp && *ep == 0 );
-    sp          = ep;
-  }
+    if ( final_empty )
+      list->field[list->used++] = empty;
 
-  /*
-   * Finally, NULL terminate the list.
-   */
-  if ( list->used + final_empty + 1 >= list->size )
-  {
     if ( list->used == list->size )
     {
       if ( list->size == 0 )
       {
         if ( FT_NEW_ARRAY( list->field, 5 ) )
-          return error;
+          goto Exit;
       }
       else
       {
-        if ( FT_RENEW_ARRAY( list->field , list->size, list->size+5 ) )
-          return error;
+        if ( FT_RENEW_ARRAY( list->field,
+                             list->size,
+                             list->size + 5 ) )
+          goto Exit;
       }
+
       list->size += 5;
     }
+
+    list->field[list->used] = 0;
+
+  Exit:
+    return error;
   }
 
-  if (final_empty)
-    list->field[ list->used++ ] = empty;
 
-  if ( list->used == list->size )
+  static void
+  _bdf_shift( unsigned long  n,
+              _bdf_list_t*   list )
   {
-    if ( list->size == 0 )
+    unsigned long  i, u;
+
+
+    if ( list == 0 || list->used == 0 || n == 0 )
+      return;
+
+    if ( n >= list->used )
     {
-      if ( FT_NEW_ARRAY( list->field , 5 ) )
-        return error;
+      list->used = 0;
+      return;
     }
+
+    for ( u = n, i = 0; u < list->used; i++, u++ )
+      list->field[i] = list->field[u];
+    list->used -= n;
+  }
+
+
+  static char *
+  _bdf_join( int             c,
+             unsigned long*  len,
+             _bdf_list_t*    list )
+  {
+    unsigned long  i, j;
+    char           *fp, *dp;
+
+
+    if ( list == 0 || list->used == 0 )
+      return 0;
+
+    *len = 0;
+
+    dp = list->field[0];
+    for ( i = j = 0; i < list->used; i++ )
+    {
+      fp = list->field[i];
+      while ( *fp )
+        dp[j++] = *fp++;
+
+      if ( i + 1 < list->used )
+        dp[j++] = c;
+    }
+    dp[j] = 0;
+
+    *len = j;
+    return dp;
+  }
+
+
+  /* High speed file reader that passes each line to a callback. */
+  static FT_Error
+  bdf_internal_readstream( FT_Stream  stream,
+                           char*      buffer,
+                           int        count,
+                           int       *read_bytes )
+  {
+    int            rbytes;
+    unsigned long  pos   = stream->pos;
+    FT_Error       error = BDF_Err_Ok;
+
+
+    if ( pos > stream->size )
+    {
+      FT_ERROR(( "bdf_internal_readstream:" ));
+      FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+                 pos, stream->size ));
+      error = BDF_Err_Invalid_Stream_Operation;
+      goto Exit;
+    }
+
+    if ( stream->read )
+      rbytes = stream->read( stream, pos,
+                             (unsigned char *)buffer, count );
     else
     {
-      if ( FT_NEW_ARRAY( list->field, list->size, list->size + 5 ) )
-        return error;
+      rbytes = stream->size - pos;
+      if ( rbytes > count )
+        rbytes = count;
+
+      FT_MEM_COPY( buffer, stream->base + pos, rbytes );
     }
-    list->size += 5;
-  }
-  list->field[ list->used ] = 0;
 
-  return FT_Err_Ok;
-}
+    stream->pos = pos + rbytes;
 
+    *read_bytes = rbytes;
 
-static void
-_bdf_shift( unsigned long  n,
-            _bdf_list_t*   list)
-{
-  unsigned long i, u;
-
-  if ( list == 0 || list->used == 0 || n == 0 )
-    return;
-
-  if ( n >= list->used )
-  {
-    list->used = 0;
-    return;
-  }
-  for ( u = n, i = 0; u < list->used; i++, u++ )
-    list->field[i] = list->field[u];
-
-  list->used -= n;
-}
-
-
-static char*
-_bdf_join( int             c,
-           unsigned long*  len,
-           _bdf_list_t*    list)
-{
-  unsigned long i, j;
-  char *fp, *dp;
-
-  if ( list == 0 || list->used == 0 )
-    return 0;
-
-  *len = 0;
-
-  dp = list->field[0];
-
-  for ( i = j = 0; i < list->used; i++ )
-  {
-    fp = list->field[i];
-    while (*fp)
-      dp[j++] = *fp++;
-      
-    if (i + 1 < list->used)
-      dp[j++] = c;
-  }
-  dp[j] = 0;
-
-  *len = j;
-  return dp;
-}
-
-/*
- * High speed file reader that passes each line to a callback.
- */
-int ftreadstream( FT_Stream  stream,
-                  char*      buffer,
-                  int        count )
-{
-  int read_bytes;
-  int pos = stream->pos;
-
-  if ( pos >= stream->size )
-  {
-    FT_ERROR(( "FT_Read_Stream_At:" ));
-    FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
-               pos, stream->size ));
-    return 0;
+  Exit:
+    return error;
   }
 
-  if ( stream->read )
-    read_bytes = stream->read( stream, pos, buffer, count );
-  else
+
+  static FT_Error
+  _bdf_readstream( FT_Stream         stream,
+                   _bdf_line_func_t  callback,
+                   void*             client_data,
+                   unsigned long    *lno )
   {
-    read_bytes = stream->size - pos;
-    if ( read_bytes > count )
-      read_bytes = count;
+    _bdf_line_func_t  cb;
+    unsigned long     lineno;
+    int               n, res, done, refill, bytes, hold;
+    char              *ls, *le, *pp, *pe, *hp;
+    /* XXX: Use a dynamic buffer */
+    char              buf[65536L];
+    FT_Error          error = BDF_Err_Ok;
 
-    ft_memcpy( buffer, stream->base + pos, read_bytes );
-  }
 
-  stream->pos = pos + read_bytes;
-
-  return read_bytes;
-}
-
-static int
-_bdf_readstream( FT_Stream         stream,
-                 _bdf_line_func_t  callback,
-                 void*             client_data,
-                 unsigned long*    lno)
-{
-  _bdf_line_func_t cb;
-  unsigned long lineno;
-  int n, res, done, refill, bytes, hold;
-  char *ls, *le, *pp, *pe, *hp;
-  char buf[65536];
-
-  if (callback == 0)
-    return -1;
-
-  cb     = callback;
-  lineno = 1;
-  buf[0] = 0;
-  res    = done = 0;
-  pp     = ls = le = buf;
-  bytes  = 65536;
-
-  while ( !done && (n = ftreadstream(stream, pp, bytes)) > 0 )
-  {
-    /*
-     * Determine the new end of the buffer pages.
-     */
-    pe = pp + n;
-
-    for (refill = 0; done == 0 && refill == 0; )
+    if ( callback == 0 )
     {
-      while (le < pe && *le != '\n' && *le != '\r')
-        le++;
+      error = BDF_Err_Invalid_Argument;
+      goto Exit;
+    }
 
-      if (le == pe)
-      {
-        /*
-         * Hit the end of the last page in the buffer.  Need to find
-         * out how many pages to shift and how many pages need to be
-         * read in.  Adjust the line start and end pointers down to
-         * point to the right places in the pages.
-         */
-        pp = buf + (((ls - buf) >> 13) << 13);
-        n = pp - buf;
-        ls -= n;
-        le -= n;
-        n   = pe - pp;
-        (void) ft_memcpy(buf, pp, n);
-        pp = buf + n;
-        bytes = 65536 - n;
-        refill = 1;
-      }
-      else
-      {
-        /*
-         * Temporarily NULL terminate the line.
-         */
-        hp   = le;
-        hold = *le;
-        *le  = 0;
+    cb     = callback;
+    lineno = 1;
+    buf[0] = 0;
 
-        if (callback && *ls != '#' && *ls != 0x1a && le > ls &&
-            (res = (*cb)(ls, le - ls, lineno, (void *) &cb,
-                         client_data)) != 0)
-          done = 1;
-        else {
+    res = done = 0;
+    pp = ls = le = buf;
+
+    bytes = 65536L;
+
+    while ( !done )
+    {
+      error = bdf_internal_readstream( stream, pp, bytes, &n );
+      if ( error )
+        goto Exit;
+
+      if ( n == 0 )
+        break;
+
+      /* Determine the new end of the buffer pages. */
+      pe = pp + n;
+
+      for ( refill = 0; done == 0 && refill == 0; )
+      {
+        while ( le < pe && *le != '\n' && *le != '\r' )
+          le++;
+
+        if ( le == pe )
+        {
+          /* Hit the end of the last page in the buffer.  Need to find */
+          /* out how many pages to shift and how many pages need to be */
+          /* read in.  Adjust the line start and end pointers down to  */
+          /* point to the right places in the pages.                   */
+
+          pp  = buf + ( ( ( ls - buf ) >> 13 ) << 13 );
+          n   = pp - buf;
+          ls -= n;
+          le -= n;
+          n   = pe - pp;
+
+          FT_MEM_COPY( buf, pp, n );
+
+          pp     = buf + n;
+          bytes  = 65536L - n;
+          refill = 1;
+        }
+        else
+        {
+          /* Temporarily NULL-terminate the line. */
+          hp   = le;
+          hold = *le;
+          *le  = 0;
+
+          /* XXX: Use encoding independent value for 0x1a */
+          if ( *ls != '#' && *ls != 0x1a                          &&
+               le > ls                                            &&
+               ( error = (*cb)( ls, le - ls, lineno, (void *)&cb,
+                                client_data ) ) != BDF_Err_Ok     )
+            done = 1;
+          else
+          {
             ls = ++le;
-            /*
-             * Handle the case of DOS crlf sequences.
-             */
-            if (le < pe && hold == '\n' && *le =='\r')
+            /* Handle the case of DOS crlf sequences. */
+            if ( le < pe && hold == '\n' && *le =='\r' )
               ls = ++le;
+          }
+
+          /* Increment the line number. */
+          lineno++;
+
+          /* Restore the character at the end of the line. */
+          *hp = hold;
         }
-
-        /*
-         * Increment the line number.
-         */
-        lineno++;
-
-        /*
-         * Restore the character at the end of the line.
-         */
-        *hp = hold;
       }
     }
+
+    *lno             = lineno;
+
+  Exit:
+    return error;
   }
-  *lno = lineno;
-  return res;
-}
 
 
-FT_LOCAL_DEF( void )
-_bdf_memmove(char *dest, char *src, unsigned long bytes)
-{
-    long i, j;
+  /* XXX: make this work with EBCDIC also */
 
-    i = (long) bytes;
-    j = i & 7;
-    i = (i + 7) >> 3;
-
-    /*
-     * Do a memmove using Ye Olde Duff's Device for efficiency.
-     */
-    if (src < dest) {
-        src += bytes;
-        dest += bytes;
-
-        switch (j) {
-          case 0: do {
-              *--dest = *--src;
-            case 7: *--dest = *--src;
-            case 6: *--dest = *--src;
-            case 5: *--dest = *--src;
-            case 4: *--dest = *--src;
-            case 3: *--dest = *--src;
-            case 2: *--dest = *--src;
-            case 1: *--dest = *--src;
-          } while (--i > 0);
-        }
-    } else if (src > dest) {
-        switch (j) {
-          case 0: do {
-              *dest++ = *src++;
-            case 7: *dest++ = *src++;
-            case 6: *dest++ = *src++;
-            case 5: *dest++ = *src++;
-            case 4: *dest++ = *src++;
-            case 3: *dest++ = *src++;
-            case 2: *dest++ = *src++;
-            case 1: *dest++ = *src++;
-          } while (--i > 0);
-        }
-    }
-}
-
-static const unsigned char a2i[128] = {
+  static unsigned char  a2i[128] =
+  {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -816,592 +750,596 @@
     0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
+  };
 
-static const unsigned char odigits[32] = {
+  static unsigned char  odigits[32] =
+  {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
+  };
 
-static const unsigned char ddigits[32] = {
+  static unsigned char  ddigits[32] =
+  {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
+  };
 
-static const unsigned char hdigits[32] = {
+  static unsigned char  hdigits[32] =
+  {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03,
     0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
+  };
 
-#define isdigok(m, d) (m[(d) >> 3] & (1 << ((d) & 7)))
 
-/*
- * Routine to convert an ASCII string into an unsigned long integer.
- */
-static unsigned long
-_bdf_atoul(char *s, char **end, int base)
-{
-  unsigned long v;
-  unsigned char *dmap;
+#define isdigok( m, d )  (m[(d) >> 3] & ( 1 << ( (d) & 7 ) ) )
 
-  if (s == 0 || *s == 0)
-    return 0;
 
-  /*
-   * Make sure the radix is something recognizable.  Default to 10.
-   */
-  switch (base)
+  /* Routine to convert an ASCII string into an unsigned long integer. */
+  static unsigned long
+  _bdf_atoul( char*   s,
+              char**  end,
+              int     base )
   {
-    case 8: dmap = odigits; break;
-    case 16: dmap = hdigits; break;
-    default: base = 10; dmap = ddigits; break;
-  }
-
-  /*
-   * Check for the special hex prefix.
-   */
-  if ( s[0] == '0' && ( s[1] == 'x' || s[1] == 'X'))
-  {
-    base = 16;
-    dmap = hdigits;
-    s   += 2;
-  }
-
-  for ( v = 0; isdigok(dmap, *s); s++ )
-    v = (v * base) + a2i[(int) *s];
-
-  if (end != 0)
-    *end = s;
-
-  return v;
-}
+    unsigned long   v;
+    unsigned char*  dmap;
 
 
-/*
- * Routine to convert an ASCII string into an signed long integer.
- */
-static long
-_bdf_atol(char *s, char **end, int base)
-{
-  long v, neg;
-  unsigned char *dmap;
-
-  if (s == 0 || *s == 0)
-    return 0;
-
-  /*
-   * Make sure the radix is something recognizable.  Default to 10.
-   */
-  switch (base) {
-    case 8: dmap = odigits; break;
-    case 16: dmap = hdigits; break;
-    default: base = 10; dmap = ddigits; break;
-  }
-
-  /*
-   * Check for a minus sign.
-   */
-  neg = 0;
-  if (*s == '-') {
-      s++;
-      neg = 1;
-  }
-
-  /*
-   * Check for the special hex prefix.
-   */
-  if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) {
-      base = 16;
-      dmap = hdigits;
-      s += 2;
-  }
-
-  for (v = 0; isdigok(dmap, *s); s++)
-    v = (v * base) + a2i[(int) *s];
-
-  if (end != 0)
-    *end = s;
-
-  return (!neg) ? v : -v;
-}
-
-
-/*
- * Routine to convert an ASCII string into an signed short integer.
- */
-static short
-_bdf_atos(char *s, char **end, int base)
-{
-    short v, neg;
-    unsigned char *dmap;
-
-    if (s == 0 || *s == 0)
+    if ( s == 0 || *s == 0 )
       return 0;
 
-    /*
-     * Make sure the radix is something recognizable.  Default to 10.
-     */
-    switch (base) {
-      case 8: dmap = odigits; break;
-      case 16: dmap = hdigits; break;
-      default: base = 10; dmap = ddigits; break;
+    /* Make sure the radix is something recognizable.  Default to 10. */
+    switch ( base )
+    {
+    case 8:
+      dmap = odigits;
+      break;
+    case 16:
+      dmap = hdigits;
+      break;
+    default:
+      base = 10;
+      dmap = ddigits;
+      break;
     }
 
-    /*
-     * Check for a minus.
-     */
-    neg = 0;
-    if (*s == '-') {
-        s++;
-        neg = 1;
+    /* Check for the special hex prefix. */
+    if ( *s == '0'                                  &&
+         ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) )
+    {
+      base = 16;
+      dmap = hdigits;
+      s   += 2;
     }
 
-    /*
-     * Check for the special hex prefix.
-     */
-    if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) {
-        base = 16;
-        dmap = hdigits;
-        s += 2;
-    }
+    for ( v = 0; isdigok( dmap, *s ); s++ )
+      v = v * base + a2i[(int)*s];
 
-    for (v = 0; isdigok(dmap, *s); s++)
-      v = (v * base) + a2i[(int) *s];
-
-    if (end != 0)
+    if ( end != 0 )
       *end = s;
 
-    return (!neg) ? v : -v;
-}
+    return v;
+  }
 
-/*
- * Routine to compare two glyphs by encoding so they can be sorted.
- */
-static int
-by_encoding(const void *a, const void *b)
-{
-    bdf_glyph_t *c1, *c2;
 
-    c1 = (bdf_glyph_t *) a;
-    c2 = (bdf_glyph_t *) b;
-    if (c1->encoding < c2->encoding)
+  /* Routine to convert an ASCII string into an signed long integer. */
+  static long
+  _bdf_atol( char*   s,
+             char**  end,
+             int     base )
+  {
+    long            v, neg;
+    unsigned char*  dmap;
+
+
+    if ( s == 0 || *s == 0 )
+      return 0;
+
+    /* Make sure the radix is something recognizable.  Default to 10. */
+    switch ( base )
+    {
+    case 8:
+      dmap = odigits;
+      break;
+    case 16:
+      dmap = hdigits;
+      break;
+    default:
+      base = 10;
+      dmap = ddigits;
+      break;
+    }
+
+    /* Check for a minus sign. */
+    neg = 0;
+    if ( *s == '-' )
+    {
+      s++;
+      neg = 1;
+    }
+
+    /* Check for the special hex prefix. */
+    if ( *s == '0'                                  &&
+         ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) )
+    {
+      base = 16;
+      dmap = hdigits;
+      s   += 2;
+    }
+
+    for ( v = 0; isdigok( dmap, *s ); s++ )
+      v = v * base + a2i[(int)*s];
+
+    if ( end != 0 )
+      *end = s;
+
+    return ( !neg ) ? v : -v;
+  }
+
+
+  /* Routine to convert an ASCII string into an signed short integer. */
+  static short
+  _bdf_atos( char*   s,
+             char**  end,
+             int     base )
+  {
+    short           v, neg;
+    unsigned char*  dmap;
+
+
+    if ( s == 0 || *s == 0 )
+      return 0;
+
+    /* Make sure the radix is something recognizable.  Default to 10. */
+    switch ( base )
+    {
+    case 8:
+      dmap = odigits;
+      break;
+    case 16:
+      dmap = hdigits;
+      break;
+    default:
+      base = 10;
+      dmap = ddigits;
+      break;
+    }
+
+    /* Check for a minus. */
+    neg = 0;
+    if ( *s == '-' )
+    {
+      s++;
+      neg = 1;
+    }
+
+    /* Check for the special hex prefix. */
+    if ( *s == '0'                                  &&
+         ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) )
+    {
+      base = 16;
+      dmap = hdigits;
+      s   += 2;
+    }
+
+    for ( v = 0; isdigok( dmap, *s ); s++ )
+      v = v * base + a2i[(int)*s];
+
+    if ( end != 0 )
+      *end = s;
+
+    return ( !neg ) ? v : -v;
+  }
+
+
+  /* Routine to compare two glyphs by encoding so they can be sorted. */
+  static int
+  by_encoding( const void*  a,
+               const void*  b )
+  {
+    bdf_glyph_t  *c1, *c2;
+
+
+    c1 = (bdf_glyph_t *)a;
+    c2 = (bdf_glyph_t *)b;
+
+    if ( c1->encoding < c2->encoding )
       return -1;
-    else if (c1->encoding > c2->encoding)
+    else if ( c1->encoding > c2->encoding )
       return 1;
+
     return 0;
-}
-
-
-
-static FT_Error
-bdf_create_property( char*        name,
-                     int          format,
-                     bdf_font_t*  font )
-{
-  unsigned long    n;
-  bdf_property_t*  p;
-  FT_Memory        memory = font->memory;
-  FT_Error         error;
-
-  /*
-   * First check to see if the property has
-   * already been added or not.  If it has, then
-   * simply ignore it.
-   */
-  if ( hash_lookup( name, &(font->proptbl)) )
-    return FT_Err_Ok;
-
-  if (font->nuser_props == 0)
-  {
-    if ( FT_NEW( font->user_props ) )
-      return error;
-  }
-  else
-  {
-    if ( FT_RENEW_ARRAY( font->user_props, font->nuser_props,
-                                          (font->nuser_props + 1) ) )
-      return error;
   }
 
-  p = font->user_props + font->nuser_props;
-  
-  FT_ZERO( p );
-  
-  n = (unsigned long) (ft_strlen(name) + 1);
-  
-  if ( FT_ALLOC ( p->name , n) )
+
+  static FT_Error
+  bdf_create_property( char*        name,
+                       int          format,
+                       bdf_font_t*  font )
+  {
+    unsigned long    n;
+    bdf_property_t*  p;
+    FT_Memory        memory = font->memory;
+    FT_Error         error = BDF_Err_Ok;
+
+
+    /* First check to see if the property has      */
+    /* already been added or not.  If it has, then */
+    /* simply ignore it.                           */
+    if ( hash_lookup( name, &(font->proptbl) ) )
+      goto Exit;
+
+    if ( font->nuser_props == 0 )
+    {
+      if ( FT_NEW_ARRAY( font->user_props, 1 ) )
+        goto Exit;
+    }
+    else
+    {
+      if ( FT_RENEW_ARRAY( font->user_props,
+                           font->nuser_props,
+                           font->nuser_props + 1 ) )
+        goto Exit;
+    }
+
+    p = font->user_props + font->nuser_props;
+    FT_MEM_SET( p, 0, sizeof ( bdf_property_t ) );
+
+    n = (unsigned long)( ft_strlen( name ) + 1 );
+    if ( FT_NEW_ARRAY( p->name, n ) )
+      goto Exit;
+
+    FT_MEM_COPY( (char *)p->name, name, n );
+
+    p->format  = format;
+    p->builtin = 0;
+
+    n = _num_bdf_properties + font->nuser_props;
+
+    error = hash_insert( p->name, (void *)n, &(font->proptbl), memory );
+    if ( error )
+      goto Exit;
+
+    font->nuser_props++;
+
+  Exit:
     return error;
-    
-  FT_MEM_COPY(p->name, name, n);
-  p->format  = format;
-  p->builtin = 0;
-
-  n = _num_bdf_properties + font->nuser_props;
-
-  error = hash_insert(p->name, (void *) n, &(font->proptbl) , memory);
-  if (error) return error;
-
-  font->nuser_props++;
-  return FT_Err_Ok;
-}
+  }
 
 
-FT_LOCAL_DEF( bdf_property_t* )
-bdf_get_property(char *name, bdf_font_t *font)
-{
-  hashnode hn;
-  unsigned long propid;
-
-  if (name == 0 || *name == 0)
-    return 0;
-
-  if ((hn = hash_lookup(name, &(font->proptbl))) == 0)
-    return 0;
-
-  propid = (unsigned long) hn->data;
-  if (propid >= _num_bdf_properties)
-    return font->user_props + (propid - _num_bdf_properties);
-
-  return _bdf_properties + propid;
-}
-
-
-/**************************************************************************
- *
- * BDF font file parsing flags and functions.
- *
- **************************************************************************/
-
-/*
- * Parse flags.
- */
-#define _BDF_START     0x0001
-#define _BDF_FONT_NAME 0x0002
-#define _BDF_SIZE      0x0004
-#define _BDF_FONT_BBX  0x0008
-#define _BDF_PROPS     0x0010
-#define _BDF_GLYPHS    0x0020
-#define _BDF_GLYPH     0x0040
-#define _BDF_ENCODING  0x0080
-#define _BDF_SWIDTH    0x0100
-#define _BDF_DWIDTH    0x0200
-#define _BDF_BBX       0x0400
-#define _BDF_BITMAP    0x0800
-
-#define _BDF_SWIDTH_ADJ 0x1000
-
-#define _BDF_GLYPH_BITS (_BDF_GLYPH|_BDF_ENCODING|_BDF_SWIDTH|\
-                         _BDF_DWIDTH|_BDF_BBX|_BDF_BITMAP)
-
-#define _BDF_GLYPH_WIDTH_CHECK 0x40000000
-#define _BDF_GLYPH_HEIGHT_CHECK 0x80000000
-
-/*
- * Auto correction messages.
- */
-#define ACMSG1 "FONT_ASCENT property missing.  Added \"FONT_ASCENT %hd\"."
-#define ACMSG2 "FONT_DESCENT property missing.  Added \"FONT_DESCENT %hd\"."
-#define ACMSG3 "Font width != actual width.  Old: %hd New: %hd."
-#define ACMSG4 "Font left bearing != actual left bearing.  Old: %hd New: %hd."
-#define ACMSG5 "Font ascent != actual ascent.  Old: %hd New: %hd."
-#define ACMSG6 "Font descent != actual descent.  Old: %hd New: %hd."
-#define ACMSG7 "Font height != actual height. Old: %hd New: %hd."
-#define ACMSG8 "Glyph scalable width (SWIDTH) adjustments made."
-#define ACMSG9 "SWIDTH field missing at line %ld.  Set automatically."
-#define ACMSG10 "DWIDTH field missing at line %ld.  Set to glyph width."
-#define ACMSG11 "SIZE bits per pixel field adjusted to %hd."
-#define ACMSG12 "Duplicate encoding %ld (%s) changed to unencoded."
-#define ACMSG13 "Glyph %ld extra rows removed."
-#define ACMSG14 "Glyph %ld extra columns removed."
-#define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found."
-
-/*
- * Error messages.
- */
-#define ERRMSG1 "[line %ld] Missing \"%s\" line."
-#define ERRMSG2 "[line %ld] Font header corrupted or missing fields."
-#define ERRMSG3 "[line %ld] Font glyphs corrupted or missing fields."
-
-static FT_Error
-_bdf_add_acmsg ( bdf_font_t*    font,
-                 char*          msg,
-                 unsigned long  len )
-{
-  char*      cp;
-  FT_Memory  memory = font->memory;
-  FT_Error   error;
-
-  if ( font->acmsgs_len == 0 )
+  FT_LOCAL_DEF( bdf_property_t * )
+  bdf_get_property( char*        name,
+                    bdf_font_t*  font )
   {
-    if ( FT_ALLOC ( font->acmsgs , len + 1 ) )
-      return error;
+    hashnode       hn;
+    unsigned long  propid;
+
+
+    if ( name == 0 || *name == 0 )
+      return 0;
+
+    if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 )
+      return 0;
+
+    propid = (unsigned long)hn->data;
+    if ( propid >= _num_bdf_properties )
+      return font->user_props + ( propid - _num_bdf_properties );
+
+    return _bdf_properties + propid;
   }
-  else
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* BDF font file parsing flags and functions.                            */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /* Parse flags. */
+
+#define _BDF_START      0x0001
+#define _BDF_FONT_NAME  0x0002
+#define _BDF_SIZE       0x0004
+#define _BDF_FONT_BBX   0x0008
+#define _BDF_PROPS      0x0010
+#define _BDF_GLYPHS     0x0020
+#define _BDF_GLYPH      0x0040
+#define _BDF_ENCODING   0x0080
+#define _BDF_SWIDTH     0x0100
+#define _BDF_DWIDTH     0x0200
+#define _BDF_BBX        0x0400
+#define _BDF_BITMAP     0x0800
+
+#define _BDF_SWIDTH_ADJ  0x1000
+
+#define _BDF_GLYPH_BITS ( _BDF_GLYPH    | \
+                          _BDF_ENCODING | \
+                          _BDF_SWIDTH   | \
+                          _BDF_DWIDTH   | \
+                          _BDF_BBX      | \
+                          _BDF_BITMAP   )
+
+#define _BDF_GLYPH_WIDTH_CHECK   0x40000000L
+#define _BDF_GLYPH_HEIGHT_CHECK  0x80000000L
+
+
+  /* Auto correction messages. */
+#define ACMSG1   "FONT_ASCENT property missing.  " \
+                 "Added \"FONT_ASCENT %hd\".\n"
+#define ACMSG2   "FONT_DESCENT property missing.  " \
+                 "Added \"FONT_DESCENT %hd\".\n"
+#define ACMSG3   "Font width != actual width.  Old: %hd New: %hd.\n"
+#define ACMSG4   "Font left bearing != actual left bearing.  " \
+                 "Old: %hd New: %hd.\n"
+#define ACMSG5   "Font ascent != actual ascent.  Old: %hd New: %hd.\n"
+#define ACMSG6   "Font descent != actual descent.  Old: %hd New: %hd.\n"
+#define ACMSG7   "Font height != actual height. Old: %hd New: %hd.\n"
+#define ACMSG8   "Glyph scalable width (SWIDTH) adjustments made.\n"
+#define ACMSG9   "SWIDTH field missing at line %ld.  Set automatically.\n"
+#define ACMSG10  "DWIDTH field missing at line %ld.  Set to glyph width.\n"
+#define ACMSG11  "SIZE bits per pixel field adjusted to %hd.\n"
+#define ACMSG12  "Duplicate encoding %ld (%s) changed to unencoded.\n"
+#define ACMSG13  "Glyph %ld extra rows removed.\n"
+#define ACMSG14  "Glyph %ld extra columns removed.\n"
+#define ACMSG15  "Incorrect glyph count: %ld indicated but %ld found.\n"
+
+  /* Error messages. */
+#define ERRMSG1  "[line %ld] Missing \"%s\" line.\n"
+#define ERRMSG2  "[line %ld] Font header corrupted or missing fields.\n"
+#define ERRMSG3  "[line %ld] Font glyphs corrupted or missing fields.\n"
+
+
+  static FT_Error
+  _bdf_add_comment( bdf_font_t*    font,
+                    char*          comment,
+                    unsigned long  len )
   {
-    if ( FT_REALLOC ( font->acmsgs , font->acmsgs_len ,
-                      font->acmsgs_len + len + 1 ) )
-      return error;
+    char*      cp;
+    FT_Memory  memory = font->memory;
+    FT_Error   error = BDF_Err_Ok;
+
+
+    if ( font->comments_len == 0 )
+    {
+      if ( FT_NEW_ARRAY( font->comments, len + 1 ) )
+        goto Exit;
+    }
+    else
+    {
+      if ( FT_RENEW_ARRAY( font->comments,
+                           font->comments_len,
+                           font->comments_len + len + 1 ) )
+        goto Exit;
+    }
+
+    cp = font->comments + font->comments_len;
+    FT_MEM_COPY( cp, comment, len );
+    cp   += len;
+    *cp++ = '\n';
+    font->comments_len += len + 1;
+
+  Exit:
+    return error;
   }
 
-  cp = font->acmsgs + font->acmsgs_len;
-  FT_MEM_COPY(cp, msg, len);
-  cp   += len;
-  *cp++ = '\n';
-  font->acmsgs_len += len + 1;
 
-  return FT_Err_Ok;
-}
-
-
-static FT_Error
-_bdf_add_comment ( bdf_font_t*    font,
-                   char*          comment,
-                   unsigned long  len )
-{
-  char *cp;
-  FT_Memory memory = font->memory;
-  FT_Error error;
-
-  if (font->comments_len == 0) {
-    if ( FT_ALLOC ( font->comments , len + 1 ) )
-      return error;
-  }
-  else
+  /* Set the spacing from the font name if it exists, or set it to the */
+  /* default specified in the options.                                 */
+  static FT_Error
+  _bdf_set_default_spacing( bdf_font_t*     font,
+                            bdf_options_t*  opts )
   {
-    if ( FT_REALLOC ( font->comments , font->comments_len,
-                      font->comments_len + len + 1) )
-      return error;
-  }
+    unsigned long  len;
+    char           name[128];
+    _bdf_list_t    list;
+    FT_Memory      memory;
+    FT_Error       error = BDF_Err_Ok;
 
-  cp = font->comments + font->comments_len;
-  FT_MEM_COPY(cp, comment, len);
-  cp += len;
-  *cp++ = '\n';
-  font->comments_len += len + 1;
 
-  return FT_Err_Ok;
-}
+    if ( font == 0 || font->name == 0 || font->name[0] == 0 )
+    {
+      error = BDF_Err_Invalid_Argument;
+      goto Exit;
+    }
 
-/*
- * Set the spacing from the font name if it exists, or set it to the default
- * specified in the options.
- */
-static void
-_bdf_set_default_spacing( bdf_font_t*     font,
-                          bdf_options_t*  opts)
-{
-  unsigned long  len;
-  char            name[128];
-  _bdf_list_t     list;
-  FT_Memory       memory;
-  /*    FT_Error error; */
+    memory = font->memory;
 
-  if ( font == 0 || font->name == 0 || font->name[0] == 0 )
-    return;
+    font->spacing = opts->font_spacing;
 
-  memory = font->memory;
+    len = (unsigned long)( ft_strlen( font->name ) + 1 );
+    FT_MEM_COPY( name, font->name, len );
 
-  font->spacing = opts->font_spacing;
+    list.size = list.used = 0;
 
-  len = (unsigned long) ( ft_strlen(font->name) + 1 );
-  (void) ft_memcpy(name, font->name, len);
-  
-  list.size = list.used = 0;
-  _bdf_split("-", name, len, &list, memory);
-  
-  if (list.used == 15) {
-      switch (list.field[11][0]) {
-        case 'C': case 'c': font->spacing = BDF_CHARCELL; break;
-        case 'M': case 'm': font->spacing = BDF_MONOWIDTH; break;
-        case 'P': case 'p': font->spacing = BDF_PROPORTIONAL; break;
+    error = _bdf_split( (char *)"-", name, len, &list, memory );
+    if ( error )
+      goto Exit;
+
+    if ( list.used == 15 )
+    {
+      switch ( list.field[11][0] )
+      {
+      case 'C':
+      case 'c':
+        font->spacing = BDF_CHARCELL;
+        break;
+      case 'M':
+      case 'm':
+        font->spacing = BDF_MONOWIDTH;
+        break;
+      case 'P':
+      case 'p':
+        font->spacing = BDF_PROPORTIONAL;
+        break;
       }
+    }
+
+    FT_FREE( list.field );
+
+  Exit:
+    return error;
   }
-  if (list.size > 0)
-    FT_FREE(list.field);
-}
 
 
-/*
- * Determine if the property is an atom or not.  If it is, then clean it up so
- * the double quotes are removed if they exist.
- */
-static int
-_bdf_is_atom( char*          line,
-              unsigned long  linelen,
-              char*         *name,
-              char*         *value,
-	      bdf_font_t*    font)
-{
-    int hold;
-    char *sp, *ep;
-    bdf_property_t *p;
+  /* Determine whether the property is an atom or not.  If it is, then */
+  /* clean it up so the double quotes are removed if they exist.       */
+  static int
+  _bdf_is_atom( char*          line,
+                unsigned long  linelen,
+                char**         name,
+                char**         value,
+                bdf_font_t*    font )
+  {
+    int              hold;
+    char             *sp, *ep;
+    bdf_property_t*  p;
+
 
     *name = sp = ep = line;
-    while (*ep && *ep != ' ' && *ep != '\t')
+
+    while ( *ep && *ep != ' ' && *ep != '\t' )
       ep++;
 
     hold = -1;
-    if (*ep)
+    if ( *ep )
     {
       hold = *ep;
       *ep  = 0;
     }
 
-    p = bdf_get_property(sp, font);
+    p = bdf_get_property( sp, font );
 
-    /*
-     * Restore the character that was saved before any return can happen.
-     */
-    if (hold != -1)
+    /* Restore the character that was saved before any return can happen. */
+    if ( hold != -1 )
       *ep = hold;
 
-    /*
-     * If the propert exists and is not an atom, just return here.
-     */
-    if (p && p->format != BDF_ATOM)
+    /* If the property exists and is not an atom, just return here. */
+    if ( p && p->format != BDF_ATOM )
       return 0;
 
-    /*
-     * The property is an atom.  Trim all leading and trailing whitespace and
-     * double quotes for the atom value.
-     */
+    /* The property is an atom.  Trim all leading and trailing whitespace */
+    /* and double quotes for the atom value.                              */
     sp = ep;
     ep = line + linelen;
 
-    /*
-     * Trim the leading whitespace if it exists.
-     */
+    /* Trim the leading whitespace if it exists. */
     *sp++ = 0;
-    while (*sp && (*sp == ' ' || *sp == '\t'))
+    while ( *sp                           &&
+            ( *sp == ' ' || *sp == '\t' ) )
       sp++;
 
-    /*
-     * Trim the leading double quote if it exists.
-     */
-    if (*sp == '"')
+    /* Trim the leading double quote if it exists. */
+    if ( *sp == '"' )
       sp++;
     *value = sp;
 
-    /*
-     * Trim the trailing whitespace if it exists.
-     */
-    while (ep > sp && (*(ep - 1) == ' ' || *(ep - 1) == '\t'))
+    /* Trim the trailing whitespace if it exists. */
+    while ( ep > sp                                       &&
+            ( *( ep - 1 ) == ' ' || *( ep - 1 ) == '\t' ) )
       *--ep = 0;
 
-    /*
-     * Trim the trailing double quote if it exists.
-     */
-    if (ep > sp && *(ep - 1) == '"')
+    /* Trim the trailing double quote if it exists. */
+    if ( ep > sp && *( ep - 1 ) == '"' )
       *--ep = 0;
 
     return 1;
-}
+  }
 
 
-static FT_Error
-_bdf_add_property ( bdf_font_t*  font,
-                    char*        name,
-                    char*        value)
-{
-    unsigned long propid;
-    hashnode hn;
-    int len;
-    bdf_property_t *prop, *fp;
-    FT_Memory memory = font->memory;
-    FT_Error error;
-    /*    hashtable proptbl = font->proptbl;
-    bdf_property_t *user_props = font->user_props;
-    unsigned long nuser_props = font->nuser_props;
-    */
+  static FT_Error
+  _bdf_add_property( bdf_font_t*  font,
+                     char*        name,
+                     char*        value )
+  {
+    unsigned long   propid;
+    hashnode        hn;
+    int             len;
+    bdf_property_t  *prop, *fp;
+    FT_Memory       memory = font->memory;
+    FT_Error        error = BDF_Err_Ok;
 
-     /*
-     * First, check to see if the property already exists in the font.
-     */
-    if ((hn = hash_lookup(name, (hashtable *) font->internal)) != 0) {
-        /*
-         * The property already exists in the font, so simply replace
-         * the value of the property with the current value.
-         */
-        fp = font->props + (unsigned long) hn->data;
 
-        switch (prop->format)
-        {
-          case BDF_ATOM:
-            {
-              /*
-               * Delete the current atom if it exists.
-               */
-              FT_FREE ( fp->value.atom );
-  
-              if (value == 0)
-                len = 1;
-              else
-                len = ft_strlen(value) + 1;
-              if (len > 1)
-              {
-  	      if ( FT_ALLOC ( fp->value.atom , len ) )
-                  return error;
-                  
-                FT_MEM_COPY(fp->value.atom, value, len);
-              }
-              else
-                fp->value.atom = 0;
-            }
-            break;
-            
-          case BDF_INTEGER:
-            fp->value.int32 = _bdf_atol(value, 0, 10);
-            break;
-            
-          case BDF_CARDINAL:
-            fp->value.card32 = _bdf_atoul(value, 0, 10);
-            break;
-          
-          default:
-            ;
-        }
-        return FT_Err_Ok;
-    }
-
-    /*
-     * See if this property type exists yet or not.  If not, create it.
-     */
-    hn = hash_lookup(name, &(font->proptbl));
-    if (hn == 0) {
-        bdf_create_property(name, BDF_ATOM, font);
-        hn = hash_lookup(name, &(font->proptbl));
-    }
-
-    /*
-     * Allocate another property if this is overflow.
-     */
-    if (font->props_used == font->props_size)
+    /* First, check to see if the property already exists in the font. */
+    if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 )
     {
-      if (font->props_size == 0)
+      /* The property already exists in the font, so simply replace */
+      /* the value of the property with the current value.          */
+      fp = font->props + (unsigned long)hn->data;
+
+      switch ( prop->format )
       {
-        if ( FT_NEW( font->props ) )
-          return error;
+      case BDF_ATOM:
+        /* Delete the current atom if it exists. */
+        FT_FREE( fp->value.atom );
+
+        if ( value == 0 )
+          len = 1;
+        else
+          len = ft_strlen( value ) + 1;
+
+        if ( len > 1 )
+        {
+          if ( FT_NEW_ARRAY( fp->value.atom, len ) )
+            goto Exit;
+          FT_MEM_COPY( fp->value.atom, value, len );
+        }
+        else
+          fp->value.atom = 0;
+        break;
+
+      case BDF_INTEGER:
+        fp->value.int32 = _bdf_atol( value, 0, 10 );
+        break;
+
+      case BDF_CARDINAL:
+        fp->value.card32 = _bdf_atoul( value, 0, 10 );
+        break;
+      }
+
+      goto Exit;
+    }
+
+    /* See whether this property type exists yet or not. */
+    /* If not, create it.                                */
+    hn = hash_lookup( name, &(font->proptbl) );
+    if ( hn == 0 )
+    {
+      error = bdf_create_property( name, BDF_ATOM, font );
+      if ( error )
+        goto Exit;
+      hn = hash_lookup( name, &(font->proptbl) );
+    }
+
+    /* Allocate another property if this is overflow. */
+    if ( font->props_used == font->props_size )
+    {
+      if ( font->props_size == 0 )
+      {
+        if ( FT_NEW_ARRAY( font->props, 1 ) )
+          goto Exit;
       }
       else
       {
-        if ( FT_RENEW_ARRAY( font->props, font->props_size,
-                                         (font->props_size + 1) ) )
-          return error;
+        if ( FT_RENEW_ARRAY( font->props,
+                             font->props_size,
+                             font->props_size + 1 ) )
+          goto Exit;
       }
+
       fp = font->props + font->props_size;
-      FT_ZERO( fp );
+      FT_MEM_SET( fp, 0, sizeof ( bdf_property_t ) );
       font->props_size++;
     }
 
-    propid = (unsigned long) hn->data;
-    if (propid >= _num_bdf_properties)
-      prop = font->user_props + (propid - _num_bdf_properties);
+    propid = (unsigned long)hn->data;
+    if ( propid >= _num_bdf_properties )
+      prop = font->user_props + ( propid - _num_bdf_properties );
     else
       prop = _bdf_properties + propid;
 
@@ -1411,1055 +1349,1062 @@
     fp->format  = prop->format;
     fp->builtin = prop->builtin;
 
-    switch (prop->format)
+    switch ( prop->format )
     {
-      case BDF_ATOM:
-        {
-          fp->value.atom = NULL;
-          
-          if ( value && value[0] != 0 )
-          {
-            len = ft_strlen(value) + 1;
+    case BDF_ATOM:
+      if ( value == 0 )
+        len = 1;
+      else
+        len = ft_strlen( value ) + 1;
 
-  	    if ( FT_ALLOC ( fp->value.atom , len ) )
-                return error;
-                
-             FT_MEM_COPY (fp->value.atom, value, len);
-          }
-        }
-        break;
+      if ( len > 1 )
+      {
+        if ( FT_NEW_ARRAY( fp->value.atom, len ) )
+          goto Exit;
+        FT_MEM_COPY( fp->value.atom, value, len );
+      }
+      else
+        fp->value.atom = 0;
+      break;
 
     case BDF_INTEGER:
-      fp->value.int32 = _bdf_atol(value, 0, 10);
+      fp->value.int32 = _bdf_atol( value, 0, 10 );
       break;
 
     case BDF_CARDINAL:
-      fp->value.card32 = _bdf_atoul(value, 0, 10);
+      fp->value.card32 = _bdf_atoul( value, 0, 10 );
       break;
-    
-    default:
-      ;
     }
 
-    /*
-     * If the property happens to be a comment, then it doesn't need
-     * to be added to the internal hash table.
-     */
-    if ( ft_memcmp(name, "COMMENT", 7) != 0 )
-      /*
-       * Add the property to the font property table.
-       */
-      hash_insert( fp->name, (void *) font->props_used,
-                   (hashtable *) font->internal, memory);
+    /* If the property happens to be a comment, then it doesn't need */
+    /* to be added to the internal hash table.                       */
+    if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) {
+      /* Add the property to the font property table. */
+      error = hash_insert( fp->name,
+                           (void *)font->props_used,
+                           (hashtable *)font->internal,
+                           memory );
+      if ( error )
+        goto Exit;
+    }
 
     font->props_used++;
 
-    /*
-     * Some special cases need to be handled here.  The DEFAULT_CHAR property
-     * needs to be located if it exists in the property list, the FONT_ASCENT
-     * and FONT_DESCENT need to be assigned if they are present, and the
-     * SPACING property should override the default spacing.
-     */
-    if ( ft_memcmp(name, "DEFAULT_CHAR", 12) == 0 )
+    /* Some special cases need to be handled here.  The DEFAULT_CHAR       */
+    /* property needs to be located if it exists in the property list, the */
+    /* FONT_ASCENT and FONT_DESCENT need to be assigned if they are        */
+    /* present, and the SPACING property should override the default       */
+    /* spacing.                                                            */
+    if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 )
       font->default_glyph = fp->value.int32;
-      
-    else if ( ft_memcmp(name, "FONT_ASCENT", 11) == 0 )
+    else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 )
       font->font_ascent = fp->value.int32;
-      
-    else if ( ft_memcmp(name, "FONT_DESCENT", 12) == 0 )
+    else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 )
       font->font_descent = fp->value.int32;
-      
-    else if ( ft_memcmp(name, "SPACING", 7) == 0 )
+    else if ( ft_memcmp( name, "SPACING", 7 ) == 0 )
     {
-      if (fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P')
+      if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' )
         font->spacing = BDF_PROPORTIONAL;
-        
-      else if (fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M')
+      else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' )
         font->spacing = BDF_MONOWIDTH;
-        
-      else if (fp->value.atom[0] == 'c' || fp->value.atom[0] == 'C')
+      else if ( fp->value.atom[0] == 'c' || fp->value.atom[0] == 'C' )
         font->spacing = BDF_CHARCELL;
     }
 
-    return FT_Err_Ok;
-}
-
-/*
- * Actually parse the glyph info and bitmaps.
- */
-static int
-_bdf_parse_glyphs( char*          line,
-                   unsigned long  linelen,
-                   unsigned long  lineno,
-                   void*          call_data,
-                   void*          client_data)
-{
-  int c;
-  char *s;
-  unsigned char *bp;
-  unsigned long i, slen, nibbles;
-  double ps, rx, dw, sw;
-  _bdf_line_func_t *next;
-  _bdf_parse_t *p;
-  bdf_glyph_t *glyph;
-  bdf_font_t *font;
-  char nbuf[128];
-  FT_Memory memory;
-  FT_Error error;
-
-  next = (_bdf_line_func_t *) call_data;
-  p = (_bdf_parse_t *) client_data;
-
-  font = p->font;
-  memory = font->memory;
-
-  /*
-   * Check for a comment.
-   */
-  if (ft_memcmp(line, "COMMENT", 7) == 0) {
-      linelen -= 7;
-      s = line + 7;
-      if (*s != 0) {
-          s++;
-          linelen--;
-      }
-      _bdf_add_comment(p->font, s, linelen);
-      return 0;
+  Exit:
+    return error;
   }
 
-  /*
-   * The very first thing expected is the number of glyphs.
-   */
-  if (!(p->flags & _BDF_GLYPHS)) {
-      if (ft_memcmp(line, "CHARS", 5) != 0) {
-          sprintf(nbuf, ERRMSG1, lineno, "CHARS");
-          _bdf_add_acmsg(p->font, nbuf, ft_strlen(nbuf));
-          return BDF_MISSING_CHARS;
-      }
-      _bdf_split(" +", line, linelen, &p->list, memory);
-      p->cnt = font->glyphs_size = _bdf_atoul(p->list.field[1], 0, 10);
 
-      /*
-       * Make sure the number of glyphs is non-zero.
-       */
-      if (p->cnt == 0)
+  static unsigned char nibble_mask[8] =
+  {
+    0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE
+  };
+
+
+  /* Actually parse the glyph info and bitmaps. */
+  static FT_Error
+  _bdf_parse_glyphs( char*          line,
+                     unsigned long  linelen,
+                     unsigned long  lineno,
+                     void*          call_data,
+                     void*          client_data )
+  {
+    int                c, mask_index;
+    char*              s;
+    unsigned char*     bp;
+    unsigned long      i, slen, nibbles;
+    double             ps, rx, dw, sw;
+
+    _bdf_line_func_t*  next;
+    _bdf_parse_t*      p;
+    bdf_glyph_t*       glyph;
+    bdf_font_t*        font;
+
+    FT_Memory          memory;
+    FT_Error           error = BDF_Err_Ok;
+
+    FT_UNUSED( lineno );        /* only used in debug mode */
+
+
+    next = (_bdf_line_func_t *)call_data;
+    p    = (_bdf_parse_t *)    client_data;
+
+    font   = p->font;
+    memory = font->memory;
+
+    /* Check for a comment. */
+    if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )
+    {
+      linelen -= 7;
+
+      s = line + 7;
+      if ( *s != 0 )
+      {
+        s++;
+        linelen--;
+      }
+      error = _bdf_add_comment( p->font, s, linelen );
+      goto Exit;
+    }
+
+    /* The very first thing expected is the number of glyphs. */
+    if ( !( p->flags & _BDF_GLYPHS ) )
+    {
+      if ( ft_memcmp( line, "CHARS", 5 ) != 0 )
+      {
+        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" ));
+        error = BDF_Err_Missing_Chars_Field;
+        goto Exit;
+      }
+
+      error = _bdf_split( (char *)" +", line, linelen, &p->list, memory );
+      if ( error )
+        goto Exit;
+      p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 );
+
+      /* Make sure the number of glyphs is non-zero. */
+      if ( p->cnt == 0 )
         font->glyphs_size = 64;
 
-if ( FT_ALLOC ( font->glyphs , sizeof(bdf_glyph_t) *
-                      font->glyphs_size ) )
-        return FT_Err_Out_Of_Memory;
+      if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) )
+        goto Exit;
 
-      /*
-       * Set up the callback to indicate the glyph loading is about to
-       * begin.
-       */
-      if (p->callback != 0) {
-          p->cb.reason = BDF_LOAD_START;
-          p->cb.total = p->cnt;
-          p->cb.current = 0;
-          (*p->callback)(&p->cb, p->client_data);
-      }
       p->flags |= _BDF_GLYPHS;
-      return 0;
-  }
 
-  /*
-   * Check for the ENDFONT field.
-   */
-  if (ft_memcmp(line, "ENDFONT", 7) == 0) {
-      /*
-       * Sort the glyphs by encoding.
-       */
-    qsort((char *) font->glyphs, font->glyphs_used, sizeof(bdf_glyph_t),
-          by_encoding);
+      goto Exit;
+    }
+
+    /* Check for the ENDFONT field. */
+    if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 )
+    {
+      /* Sort the glyphs by encoding. */
+      ft_qsort( (char *)font->glyphs,
+                font->glyphs_used,
+                sizeof ( bdf_glyph_t ),
+                by_encoding );
 
       p->flags &= ~_BDF_START;
-      return 0;
-  }
 
-  /*
-   * Check for the ENDCHAR field.
-   */
-  if (ft_memcmp(line, "ENDCHAR", 7) == 0) {
-      /*
-       * Set up and call the callback if it was passed.
-       */
-    if (p->callback != 0) {
-      p->cb.reason = BDF_LOADING;
-      p->cb.total = font->glyphs_size;
-      p->cb.current = font->glyphs_used;
-      (*p->callback)(&p->cb, p->client_data);
-    }
-    p->glyph_enc = 0;
-    p->flags &= ~_BDF_GLYPH_BITS;
-    return 0;
-  }
-
-  /*
-   * Check to see if a glyph is being scanned but should be ignored
-   * because it is an unencoded glyph.
-   */
-  if ((p->flags & _BDF_GLYPH) &&
-      p->glyph_enc == -1 && p->opts->keep_unencoded == 0)
-    return 0;
-
-  /*
-   * Check for the STARTCHAR field.
-   */
-  if (ft_memcmp(line, "STARTCHAR", 9) == 0) {
-      /*
-       * Set the character name in the parse info first until the
-       * encoding can be checked for an unencoded character.
-       */
-    if (p->glyph_name != 0)
-      FT_FREE(p->glyph_name);
-    _bdf_split(" +", line, linelen, &p->list,memory);
-    _bdf_shift(1, &p->list);
-    s = _bdf_join(' ', &slen, &p->list);
-    if ( FT_ALLOC ( p->glyph_name , (slen + 1) ) )
-      return BDF_OUT_OF_MEMORY;
-    FT_MEM_COPY(p->glyph_name, s, slen + 1);
-    p->flags |= _BDF_GLYPH;
-    return 0;
-  }
-
-  /*
-   * Check for the ENCODING field.
-   */
-  if (ft_memcmp(line, "ENCODING", 8) == 0) {
-    if (!(p->flags & _BDF_GLYPH)) {
-      /*
-       * Missing STARTCHAR field.
-       */
-      sprintf(nbuf, ERRMSG1, lineno, "STARTCHAR");
-      _bdf_add_acmsg(font, nbuf, ft_strlen(nbuf));
-      return BDF_MISSING_STARTCHAR;
-    }
-    _bdf_split(" +", line, linelen, &p->list, memory);
-    p->glyph_enc = _bdf_atol(p->list.field[1], 0, 10);
-
-    /*
-     * Check to see if this encoding has already been encountered.  If it
-     * has then change it to unencoded so it gets added if indicated.
-     */
-    if (p->glyph_enc >= 0) {
-      if (_bdf_glyph_modified(p->have, p->glyph_enc)) {
-        /*
-         * Add a message saying a glyph has been moved to the
-         * unencoded area.
-         */
-        sprintf(nbuf, ACMSG12, p->glyph_enc, p->glyph_name);
-        _bdf_add_acmsg(font, nbuf, ft_strlen(nbuf));
-        p->glyph_enc = -1;
-        font->modified = 1;
-      } else
-        _bdf_set_glyph_modified(p->have, p->glyph_enc);
+      goto Exit;
     }
 
-    if (p->glyph_enc >= 0) {
-      /*
-       * Make sure there are enough glyphs allocated in case the
-       * number of characters happen to be wrong.
-       */
-      if (font->glyphs_used == font->glyphs_size) {
-        if ( FT_REALLOC ( font->glyphs,
-                          sizeof(bdf_glyph_t) * font->glyphs_size,
-                          sizeof(bdf_glyph_t) * (font->glyphs_size + 64) ) )
-          return BDF_OUT_OF_MEMORY;
-        FT_MEM_SET ((char *) (font->glyphs + font->glyphs_size),
-                    0, sizeof(bdf_glyph_t) << 6); /* FZ inutile */
-        font->glyphs_size += 64;
+    /* Check for the ENDCHAR field. */
+    if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 )
+    {
+      p->glyph_enc = 0;
+      p->flags    &= ~_BDF_GLYPH_BITS;
+
+      goto Exit;
+    }
+
+    /* Check to see whether a glyph is being scanned but should be */
+    /* ignored because it is an unencoded glyph.                   */
+    if ( ( p->flags & _BDF_GLYPH )     &&
+         p->glyph_enc            == -1 &&
+         p->opts->keep_unencoded == 0  )
+      goto Exit;
+
+    /* Check for the STARTCHAR field. */
+    if ( ft_memcmp( line, "STARTCHAR", 9 ) == 0 )
+    {
+      /* Set the character name in the parse info first until the */
+      /* encoding can be checked for an unencoded character.      */
+      FT_FREE( p->glyph_name );
+
+      error = _bdf_split( (char *)" +", line, linelen, &p->list,memory );
+      if ( error )
+        goto Exit;
+      _bdf_shift( 1, &p->list );
+
+      s = _bdf_join( ' ', &slen, &p->list );
+
+      if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) )
+        goto Exit;
+      FT_MEM_COPY( p->glyph_name, s, slen + 1 );
+
+      p->flags |= _BDF_GLYPH;
+
+      goto Exit;
+    }
+
+    /* Check for the ENCODING field. */
+    if ( ft_memcmp( line, "ENCODING", 8 ) == 0 )
+    {
+      if ( !( p->flags & _BDF_GLYPH ) )
+      {
+        /* Missing STARTCHAR field. */
+        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" ));
+        error = BDF_Err_Missing_Startchar_Field;
+        goto Exit;
       }
 
-      glyph = font->glyphs + font->glyphs_used++;
-      glyph->name = p->glyph_name;
-      glyph->encoding = p->glyph_enc;
+      error = _bdf_split( (char *)" +", line, linelen, &p->list, memory );
+      if ( error )
+        goto Exit;
+      p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 );
 
-      /*
-       * Reset the initial glyph info.
-       */
-      p->glyph_name = 0;
-    } else {
-      /*
-       * Unencoded glyph.  Check to see if it should be added or not.
-       */
-      if (p->opts->keep_unencoded != 0) {
-        /*
-         * Allocate the next unencoded glyph.
-         */
-        if (font->unencoded_used == font->unencoded_size) {
-          if (font->unencoded_size == 0) {
-            if ( FT_ALLOC ( font->unencoded , sizeof(bdf_glyph_t) << 2 ) )
-              return BDF_OUT_OF_MEMORY;
-          }
-          else {
-            if ( FT_REALLOC ( font->unencoded ,
-                              sizeof(bdf_glyph_t) * font->unencoded_size,
-                              sizeof(bdf_glyph_t) *
-                              (font->unencoded_size + 4) ) )
-              return BDF_OUT_OF_MEMORY;
-          }
-          font->unencoded_size += 4;
+      /* Check to see whether this encoding has already been encountered. */
+      /* If it has then change it to unencoded so it gets added if        */
+      /* indicated.                                                       */
+      if ( p->glyph_enc >= 0 )
+      {
+        if ( _bdf_glyph_modified( p->have, p->glyph_enc ) )
+        {
+          /* Emit a message saying a glyph has been moved to the */
+          /* unencoded area.                                     */
+          FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG12,
+                      p->glyph_enc, p->glyph_name ));
+          p->glyph_enc = -1;
+          font->modified = 1;
+        }
+        else
+          _bdf_set_glyph_modified( p->have, p->glyph_enc );
+      }
+
+      if ( p->glyph_enc >= 0 )
+      {
+        /* Make sure there are enough glyphs allocated in case the */
+        /* number of characters happen to be wrong.                */
+        if ( font->glyphs_used == font->glyphs_size )
+        {
+          if ( FT_RENEW_ARRAY( font->glyphs,
+                               font->glyphs_size,
+                               font->glyphs_size + 64 ) )
+            goto Exit;
+          FT_MEM_SET( font->glyphs + font->glyphs_size,
+                      0,
+                      sizeof ( bdf_glyph_t ) * 64 ); /* FZ inutile */
+          font->glyphs_size += 64;
         }
 
-        glyph = font->unencoded + font->unencoded_used;
-        glyph->name = p->glyph_name;
-        glyph->encoding = font->unencoded_used++;
-      } else
-        /*
-         * Free up the glyph name if the unencoded shouldn't be
-         * kept.
-         */
-        FT_FREE( p->glyph_name );
+        glyph           = font->glyphs + font->glyphs_used++;
+        glyph->name     = p->glyph_name;
+        glyph->encoding = p->glyph_enc;
 
-      p->glyph_name = 0;
+        /* Reset the initial glyph info. */
+        p->glyph_name = 0;
+      }
+      else
+      {
+        /* Unencoded glyph.  Check to see whether it should */
+        /* be added or not.                                 */
+        if ( p->opts->keep_unencoded != 0 )
+        {
+          /* Allocate the next unencoded glyph. */
+          if ( font->unencoded_used == font->unencoded_size )
+          {
+            if ( font->unencoded_size == 0 )
+            {
+              if ( FT_NEW_ARRAY( font->unencoded, 2 ) )
+                goto Exit;
+            }
+            else
+            {
+              if ( FT_RENEW_ARRAY( font->unencoded ,
+                                   font->unencoded_size,
+                                   font->unencoded_size + 4 ) )
+                goto Exit;
+            }
+            font->unencoded_size += 4;
+          }
+
+          glyph           = font->unencoded + font->unencoded_used;
+          glyph->name     = p->glyph_name;
+          glyph->encoding = font->unencoded_used++;
+        }
+        else
+          /* Free up the glyph name if the unencoded shouldn't be */
+          /* kept.                                                */
+          FT_FREE( p->glyph_name );
+
+        p->glyph_name = 0;
+      }
+
+      /* Clear the flags that might be added when width and height are */
+      /* checked for consistency.                                      */
+      p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK );
+
+      p->flags |= _BDF_ENCODING;
+
+      goto Exit;
     }
 
-    /*
-     * Clear the flags that might be added when width and height are
-     * checked for consistency.
-     */
-    p->flags &= ~(_BDF_GLYPH_WIDTH_CHECK|_BDF_GLYPH_HEIGHT_CHECK);
+    /* Point at the glyph being constructed. */
+    if ( p->glyph_enc == -1 )
+      glyph = font->unencoded + ( font->unencoded_used - 1 );
+    else
+      glyph = font->glyphs + ( font->glyphs_used - 1 );
 
-    p->flags |= _BDF_ENCODING;
-    return 0;
-  }
-
-  /*
-   * Point at the glyph being constructed.
-   */
-  if (p->glyph_enc == -1)
-    glyph = font->unencoded + (font->unencoded_used - 1);
-  else
-    glyph = font->glyphs + (font->glyphs_used - 1);
-
-  /*
-   * Check to see if a bitmap is being constructed.
-   */
-  if (p->flags & _BDF_BITMAP) {
-      /*
-       * If there are more rows than are specified in the glyph metrics,
-       * ignore the remaining lines.
-       */
-      if (p->row >= glyph->bbx.height) {
-          if (!(p->flags & _BDF_GLYPH_HEIGHT_CHECK)) {
-              sprintf(nbuf, ACMSG13, glyph->encoding);
-              _bdf_add_acmsg(font, nbuf, ft_strlen(nbuf));
-              p->flags |= _BDF_GLYPH_HEIGHT_CHECK;
-              font->modified = 1;
-          }
-          return 0;
-      }
-
-      /*
-       * Only collect the number of nibbles indicated by the glyph metrics.
-       * If there are more columns, they are simply ignored.
-       */
-      nibbles = p->bpr << 1;
-      bp = glyph->bitmap + (p->row * p->bpr);
-      for (i = 0, *bp = 0; i < nibbles; i++) {
-          c = line[i];
-          *bp = (*bp << 4) + a2i[c];
-          if (i + 1 < nibbles && (i & 1))
-            *++bp = 0;
-      }
-
-      /*
-       * If any line has extra columns, indicate they have been removed.
-       */
-      if ((line[nibbles] == '0' || a2i[(int) line[nibbles]] != 0) &&
-          !(p->flags & _BDF_GLYPH_WIDTH_CHECK)) {
-          sprintf(nbuf, ACMSG14, glyph->encoding);
-          _bdf_add_acmsg(font, nbuf, ft_strlen(nbuf));
-          p->flags |= _BDF_GLYPH_WIDTH_CHECK;
+    /* Check to see whether a bitmap is being constructed. */
+    if ( p->flags & _BDF_BITMAP )
+    {
+      /* If there are more rows than are specified in the glyph metrics, */
+      /* ignore the remaining lines.                                     */
+      if ( p->row >= glyph->bbx.height )
+      {
+        if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) )
+        {
+          FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding ));
+          p->flags |= _BDF_GLYPH_HEIGHT_CHECK;
           font->modified = 1;
+        }
+
+        goto Exit;
+      }
+
+      /* Only collect the number of nibbles indicated by the glyph     */
+      /* metrics.  If there are more columns, they are simply ignored. */
+      nibbles = glyph->bpr << 1;
+      bp      = glyph->bitmap + p->row * glyph->bpr;
+
+      for ( i = 0, *bp = 0; i < nibbles; i++ )
+      {
+        c = line[i];
+        *bp = ( *bp << 4 ) + a2i[c];
+        if ( i + 1 < nibbles && ( i & 1 ) )
+          *++bp = 0;
+      }
+
+      /* Remove possible garbage at the right. */
+      mask_index = ( glyph->bbx.width * p->font->bpp ) & 7;
+      *bp &= nibble_mask[mask_index];
+
+      /* If any line has extra columns, indicate they have been removed. */
+      if ( ( line[nibbles] == '0' || a2i[(int)line[nibbles]] != 0 ) &&
+           !( p->flags & _BDF_GLYPH_WIDTH_CHECK )                   )
+      {
+        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding ));
+        p->flags       |= _BDF_GLYPH_WIDTH_CHECK;
+        font->modified  = 1;
       }
 
       p->row++;
-      return 0;
-  }
+      goto Exit;
+    }
 
-  /*
-   * Expect the SWIDTH (scalable width) field next.
-   */
-  if (ft_memcmp(line, "SWIDTH", 6) == 0) {
-      if (!(p->flags & _BDF_ENCODING)) {
-          /*
-           * Missing ENCODING field.
-           */
-          sprintf(nbuf, ERRMSG1, lineno, "ENCODING");
-          _bdf_add_acmsg(font, nbuf, ft_strlen(nbuf));
-          return BDF_MISSING_ENCODING;
+    /* Expect the SWIDTH (scalable width) field next. */
+    if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 )
+    {
+      if ( !( p->flags & _BDF_ENCODING ) )
+      {
+        /* Missing ENCODING field. */
+        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" ));
+        error = BDF_Err_Missing_Encoding_Field;
+        goto Exit;
       }
-      _bdf_split(" +", line, linelen, &p->list, memory);
-      glyph->swidth = _bdf_atoul(p->list.field[1], 0, 10);
+
+      error = _bdf_split( (char *)" +", line, linelen, &p->list, memory );
+      if ( error )
+        goto Exit;
+      glyph->swidth = _bdf_atoul( p->list.field[1], 0, 10 );
       p->flags |= _BDF_SWIDTH;
-      return 0;
-  }
 
-  /*
-   * Expect the DWIDTH (scalable width) field next.
-   */
-  if (ft_memcmp(line, "DWIDTH", 6) == 0) {
-      _bdf_split(" +", line, linelen, &p->list,memory);
-      glyph->dwidth = _bdf_atoul(p->list.field[1], 0, 10);
+      goto Exit;
+    }
 
-      if (!(p->flags & _BDF_SWIDTH)) {
-          /*
-           * Missing SWIDTH field.  Add an auto correction message and set
-           * the scalable width from the device width.
-           */
-          sprintf(nbuf, ACMSG9, lineno);
-          _bdf_add_acmsg(font, nbuf, ft_strlen(nbuf));
-          ps = (double) font->point_size;
-          rx = (double) font->resolution_x;
-          dw = (double) glyph->dwidth;
-          glyph->swidth = (unsigned short) ((dw * 72000.0) / (ps * rx));
+    /* Expect the DWIDTH (scalable width) field next. */
+    if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 )
+    {
+      error = _bdf_split( (char *)" +", line, linelen, &p->list,memory );
+      if ( error )
+        goto Exit;
+      glyph->dwidth = _bdf_atoul( p->list.field[1], 0, 10 );
+
+      if ( !( p->flags & _BDF_SWIDTH ) )
+      {
+        /* Missing SWIDTH field.  Emit an auto correction message and set */
+        /* the scalable width from the device width.                      */
+        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG9, lineno ));
+
+        ps = (double)font->point_size;
+        rx = (double)font->resolution_x;
+        dw = (double)glyph->dwidth;
+
+        glyph->swidth = (unsigned short)( ( dw * 72000.0 ) / ( ps * rx ) );
       }
 
       p->flags |= _BDF_DWIDTH;
-      return 0;
-  }
+      goto Exit;
+    }
 
-  /*
-   * Expect the BBX field next.
-   */
-  if (ft_memcmp(line, "BBX", 3) == 0) {
-      _bdf_split(" +", line, linelen, &p->list, memory);
-      glyph->bbx.width = _bdf_atos(p->list.field[1], 0, 10);
-      glyph->bbx.height = _bdf_atos(p->list.field[2], 0, 10);
-      glyph->bbx.x_offset = _bdf_atos(p->list.field[3], 0, 10);
-      glyph->bbx.y_offset = _bdf_atos(p->list.field[4], 0, 10);
+    /* Expect the BBX field next. */
+    if ( ft_memcmp( line, "BBX", 3 ) == 0 )
+    {
+      error = _bdf_split( (char *)" +", line, linelen, &p->list, memory );
+      if ( error )
+        goto Exit;
 
-      /*
-       * Generate the ascent and descent of the character.
-       */
-      glyph->bbx.ascent = glyph->bbx.height + glyph->bbx.y_offset;
+      glyph->bbx.width    = _bdf_atos( p->list.field[1], 0, 10 );
+      glyph->bbx.height   = _bdf_atos( p->list.field[2], 0, 10 );
+      glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 );
+      glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 );
+
+      /* Generate the ascent and descent of the character. */
+      glyph->bbx.ascent  = glyph->bbx.height + glyph->bbx.y_offset;
       glyph->bbx.descent = -glyph->bbx.y_offset;
 
-      /*
-       * Determine the overall font bounding box as the characters are
-       * loaded so corrections can be done later if indicated.
-       */
-      p->maxas = MAX(glyph->bbx.ascent, p->maxas);
-      p->maxds = MAX(glyph->bbx.descent, p->maxds);
+      /* Determine the overall font bounding box as the characters are */
+      /* loaded so corrections can be done later if indicated.         */
+      p->maxas    = MAX( glyph->bbx.ascent, p->maxas );
+      p->maxds    = MAX( glyph->bbx.descent, p->maxds );
+
       p->rbearing = glyph->bbx.width + glyph->bbx.x_offset;
-      p->maxrb = MAX(p->rbearing, p->maxrb);
-      p->minlb = MIN(glyph->bbx.x_offset, p->minlb);
-      p->maxlb = MAX(glyph->bbx.x_offset, p->maxlb);
 
-      if (!(p->flags & _BDF_DWIDTH)) {
-          /*
-           * Missing DWIDTH field.  Add an auto correction message and set
-           * the device width to the glyph width.
-           */
-          sprintf(nbuf, ACMSG10, lineno);
-          _bdf_add_acmsg(font, nbuf, ft_strlen(nbuf));
-          glyph->dwidth = glyph->bbx.width;
+      p->maxrb    = MAX( p->rbearing, p->maxrb );
+      p->minlb    = MIN( glyph->bbx.x_offset, p->minlb );
+      p->maxlb    = MAX( glyph->bbx.x_offset, p->maxlb );
+
+      if ( !( p->flags & _BDF_DWIDTH ) )
+      {
+        /* Missing DWIDTH field.  Emit an auto correction message and set */
+        /* the device width to the glyph width.                           */
+        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG10, lineno ));
+        glyph->dwidth = glyph->bbx.width;
       }
 
-      /*
-       * If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH
-       * value if necessary.
-       */
-      if (p->opts->correct_metrics != 0) {
-          /*
-           * Determine the point size of the glyph.
-           */
-          ps = (double) font->point_size;
-          rx = (double) font->resolution_x;
-          dw = (double) glyph->dwidth;
-          sw = (unsigned short) ((dw * 72000.0) / (ps * rx));
+      /* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */
+      /* value if necessary.                                            */
+      if ( p->opts->correct_metrics != 0 )
+      {
+        /* Determine the point size of the glyph. */
+        ps = (double)font->point_size;
+        rx = (double)font->resolution_x;
+        dw = (double)glyph->dwidth;
 
-          if (sw != glyph->swidth) {
-              glyph->swidth = sw;
-              if (p->glyph_enc == -1)
-                _bdf_set_glyph_modified(font->umod,
-                                        font->unencoded_used - 1);
-              else
-                _bdf_set_glyph_modified(font->nmod, glyph->encoding);
-              p->flags |= _BDF_SWIDTH_ADJ;
-              font->modified = 1;
-          }
+        sw = (unsigned short)( ( dw * 72000.0 ) / ( ps * rx ) );
+
+        if ( sw != glyph->swidth )
+        {
+          glyph->swidth = sw;
+
+          if ( p->glyph_enc == -1 )
+            _bdf_set_glyph_modified( font->umod,
+                                     font->unencoded_used - 1 );
+          else
+            _bdf_set_glyph_modified( font->nmod, glyph->encoding );
+
+          p->flags       |= _BDF_SWIDTH_ADJ;
+          font->modified  = 1;
+        }
       }
+
       p->flags |= _BDF_BBX;
-      return 0;
-  }
+      goto Exit;
+    }
 
-  /*
-   * And finally, gather up the bitmap.
-   */
-  if (ft_memcmp(line, "BITMAP", 6) == 0) {
-      if (!(p->flags & _BDF_BBX)) {
-          /*
-           * Missing BBX field.
-           */
-          sprintf(nbuf, ERRMSG1, lineno, "BBX");
-          _bdf_add_acmsg(font, nbuf, ft_strlen(nbuf));
-          return BDF_MISSING_BBX;
+    /* And finally, gather up the bitmap. */
+    if ( ft_memcmp( line, "BITMAP", 6 ) == 0 )
+    {
+      if ( !( p->flags & _BDF_BBX ) )
+      {
+        /* Missing BBX field. */
+        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" ));
+        error = BDF_Err_Missing_Bbx_Field;
+        goto Exit;
       }
-      /*
-       * Allocate enough space for the bitmap.
-       */
-      p->bpr = ((glyph->bbx.width * p->font->bpp) + 7) >> 3;
-      glyph->bytes = p->bpr * glyph->bbx.height;
-      if ( FT_ALLOC ( glyph->bitmap , glyph->bytes ) )
-        return BDF_OUT_OF_MEMORY;
-      p->row = 0;
+
+      /* Allocate enough space for the bitmap. */
+      glyph->bpr   = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3;
+      glyph->bytes = glyph->bpr * glyph->bbx.height;
+
+      if ( FT_NEW_ARRAY( glyph->bitmap, glyph->bytes ) )
+        goto Exit;
+
+      p->row    = 0;
       p->flags |= _BDF_BITMAP;
-      return 0;
+
+      goto Exit;
+    }
+
+    error = BDF_Err_Invalid_File_Format;
+
+  Exit:
+    return error;
   }
 
-  return BDF_INVALID_LINE;
-}
 
-/*
-* Load the font properties.
-*/
-static int
-_bdf_parse_properties(char *line, unsigned long linelen, unsigned long lineno,
-                    void *call_data, void *client_data)
-{
-  unsigned long vlen;
-  _bdf_line_func_t *next;
-  _bdf_parse_t *p;
-  char *name, *value, nbuf[128];
-  FT_Memory memory;
+  /* Load the font properties. */
+  static FT_Error
+  _bdf_parse_properties( char*          line,
+                         unsigned long  linelen,
+                         unsigned long  lineno,
+                         void*          call_data,
+                         void*          client_data )
+  {
+    unsigned long      vlen;
+    _bdf_line_func_t*  next;
+    _bdf_parse_t*      p;
+    char*              name;
+    char*              value;
+    char               nbuf[128];
+    FT_Memory          memory;
+    FT_Error           error = BDF_Err_Ok;
 
-  next = (_bdf_line_func_t *) call_data;
-  p = (_bdf_parse_t *) client_data;
+    FT_UNUSED( lineno );
 
-  memory = p->font->memory;
-  /*
-   * Check for the end of the properties.
-   */
-  if (ft_memcmp(line, "ENDPROPERTIES", 13) == 0) {
-      /*
-       * If the FONT_ASCENT or FONT_DESCENT properties have not been
-       * encountered yet, then make sure they are added as properties and
-       * make sure they are set from the font bounding box info.
-       *
-       * This is *always* done regardless of the options, because X11
-       * requires these two fields to compile fonts.
-       */
-      if (bdf_get_font_property(p->font, "FONT_ASCENT") == 0) {
-          p->font->font_ascent = p->font->bbx.ascent;
-          sprintf(nbuf, "%hd", p->font->bbx.ascent);
-          _bdf_add_property(p->font, "FONT_ASCENT", nbuf);
-          sprintf(nbuf, ACMSG1, p->font->bbx.ascent);
-          _bdf_add_acmsg(p->font, nbuf, ft_strlen(nbuf));
-          p->font->modified = 1;
+
+    next = (_bdf_line_func_t *)call_data;
+    p    = (_bdf_parse_t *)    client_data;
+
+    memory = p->font->memory;
+
+    /* Check for the end of the properties. */
+    if ( ft_memcmp( line, "ENDPROPERTIES", 13 ) == 0 )
+    {
+      /* If the FONT_ASCENT or FONT_DESCENT properties have not been      */
+      /* encountered yet, then make sure they are added as properties and */
+      /* make sure they are set from the font bounding box info.          */
+      /*                                                                  */
+      /* This is *always* done regardless of the options, because X11     */
+      /* requires these two fields to compile fonts.                      */
+      if ( bdf_get_font_property( p->font, (char *)"FONT_ASCENT" ) == 0 )
+      {
+        p->font->font_ascent = p->font->bbx.ascent;
+        ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
+        error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", nbuf );
+        if ( error )
+          goto Exit;
+
+        FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent ));
+        p->font->modified = 1;
       }
-      if (bdf_get_font_property(p->font, "FONT_DESCENT") == 0) {
-          p->font->font_descent = p->font->bbx.descent;
-          sprintf(nbuf, "%hd", p->font->bbx.descent);
-          _bdf_add_property(p->font, "FONT_DESCENT", nbuf);
-          sprintf(nbuf, ACMSG2, p->font->bbx.descent);
-          _bdf_add_acmsg(p->font, nbuf, ft_strlen(nbuf));
-          p->font->modified = 1;
+
+      if ( bdf_get_font_property( p->font, (char *)"FONT_DESCENT" ) == 0 )
+      {
+        p->font->font_descent = p->font->bbx.descent;
+        ft_sprintf( nbuf, "%hd", p->font->bbx.descent );
+        error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", nbuf );
+        if ( error )
+          goto Exit;
+
+        FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent ));
+        p->font->modified = 1;
       }
+
       p->flags &= ~_BDF_PROPS;
-      *next = _bdf_parse_glyphs;
-      return 0;
-  }
+      *next     = _bdf_parse_glyphs;
 
-  /*
-   * Ignore the _XFREE86_GLYPH_RANGES properties.
-   */
-  if (ft_memcmp(line, "_XFREE86_GLYPH_RANGES", 21) == 0)
-    return 0;
+      goto Exit;
+    }
 
-  /*
-   * Handle COMMENT fields and properties in a special way to preserve
-   * the spacing.
-   */
-  if (ft_memcmp(line, "COMMENT", 7) == 0) {
+    /* Ignore the _XFREE86_GLYPH_RANGES properties. */
+    if ( ft_memcmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 )
+      goto Exit;
+
+    /* Handle COMMENT fields and properties in a special way to preserve */
+    /* the spacing.                                                      */
+    if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )
+    {
       name = value = line;
       value += 7;
-      if (*value)
+      if ( *value )
         *value++ = 0;
-      _bdf_add_property(p->font, name, value);
-  } else if (_bdf_is_atom(line, linelen, &name, &value, p->font))
-    _bdf_add_property(p->font, name, value);
-  else {
-      _bdf_split(" +", line, linelen, &p->list, memory);
+      error = _bdf_add_property( p->font, name, value );
+      if ( error )
+        goto Exit;
+    }
+    else if ( _bdf_is_atom( line, linelen, &name, &value, p->font ) )
+    {
+      error = _bdf_add_property( p->font, name, value );
+      if ( error )
+        goto Exit;
+    }
+    else
+    {
+      error = _bdf_split( (char *)" +", line, linelen, &p->list, memory );
+      if ( error )
+        goto Exit;
       name = p->list.field[0];
-      _bdf_shift(1, &p->list);
-      value = _bdf_join(' ', &vlen, &p->list);
-      _bdf_add_property(p->font, name, value);
+
+      _bdf_shift( 1, &p->list );
+      value = _bdf_join( ' ', &vlen, &p->list );
+
+      error = _bdf_add_property( p->font, name, value );
+      if ( error )
+        goto Exit;
+    }
+
+  Exit:
+    return error;
   }
 
-  return 0;
-}
 
-/*
- * Load the font header.
- */
-static int
-_bdf_parse_start(char *line, unsigned long linelen, unsigned long lineno,
-                 void *call_data, void *client_data)
-{
-    unsigned long slen;
-    _bdf_line_func_t *next;
-    _bdf_parse_t *p;
-    bdf_font_t *font;
-    char *s, nbuf[128];
-    /*    int test; */
-    FT_Memory memory;
-    FT_Error error;
+  /* Load the font header. */
+  static FT_Error
+  _bdf_parse_start( char*          line,
+                    unsigned long  linelen,
+                    unsigned long  lineno,
+                    void*          call_data,
+                    void*          client_data )
+  {
+    unsigned long      slen;
+    _bdf_line_func_t*  next;
+    _bdf_parse_t*      p;
+    bdf_font_t*        font;
+    char               *s;
 
-    next = (_bdf_line_func_t *) call_data;
-    p = (_bdf_parse_t *) client_data;
-    if (p->font)
+    FT_Memory          memory;
+    FT_Error           error = BDF_Err_Ok;
+
+    FT_UNUSED( lineno );            /* only used in debug mode */
+
+
+    next = (_bdf_line_func_t *)call_data;
+    p    = (_bdf_parse_t *)    client_data;
+
+    if ( p->font )
       memory = p->font->memory;
 
-    /*
-     * Check for a comment.  This is done to handle those fonts that have
-     * comments before the STARTFONT line for some reason.
-     */
-    if (ft_memcmp(line, "COMMENT", 7) == 0) {
-        if (p->opts->keep_comments != 0 && p->font != 0) {
-            linelen -= 7;
-            s = line + 7;
-            if (*s != 0) {
-                s++;
-                linelen--;
-            }
-            _bdf_add_comment(p->font, s, linelen);
-	    /* here font is not defined ! */
+    /* Check for a comment.  This is done to handle those fonts that have */
+    /* comments before the STARTFONT line for some reason.                */
+    if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )
+    {
+      if ( p->opts->keep_comments != 0 && p->font != 0 )
+      {
+        linelen -= 7;
+
+        s = line + 7;
+        if ( *s != 0 )
+        {
+          s++;
+          linelen--;
         }
-        return 0;
+
+        error = _bdf_add_comment( p->font, s, linelen );
+        if ( error )
+          goto Exit;
+        /* here font is not defined! */
+      }
+
+      goto Exit;
     }
 
-    if (!(p->flags & _BDF_START)) {
+    if ( !( p->flags & _BDF_START ) )
+    {
+      memory = p->memory;
 
-        memory = p->memory;
+      if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 )
+      {
+        /* No STARTFONT field is a good indication of a problem. */
+        error = BDF_Err_Missing_Startfont_Field;
+        goto Exit;
+      }
 
-        if (ft_memcmp(line, "STARTFONT", 9) != 0)
-          /*
-           * No STARTFONT field is a good indication of a problem.
-           */
-          return BDF_MISSING_START;
-        p->flags = _BDF_START;
-        font = p->font = 0;
+      p->flags = _BDF_START;
+      font = p->font = 0;
 
-	if ( FT_ALLOC ( font, sizeof(bdf_font_t) ) )
-	  return BDF_OUT_OF_MEMORY;
-	p->font = font;
+      if ( FT_NEW( font ) )
+        goto Exit;
+      p->font = font;
 
-	font->memory = p->memory;
-	p->memory = 0;
+      font->memory = p->memory;
+      p->memory    = 0;
 
-	/*	if (font == 0) {
-          fprintf(stderr,"failed font\n");
-	  }*/ /* XXX */
+      { /* setup */
+        unsigned long    i;
+        bdf_property_t*  prop;
 
-	{ /* setup */
-	  unsigned long i;
-	  bdf_property_t *prop;
 
-	  hash_init(&(font->proptbl), memory);
-	  for (i = 0, prop = _bdf_properties;
-		 i < _num_bdf_properties; i++, prop++)
-	    hash_insert(prop->name, (void *) i, &(font->proptbl) , memory);
-	}
-
-	if ( FT_ALLOC ( p->font->internal , sizeof(hashtable) ) )
-	  return BDF_OUT_OF_MEMORY;
-	hash_init((hashtable *) p->font->internal,memory);
-	p->font->spacing = p->opts->font_spacing;
-        p->font->default_glyph = -1;
-	return 0;
-    }
-
-    /*
-     * Check for the start of the properties.
-     */
-    if (ft_memcmp(line, "STARTPROPERTIES", 15) == 0) {
-        _bdf_split(" +", line, linelen, &p->list, memory);
-        p->cnt = p->font->props_size = _bdf_atoul(p->list.field[1], 0, 10);
-
-	if ( FT_ALLOC ( p->font->props , (sizeof(bdf_property_t) * p->cnt) ) )
-	  return BDF_OUT_OF_MEMORY;
-        p->flags |= _BDF_PROPS;
-        *next = _bdf_parse_properties;
-        return 0;
-    }
-
-    /*
-     * Check for the FONTBOUNDINGBOX field.
-     */
-    if (ft_memcmp(line, "FONTBOUNDINGBOX", 15) == 0) {
-        if (!(p->flags & _BDF_SIZE)) {
-            /*
-             * Missing the SIZE field.
-             */
-            sprintf(nbuf, ERRMSG1, lineno, "SIZE");
-            _bdf_add_acmsg(p->font, nbuf, ft_strlen(nbuf));
-            return BDF_MISSING_SIZE;
+        error = hash_init( &(font->proptbl), memory );
+        if ( error )
+          goto Exit;
+        for ( i = 0, prop = _bdf_properties;
+              i < _num_bdf_properties; i++, prop++ )
+        {
+          error = hash_insert( prop->name, (void *)i,
+                               &(font->proptbl), memory );
+          if ( error )
+            goto Exit;
         }
-        _bdf_split(" +", line, linelen, &p->list , memory);
-        p->font->bbx.width = _bdf_atos(p->list.field[1], 0, 10);
-        p->font->bbx.height = _bdf_atos(p->list.field[2], 0, 10);
-        p->font->bbx.x_offset = _bdf_atos(p->list.field[3], 0, 10);
-        p->font->bbx.y_offset = _bdf_atos(p->list.field[4], 0, 10);
-        p->font->bbx.ascent = p->font->bbx.height + p->font->bbx.y_offset;
-        p->font->bbx.descent = -p->font->bbx.y_offset;
-        p->flags |= _BDF_FONT_BBX;
-        return 0;
+      }
+
+      if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) )
+        goto Exit;
+      error = hash_init( (hashtable *)p->font->internal,memory );
+      if ( error )
+        goto Exit;
+      p->font->spacing       = p->opts->font_spacing;
+      p->font->default_glyph = -1;
+
+      goto Exit;
     }
 
-    /*
-     * The next thing to check for is the FONT field.
-     */
-    if (ft_memcmp(line, "FONT", 4) == 0) {
-        _bdf_split(" +", line, linelen, &p->list , memory);
-        _bdf_shift(1, &p->list);
-        s = _bdf_join(' ', &slen, &p->list);
-	if ( FT_ALLOC ( p->font->name , slen + 1 ) )
-	  return BDF_OUT_OF_MEMORY;
-        (void) ft_memcpy(p->font->name, s, slen + 1);
-        /*
-         * If the font name is an XLFD name, set the spacing to the one in the
-         * font name.  If there is no spacing fall back on the default.
-         */
-        _bdf_set_default_spacing(p->font, p->opts);
-        p->flags |= _BDF_FONT_NAME;
-	return 0;
+    /* Check for the start of the properties. */
+    if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 )
+    {
+      error = _bdf_split( (char *)" +", line, linelen, &p->list, memory );
+      if ( error )
+        goto Exit;
+      p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 );
+
+      if ( FT_NEW_ARRAY( p->font->props, p->cnt ) )
+        goto Exit;
+
+      p->flags |= _BDF_PROPS;
+      *next     = _bdf_parse_properties;
+
+      goto Exit;
     }
 
-    /*
-     * Check for the SIZE field.
-     */
-    if (ft_memcmp(line, "SIZE", 4) == 0) {
-        if (!(p->flags & _BDF_FONT_NAME)) {
-            /*
-             * Missing the FONT field.
-             */
-            sprintf(nbuf, ERRMSG1, lineno, "FONT");
-            _bdf_add_acmsg(p->font, nbuf, ft_strlen(nbuf));
-            return BDF_MISSING_FONTNAME;
+    /* Check for the FONTBOUNDINGBOX field. */
+    if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 )
+    {
+      if ( !(p->flags & _BDF_SIZE ) )
+      {
+        /* Missing the SIZE field. */
+        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" ));
+        error = BDF_Err_Missing_Size_Field;
+        goto Exit;
+      }
+
+      error = _bdf_split( (char *)" +", line, linelen, &p->list , memory );
+      if ( error )
+        goto Exit;
+
+      p->font->bbx.width  = _bdf_atos( p->list.field[1], 0, 10 );
+      p->font->bbx.height = _bdf_atos( p->list.field[2], 0, 10 );
+
+      p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 );
+      p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 );
+
+      p->font->bbx.ascent  = p->font->bbx.height + p->font->bbx.y_offset;
+      p->font->bbx.descent = -p->font->bbx.y_offset;
+
+      p->flags |= _BDF_FONT_BBX;
+
+      goto Exit;
+    }
+
+    /* The next thing to check for is the FONT field. */
+    if ( ft_memcmp( line, "FONT", 4 ) == 0 )
+    {
+      error = _bdf_split( (char *)" +", line, linelen, &p->list , memory );
+      if ( error )
+        goto Exit;
+      _bdf_shift( 1, &p->list );
+
+      s = _bdf_join( ' ', &slen, &p->list );
+      if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) )
+        goto Exit;
+      FT_MEM_COPY( p->font->name, s, slen + 1 );
+
+      /* If the font name is an XLFD name, set the spacing to the one in  */
+      /* the font name.  If there is no spacing fall back on the default. */
+      error = _bdf_set_default_spacing( p->font, p->opts );
+      if ( error )
+        goto Exit;
+
+      p->flags |= _BDF_FONT_NAME;
+
+      goto Exit;
+    }
+
+    /* Check for the SIZE field. */
+    if ( ft_memcmp( line, "SIZE", 4 ) == 0 )
+    {
+      if ( !( p->flags & _BDF_FONT_NAME ) )
+      {
+        /* Missing the FONT field. */
+        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" ));
+        error = BDF_Err_Missing_Font_Field;
+        goto Exit;
+      }
+
+      error = _bdf_split( (char *)" +", line, linelen, &p->list, memory );
+      if ( error )
+        goto Exit;
+
+      p->font->point_size   = _bdf_atoul( p->list.field[1], 0, 10 );
+      p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 );
+      p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 );
+
+      /* Check for the bits per pixel field. */
+      if ( p->list.used == 5 )
+      {
+        p->font->bpp = _bdf_atos( p->list.field[4], 0, 10 );
+        if ( p->font->bpp > 1 && ( p->font->bpp & 1 ) )
+        {
+          /* Move up to the next bits per pixel value if an odd number */
+          /* is encountered.                                           */
+          p->font->bpp++;
+          if ( p->font->bpp <= 4 )
+            FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp ));
         }
-        _bdf_split(" +", line, linelen, &p->list, memory);
-        p->font->point_size = _bdf_atoul(p->list.field[1], 0, 10);
-        p->font->resolution_x = _bdf_atoul(p->list.field[2], 0, 10);
-        p->font->resolution_y = _bdf_atoul(p->list.field[3], 0, 10);
 
-        /*
-         * Check for the bits per pixel field.
-         */
-        if (p->list.used == 5) {
-            p->font->bpp = _bdf_atos(p->list.field[4], 0, 10);
-            if (p->font->bpp > 1 && (p->font->bpp & 1)) {
-                /*
-                 * Move up to the next bits per pixel value if an odd number
-                 * is encountered.
-                 */
-                p->font->bpp++;
-                if (p->font->bpp <= 4) {
-                    sprintf(nbuf, ACMSG11, p->font->bpp);
-                    _bdf_add_acmsg(p->font, nbuf, ft_strlen(nbuf));
-                }
-            }
-            if (p->font->bpp > 4) {
-                sprintf(nbuf, ACMSG11, p->font->bpp);
-                _bdf_add_acmsg(p->font, nbuf, ft_strlen(nbuf));
-                p->font->bpp = 4;
-            }
-        } else
-          p->font->bpp = 1;
+        if ( p->font->bpp > 4 )
+        {
+          FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp ));
+          p->font->bpp = 4;
+        }
+      }
+      else
+        p->font->bpp = 1;
 
-        p->flags |= _BDF_SIZE;
-        return 0;
+      p->flags |= _BDF_SIZE;
+
+      goto Exit;
     }
 
-    return BDF_INVALID_LINE;
-}
+    error = BDF_Err_Invalid_File_Format;
 
-/**************************************************************************
- *
- * API.
- *
- **************************************************************************/
+  Exit:
+    return error;
+  }
 
 
-FT_LOCAL_DEF( bdf_font_t* )
-bdf_load_font( FT_Stream       stream,
-               FT_Memory       extmemory,
-               bdf_options_t*  opts,
-               bdf_callback_t  callback,
-               void*           data)
-{
-    int n;
-    unsigned long lineno;
-    char msgbuf[128];
-    _bdf_parse_t p;
-    FT_Memory memory;
-    FT_Error error;
+  /*************************************************************************/
+  /*                                                                       */
+  /* API.                                                                  */
+  /*                                                                       */
+  /*************************************************************************/
 
-    (void) ft_memset((char *) &p, 0, sizeof(_bdf_parse_t));
-    p.opts = (opts != 0) ? opts : &_bdf_opts;
-    p.minlb = 32767;
-    p.callback = callback;
-    p.client_data = data;
 
+  FT_LOCAL_DEF( FT_Error )
+  bdf_load_font( FT_Stream       stream,
+                 FT_Memory       extmemory,
+                 bdf_options_t*  opts,
+                 bdf_font_t*    *font )
+  {
+    unsigned long  lineno;
+    _bdf_parse_t   p;
+
+    FT_Memory      memory;
+    FT_Error       error = BDF_Err_Ok;
+
+
+    FT_MEM_SET( &p, 0, sizeof ( _bdf_parse_t ) );
+
+    p.opts   = ( opts != 0 ) ? opts : &_bdf_opts;
+    p.minlb  = 32767;
     p.memory = extmemory;  /* only during font creation */
 
-    n = _bdf_readstream(stream, _bdf_parse_start, (void *) &p, &lineno);
+    error = _bdf_readstream( stream, _bdf_parse_start,
+                             (void *)&p, &lineno );
+    if ( error )
+      goto Exit;
 
-    if (p.font != 0) {
-        /*
-         * If the font is not proportional, set the fonts monowidth
-         * field to the width of the font bounding box.
-         */
+    if ( p.font != 0 )
+    {
+      /* If the font is not proportional, set the font's monowidth */
+      /* field to the width of the font bounding box.              */
       memory = p.font->memory;
 
-        if (p.font->spacing != BDF_PROPORTIONAL)
-          p.font->monowidth = p.font->bbx.width;
+      if ( p.font->spacing != BDF_PROPORTIONAL )
+        p.font->monowidth = p.font->bbx.width;
 
-        /*
-         * If the number of glyphs loaded is not that of the original count,
-         * indicate the difference.
-         */
-        if (p.cnt != p.font->glyphs_used + p.font->unencoded_used) {
-            sprintf(msgbuf, ACMSG15, p.cnt,
-                    p.font->glyphs_used + p.font->unencoded_used);
-            _bdf_add_acmsg(p.font, msgbuf, ft_strlen(msgbuf));
-            p.font->modified = 1;
+      /* If the number of glyphs loaded is not that of the original count, */
+      /* indicate the difference.                                          */
+      if ( p.cnt != p.font->glyphs_used + p.font->unencoded_used )
+      {
+        FT_TRACE2(( "bdf_load_font: " ACMSG15, p.cnt,
+                    p.font->glyphs_used + p.font->unencoded_used ));
+        p.font->modified = 1;
+      }
+
+      /* Once the font has been loaded, adjust the overall font metrics if */
+      /* necessary.                                                        */
+      if ( p.opts->correct_metrics != 0 &&
+           ( p.font->glyphs_used > 0 || p.font->unencoded_used > 0 ) )
+      {
+        if ( p.maxrb - p.minlb != p.font->bbx.width )
+        {
+          FT_TRACE2(( "bdf_load_font: " ACMSG3,
+                      p.font->bbx.width, p.maxrb - p.minlb ));
+          p.font->bbx.width = p.maxrb - p.minlb;
+          p.font->modified  = 1;
         }
 
-        /*
-         * Once the font has been loaded, adjust the overall font metrics if
-         * necessary.
-         */
-        if (p.opts->correct_metrics != 0 &&
-            (p.font->glyphs_used > 0 || p.font->unencoded_used > 0)) {
-            if (p.maxrb - p.minlb != p.font->bbx.width) {
-                sprintf(msgbuf, ACMSG3, p.font->bbx.width, p.maxrb - p.minlb);
-                _bdf_add_acmsg(p.font, msgbuf, ft_strlen(msgbuf));
-                p.font->bbx.width = p.maxrb - p.minlb;
-                p.font->modified = 1;
-            }
-            if (p.font->bbx.x_offset != p.minlb) {
-                sprintf(msgbuf, ACMSG4, p.font->bbx.x_offset, p.minlb);
-                _bdf_add_acmsg(p.font, msgbuf, ft_strlen(msgbuf));
-                p.font->bbx.x_offset = p.minlb;
-                p.font->modified = 1;
-            }
-            if (p.font->bbx.ascent != p.maxas) {
-                sprintf(msgbuf, ACMSG5, p.font->bbx.ascent, p.maxas);
-                _bdf_add_acmsg(p.font, msgbuf, ft_strlen(msgbuf));
-                p.font->bbx.ascent = p.maxas;
-                p.font->modified = 1;
-            }
-            if (p.font->bbx.descent != p.maxds) {
-                sprintf(msgbuf, ACMSG6, p.font->bbx.descent, p.maxds);
-                _bdf_add_acmsg(p.font, msgbuf, ft_strlen(msgbuf));
-                p.font->bbx.descent = p.maxds;
-                p.font->bbx.y_offset = -p.maxds;
-                p.font->modified = 1;
-            }
-            if (p.maxas + p.maxds != p.font->bbx.height) {
-                sprintf(msgbuf, ACMSG7, p.font->bbx.height, p.maxas + p.maxds);
-                _bdf_add_acmsg(p.font, msgbuf, ft_strlen(msgbuf));
-            }
-            p.font->bbx.height = p.maxas + p.maxds;
-
-            if (p.flags & _BDF_SWIDTH_ADJ)
-              _bdf_add_acmsg(p.font, ACMSG8, ft_strlen(ACMSG8));
+        if ( p.font->bbx.x_offset != p.minlb )
+        {
+          FT_TRACE2(( "bdf_load_font: " ACMSG4,
+                      p.font->bbx.x_offset, p.minlb ));
+          p.font->bbx.x_offset = p.minlb;
+          p.font->modified     = 1;
         }
+
+        if ( p.font->bbx.ascent != p.maxas )
+        {
+          FT_TRACE2(( "bdf_load_font: " ACMSG5,
+                      p.font->bbx.ascent, p.maxas ));
+          p.font->bbx.ascent = p.maxas;
+          p.font->modified   = 1;
+        }
+
+        if ( p.font->bbx.descent != p.maxds )
+        {
+          FT_TRACE2(( "bdf_load_font: " ACMSG6,
+                      p.font->bbx.descent, p.maxds ));
+          p.font->bbx.descent  = p.maxds;
+          p.font->bbx.y_offset = -p.maxds;
+          p.font->modified     = 1;
+        }
+
+        if ( p.maxas + p.maxds != p.font->bbx.height )
+        {
+          FT_TRACE2(( "bdf_load_font: " ACMSG7,
+                      p.font->bbx.height, p.maxas + p.maxds ));
+          p.font->bbx.height = p.maxas + p.maxds;
+        }
+
+        if ( p.flags & _BDF_SWIDTH_ADJ )
+          FT_TRACE2(( "bdf_load_font: " ACMSG8 ));
+      }
     }
 
-    /*
-     * Last, if an error happened during loading, handle the messages.
-     */
-    if (n < 0 && callback != 0) {
-        /*
-         * An error was returned.  Alert the client.
-         */
-        p.cb.reason = BDF_ERROR;
-        p.cb.errlineno = lineno;
-        (*callback)(&p.cb, data);
-    } else if (p.flags & _BDF_START) {
-        if (p.font != 0) {
-            /*
-             * The ENDFONT field was never reached or did not exist.
-             */
-            if (!(p.flags & _BDF_GLYPHS))
-              /*
-               * Error happened while parsing header.
-               */
-              sprintf(msgbuf, ERRMSG2, lineno);
-            else
-              /*
-               * Error happened when parsing glyphs.
-               */
-              sprintf(msgbuf, ERRMSG3, lineno);
-
-            _bdf_add_acmsg(p.font, msgbuf, ft_strlen(msgbuf));
-        }
-
-        if (callback != 0) {
-            p.cb.reason = BDF_ERROR;
-            p.cb.errlineno = lineno;
-            (*callback)(&p.cb, data);
-        }
-    } else if (callback != 0) {
-        /*
-         * This forces the progress bar to always finish.
-         */
-        p.cb.current = p.cb.total;
-        (*p.callback)(&p.cb, p.client_data);
+    if ( p.flags & _BDF_START )
+    {
+      {
+        /* The ENDFONT field was never reached or did not exist. */
+        if ( !( p.flags & _BDF_GLYPHS ) )
+          /* Error happened while parsing header. */
+          FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno ));
+        else
+          /* Error happened when parsing glyphs. */
+          FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno ));
+      }
     }
 
-    /*
-     * Free up the list used during the parsing.
-     */
-    if (p.list.size > 0)
-      FT_FREE( p.list.field );
+    /* Free up the list used during the parsing. */
+    FT_FREE( p.list.field );
 
-    if (p.font != 0) {
-        /*
-         * Make sure the comments are NULL terminated if they exist.
-         */
-        memory = p.font->memory;
+    if ( p.font != 0 )
+    {
+      /* Make sure the comments are NULL terminated if they exist. */
+      memory = p.font->memory;
 
-        if (p.font->comments_len > 0) {
-	  if ( FT_REALLOC ( p.font->comments , p.font->comments_len ,
-			 p.font->comments_len + 1 ) )
-	    return 0;
-            p.font->comments[p.font->comments_len] = 0;
-        }
+      if ( p.font->comments_len > 0 ) {
+        if ( FT_RENEW_ARRAY( p.font->comments,
+                             p.font->comments_len,
+                             p.font->comments_len + 1 ) )
+          goto Exit;
 
-        /*
-         * Make sure the auto-correct messages are NULL terminated if they
-         * exist.
-         */
-        if (p.font->acmsgs_len > 0) {
-	  memory = p.font->memory;
-
-	  if ( FT_REALLOC ( p.font->acmsgs , p.font->acmsgs_len ,
-			 p.font->acmsgs_len + 1 ) )
-	    return 0;
-            p.font->acmsgs[p.font->acmsgs_len] = 0;
-        }
+        p.font->comments[p.font->comments_len] = 0;
+      }
     }
 
-    return p.font;
-}
+    *font = p.font;
+
+  Exit:
+    return error;
+  }
 
 
-FT_LOCAL_DEF( void )
-bdf_free_font( bdf_font_t *font )
-{
-  bdf_property_t *prop;
-    unsigned long i;
-    bdf_glyph_t *glyphs;
-    FT_Memory memory;
+  FT_LOCAL_DEF( void )
+  bdf_free_font( bdf_font_t*  font )
+  {
+    bdf_property_t*  prop;
+    unsigned long    i;
+    bdf_glyph_t*     glyphs;
+    FT_Memory        memory;
 
-    if (font == 0)
-        return;
+
+    if ( font == 0 )
+      return;
 
     memory = font->memory;
 
-    if (font->name != 0)
-      FT_FREE(font->name);
+    FT_FREE( font->name );
 
-    /*
-     * Free up the internal hash table of property names.
-     */
-    if (font->internal) {
-      hash_free((hashtable *) font->internal, memory);
-      FT_FREE(font->internal);
-    }
-    /*
-     * Free up the comment info.
-     */
-    if (font->comments_len > 0)
-      FT_FREE(font->comments);
-
-    /*
-     * Free up the auto-correction messages.
-     */
-    if (font->acmsgs_len > 0)
-      FT_FREE(font->acmsgs);
-
-    /*
-     * Free up the properties.
-     */
-    for (i = 0; i < font->props_size; i++) {
-        if (font->props[i].format == BDF_ATOM && font->props[i].value.atom)
-          FT_FREE(font->props[i].value.atom);
+    /* Free up the internal hash table of property names. */
+    if ( font->internal )
+    {
+      hash_free( (hashtable *)font->internal, memory );
+      FT_FREE( font->internal );
     }
 
-    if (font->props_size > 0 && font->props != 0)
-      FT_FREE(font->props);
+    /* Free up the comment info. */
+    FT_FREE( font->comments );
 
-    /*
-     * Free up the character info.
-     */
-    for (i = 0, glyphs = font->glyphs; i < font->glyphs_used; i++, glyphs++) {
-        if (glyphs->name)
-          FT_FREE(glyphs->name);
-        if (glyphs->bytes > 0 && glyphs->bitmap != 0)
-          FT_FREE(glyphs->bitmap);
+    /* Free up the properties. */
+    for ( i = 0; i < font->props_size; i++ )
+    {
+      if ( font->props[i].format == BDF_ATOM )
+        FT_FREE( font->props[i].value.atom );
     }
 
-    for (i = 0, glyphs = font->unencoded; i < font->unencoded_used;
-         i++, glyphs++) {
-        if (glyphs->name)
-          FT_FREE(glyphs->name);
-        if (glyphs->bytes > 0)
-          FT_FREE(glyphs->bitmap);
+    FT_FREE( font->props );
+
+    /* Free up the character info. */
+    for ( i = 0, glyphs = font->glyphs;
+          i < font->glyphs_used; i++, glyphs++ )
+    {
+      FT_FREE( glyphs->name );
+      FT_FREE( glyphs->bitmap );
     }
 
-    if (font->glyphs_size > 0)
-      FT_FREE( font->glyphs);
-
-    if (font->unencoded_size > 0)
-      FT_FREE( font->unencoded);
-
-    /*
-     * Free up the overflow storage if it was used.
-     */
-    for (i = 0, glyphs = font->overflow.glyphs; i < font->overflow.glyphs_used;
-         i++, glyphs++) {
-      if (glyphs->name != 0)
-	FT_FREE(glyphs->name);
-      if (glyphs->bytes > 0)
-	FT_FREE( glyphs->bitmap);;
+    for ( i = 0, glyphs = font->unencoded; i < font->unencoded_used;
+          i++, glyphs++ )
+    {
+      FT_FREE( glyphs->name );
+      FT_FREE( glyphs->bitmap );
     }
-    if (font->overflow.glyphs_size > 0)
-      FT_FREE(font->overflow.glyphs);
+
+    FT_FREE( font->glyphs );
+    FT_FREE( font->unencoded );
+
+    /* Free up the overflow storage if it was used. */
+    for ( i = 0, glyphs = font->overflow.glyphs;
+          i < font->overflow.glyphs_used; i++, glyphs++ )
+    {
+      FT_FREE( glyphs->name );
+      FT_FREE( glyphs->bitmap );
+    }
+
+    FT_FREE( font->overflow.glyphs );
 
     /* bdf_cleanup */
-    hash_free(&(font->proptbl),memory);
+    hash_free( &(font->proptbl), memory );
 
-    /*
-     * Free up the user defined properties.
-     */
-    for (prop = font->user_props, i = 0; i < font->nuser_props; i++, prop++) {
-      FT_FREE(prop->name);
-      if (prop->format == BDF_ATOM && prop->value.atom != 0)
-	FT_FREE(prop->value.atom);
+    /* Free up the user defined properties. */
+    for (prop = font->user_props, i = 0;
+         i < font->nuser_props; i++, prop++ )
+    {
+      FT_FREE( prop->name );
+      if ( prop->format == BDF_ATOM )
+        FT_FREE( prop->value.atom );
     }
-    if (font->nuser_props > 0)
-      FT_FREE(font->user_props);
 
-    /*FREE( font);*/ /* XXX Fixme */
-}
+    FT_FREE( font->user_props );
+
+    /* FREE( font ); */ /* XXX Fixme */
+  }
 
 
+  FT_LOCAL_DEF( bdf_property_t * )
+  bdf_get_font_property( bdf_font_t*  font,
+                         char*        name )
+  {
+    hashnode  hn;
 
-FT_LOCAL_DEF( bdf_property_t* )
-bdf_get_font_property( bdf_font_t*  font,
-                       char*        name)
-{
-    hashnode hn;
 
-    if (font == 0 || font->props_size == 0 || name == 0 || *name == 0)
+    if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 )
       return 0;
 
-    hn = hash_lookup(name, (hashtable *) font->internal);
-    return (hn) ? (font->props + ((unsigned long) hn->data)) : 0;
-}
+    hn = hash_lookup( name, (hashtable *)font->internal );
+
+    return hn ? ( font->props + (unsigned long)hn->data ) : 0;
+  }
+
+
+/* END */